c語言實現單鏈表

c語言實現單鏈表


定義

首先來看一看單鏈表的定義(看看百度的)

單鏈表是一種鏈式存取的數據結構,用一組地址任意的存儲單元存放線性表中的數據元素。鏈表中的數據是以結點來表示的,每個結點的構成:元素(數據元素的映象) + 指針(指示後繼元素存儲位置),元素就是存儲數據的存儲單元,指針就是連接每個結點的地址數據。[1]

再來看看我用c語言的描述吧

typedef struct Node
{
    //數據域 
    int data;
    //指針域 
    struct Node *pNext;
}NODE,*PNODE;
//NODE 等價於 struct Node
//*PNODE 等價於  struct Node *

數據域:用來存放數據
指針域:用來指向下一個結點(邏輯上相連)

如果看不懂,看看圖吧:)

侵刪

HEAD是頭結點
HEAD指向的是首結點

創建

創建單鏈表
思路:
我們可以一個一個的創建node最後串在一起。。。。
也可以先創建一個頭,然後創建一下一個,並把最後一個結點的pNext指向下一個,如此循環,這裏我們就要用一個指針一直指向鏈表的最後一個(尾指針),代碼就是使用的這種

PNODE Create_Node(void) 
{ 
    int len, val;
    PNODE List;
    PNODE pHead = (PNODE)malloc(sizeof(NODE));//分配一個頭結點 
    if(NULL == pHead) 
    {
        printf("memory allocation failure");
        exit(-1);
    }
    else
    {
        PNODE pTail = pHead;    //尾指針指向頭 
        pHead->pNext = NULL;
        printf("please input the length of list: ");
        scanf("%d",&len);       //鏈表長度 
        for(int i=0; i<len; i++)
        {
            PNODE p = (PNODE)malloc(sizeof(NODE));
            if(NULL == p)
            {
                printf("memory allocation failure");
                exit(-1);
            }
            else
            {
                printf("please input the value of list: ");
                scanf("%d",&val);
                //尾指針指向p 
                p->data=val;
                pTail->pNext=p;
                p->pNext=NULL;
                pTail=p;
            }
        }
    }
    return pHead; //這裏返回的是頭結點 不是首結點  
}

銷燬

銷燬鏈表,就是幹掉這個鏈表從頭到尾,什麼都不留
思路:
從頭開始釋放,但是把頭釋放掉之後就找不到下一個結點,所以預先把下一個結點保存下來,然後刪除,循環,有點繞,你可以簡單的理解爲過河拆橋

void destory_Node(PNODE pHead)
{
    if(pHead == NULL)
        return ;
    PNODE temp = NULL;
    while(pHead != NULL)
    {
//      printf("--------\n");
//      print(pHead->data);
        temp = pHead->pNext;    //  先拿到下一個結點 
        free(pHead);
        pHead = temp;
//      if(pHead == NULL){
//          printf("NULL");
//      }
    }
}

清空

清空結點,只留下一個頭結點,並讓它指向NULL,意思就是把數據刪了留下頭
思路:直接從首節點銷燬,把頭結點指向NULL

PNODE clear_Node(PNODE pHead)
{
    if(pHead->pNext == NULL)
        return pHead;
    destory_Node(pHead->pNext);
    pHead->pNext = NULL;
    return pHead;
} 

打印

循環打印 沒什麼好說的 直接上代碼

這裏寫代碼片void print(PNODE p)
{
    p = p->pNext;
    while(NULL != p){
        printf("%d \n",p->data);
        p = p->pNext;
    }   
}

獲取長度

注意長度是從有效節點開始的

int length_Node(PNODE pHead)
{
    //這裏的長度是有效data的值 所以頭結點不算 
    int len = 0;
    PNODE p = pHead->pNext;
    while(p != NULL)
    {
        len++;
        p = p->pNext;
    } 
    return len;
}

查詢

思路:注意最前面有一個頭結點 所以會-1,這樣返回的就是第pos個結點了

PNODE find_Node(PNODE pHead, int pos)
{
    int i = 0;
    PNODE p = pHead;
    while(NULL != p && i < pos-1)
    {
        p = p->pNext;
        i++;
    }
    if(p->pNext == NULL || i > pos-1)
    {
        printf("error input pos");
        exit(-1);
    }
    return p->pNext;
}

刪除第pos個結點

思路:第一個結點特殊處理,後面的直接在查詢的基礎上找到pos-1的結點,然後拿到pos,pos+1結點,刪掉pos,把pos-1指向pos+1

bool delete_Node_pos(PNODE pHead, int pos)
{
    PNODE pre,cur,next;
    if(pos == 1)
    {
        next = pHead->pNext;
        pHead->pNext = next->pNext;
        free(next);
        next = NULL;
        return true;
    }
    pre = find_Node(pHead, pos-1);
    if(pre->pNext != NULL)
    {
        cur = pre->pNext;
        next = cur->pNext; 
        //pos前一位 指向pos後一位 
        pre->pNext = next;
        //釋放pos 
        free(cur);
        cur = NULL;
        return true;
    }
    else
    {
        printf("pos out of node");
    }
    return false;
}

在第pos插入結點

思路:重點是找到pos-1的結點,所以第一個結點特殊處理,找到前一個結點後,把他的next指向新結點,新節點指向前一個結點指向的地方

bool insert_Node(PNODE pHead, int pos, int data)
{
    PNODE p = NULL; 
    if(pos == 1){
        p = pHead;
    } 
    else
    {
        //找前一位 
        p = find_Node(pHead,pos-1);
    }
    PNODE pNew = (PNODE)malloc(sizeof(NODE));
    if(pNew == NULL)
    {
        printf("memory allocation failure");
        exit(-1);
    }
    printf("insert %d into Node->%d \n",data,pos);
    //最後結果p(pos-1)->pNew(pos)->q(pos+1原第pos結點) 
    pNew->data = data;
    PNODE q = p->pNext;
    p->pNext = pNew;
    pNew->pNext = q;
    return true;
}

完整代碼在這裏
參考

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章