單鏈表(c語言實現)賊詳細


直接上代碼吧

#include<stdio.h>
#include<malloc.h>
/*
單鏈表特點:
它是一種動態的儲存結構,鏈表中每個節點占用的儲存空間不是預先分配的,而是運行時系統根據需求生成的
*/
typedef struct lnode
{
    int data;
    struct lnode *next;
}lnode,*linklist;
//結點定義
/*
關於頭指針的一點說明:
linklist L;
外面用頭指針來標識一個單鏈表,如單鏈表L,單鏈表H等,是指鏈表的第一個節點的地址被記錄在指針變量L,H中,頭指針為NULL
時,表示一個空的單鏈表,需要進一步指出的是:上面定義的lnode是節點的類型,linklist是指向lnode節點的指針的類型,
為了增強程序的可讀性,通常將標識一個鏈表的頭指針說明為linklist類型的變量
*/
linklist creat_linklist_insert_head_nohead()
{
    linklist l=NULL;//定義頭指針變量l
    lnode *s;//新建一個節點
    int flag=-1;//輸入停止標志位
    printf("輸入整型數據,數據以空格隔開,輸入數據為-1的時候表示輸入截止\n");
    while(1)
    {
        int x;
        scanf("%d",&x);
        if(x==flag)
            break;
        s=(lnode*)malloc(sizeof(lnode));//對s節點申請儲存空間
        s->data=x;//賦值
        s->next=l;//s節點的next指向頭指針
        l=s;//頭指針指向新建立的s節點,因為這是在單鏈表的頭部插入數據
    }
    return l;
}//創建一個單鏈表,通過在頭部插入數據,不含空的頭節點
//-------------------------------------------------------------------------------------------------------------//
/*在單鏈表的表頭插入,只要x!=flag,就是一直申請s結點,從而可以一直在表頭插入,
其中l=s是最重要的,因為這是將s插入到l的表頭,因為是在頭部插入,所以只要一個頭指針就可以,
若是在單鏈表的尾部插入,那么就需要尾部指針
關於此函數使用的一點說明:
我們輸入數據 1 2 3 4 5的時候,輸出的是 5 4 3 2 1,因為我們是在頭部插入數據的
*/
//-------------------------------------------------------------------------------------------------------------//
linklist creat_linklist_insert_end_yeshead()
{
    linklist l=NULL,r=NULL;//定義頭指針變量和尾指針變量
    lnode *s;//定義新建節點
    int flag=-1;//輸入結束標志位
    printf("輸入整型數據,數據以空格隔開,輸入數據為-1的時候表示輸入截止\n");
    while(1)
    {
        int x;
        scanf("%d",&x);
        if(x==flag)//輸入數據等於輸入結束標志位則跳出循環
            break;
        s=(lnode*)malloc(sizeof(lnode));//申請內存空間
        s->data=x;//賦值
        if(l==NULL)//單鏈表為空
            l=s;//則將頭指針指向新建節點
        else
            r->next=s;//不空的話則將尾指針的next指向s,因為如果不空的話,尾指針指向的肯定是一個數據節點,尾指針的next指向s是為了將兩個數據節點連接起來
        r=s;//尾指針移動到新插入的節點上
    }
    if(r!=NULL)//有數據
        r->next=NULL;//尾指針的next指向空,說明尾指針后面沒有數據了,目的的為了保證單鏈表尾指針邏輯的合理性
    return l;
}//建立單鏈表且在鏈表尾部插入數據,含空的頭節點
//-----------------------------------------------------------------------------------------------------------------------//
/*在單鏈表的尾部插入,只要沒有輸入結束的標志,就一直申請s結點,然后把x賦給s結點的data域,
l=s是為了第一個結點的結點的處理,因為在此之前l是一個空表,然后因為不斷有新的結點生成,所以就是不斷把新的s結點賦給r的next,
這樣就不斷有s結點加入到了單鏈表中間,然后最重要的是每次新的結點加入到單鏈表中后要把r尾指針向后面移動,就是文中的r=s;
關於此函數的一點說明:
輸入數據 1 2 3 4 5,輸出還是 1 2 3 4 5,而不是 5 4 3 2 1,因為我們插入數據是在鏈表尾部插入的
*/
//-----------------------------------------------------------------------------------------------------------------------//
int length_linklist_yeshead(linklist l)
{
    linklist p=l;
    int j=1;
    while(p->next)
    {
        j++;
        p=p->next;
    }
    return j;
}//求單鏈表的表長,針對含有空的頭節點的單鏈表
int length_linklist_nohead(linklist l)
{
    lnode *p=l;
    int j=0;
    while(p)
    {
        j++;
        p=p->next;
    }
    return j;
}//求鏈表的表長,針對不含空的頭節點的單鏈表
lnode *get_linklist(linklist l,int i)
{
    lnode *p=l;
    int j=0;
    while(p!=NULL&&j<i)
    {
        p=p->next;
        j++;
    }
    if(j==i)
        return p;
    else
        return NULL;
}//單鏈表的查找第i個元素結點,*p=l就是使p指針指向l鏈表;
lnode *locate_linklist(linklist l,int x)
{
    lnode *p=l->next;//l為頭節點
    while(p!=NULL&&p->data!=x)
        p=p->next;
    return p;
}//單鏈表查找值為x的結點,找到后返回指向這個結點的指針;以后時刻要記得l為頭指針,因為定義了頭指針比沒有定義頭指針要方便許多;
int insert_linklist(linklist l,int i,int x)
{
    lnode *p,*s;
    p=get_linklist(l,i-1);//找到第i-1個結點
    if(p==NULL)
    {printf("i錯誤");return 0;}
    else
        s=(lnode*)malloc(sizeof(lnode));
    s->data=x;
    s->next=p->next;
    p->next=s;
    return 1;
}//單鏈表的第i個結點后面的插入,重要的是申請,封裝s結點,
int del_linklist(linklist l,int i)
{
    i--;
    linklist p,s;
    p=get_linklist(l,i-1);
    if(p==NULL)
    {
        printf("該i-1節點不存在");
        return -1;
    }
    else if(p->next==NULL)
    {
        printf("第i個結點不存在");
        return 0;
    }
    else
    {
        s=p->next;
        p->next=s->next;
        free(s);
        return 1;
    }
}//單鏈表中刪除第i個結點,那么就先要找到i個結點的前驅,也就是第i-1個結點,同理單鏈表中的插入也要知道其前驅結點,所以單鏈表中的頭節點的重要性就可想而知了
void printf_linklist(lnode *plisthead)
{
    lnode *ptemp=plisthead;
    while(ptemp)
    {
        printf("%d\t",ptemp->data);
        ptemp=ptemp->next;
    }
    printf("\n");
}//鏈表打印函數
int main()
{
    /*
    linklist l=creat_linklist_insert_end_yeshead();
    printf("%d\n",length_linklist_yeshead(l));
    insert_linklist(l,2,100);//第二個結點的后面插入100
    printf_linklist(l);
    del_linklist(l,4);//刪除第四個結點
    printf_linklist(l);
    */
    /*
    linklist l=creat_linklist_insert_head_nohead();
    printf("%d\n",length_linklist_nohead(l));
    insert_linklist(l,2,100);
    printf_linklist(l);
    del_linklist(l,4);
    printf_linklist(l);
    */
    return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM