C語言實現單鏈表。

因爲順序表的不足而產生了鏈表,鏈表是一種物理存儲單元上非連續、非順序的存儲結構,數據元素的邏輯順序是通過鏈表中的指針鏈接次序實現的。鏈表由一系列結點(鏈表中每一個元素稱爲結點)組成,結點可以在運行時動態生成。每個結點包括兩個部分:一個是存儲數據元素的數據域,另一個是存儲下一個結點地址的指針域。 相比於線性表順序結構,操作簡單。
這裏寫圖片描述

#include "ListNode.h"

void Compatibo(ListNode** ppList)// 增容
{
    *ppList = (ListNode *)malloc(sizeof(ListNode));
}


void PrintList(ListNode* pList)//打印鏈表
{
    if(pList == NULL);
    else if(pList->next == NULL)
        printf("%d->",pList->data);
    else 
    {
        while(pList)
        {
            printf("%d->",pList->data);
            pList = pList->next;
        }
    }
    printf("NULL\n");
}

void PushBack(ListNode** ppList, DataType x)//鏈表尾插 
{
    assert(ppList);
    ListNode *pavi = *ppList;
    //用於遍歷鏈表,若用*ppList遍歷後改變*ppList的值
    ListNode *tail  = NULL;
    Compatibo(&tail);
    tail->data = x;
    tail->next = NULL;
    if(*ppList == NULL)
    {
        *ppList = tail;
    }
    else 
    {
        while(pavi->next)
        {
            pavi = pavi->next;
        }
        pavi->next = tail;
    }
}

void PopBack(ListNode** ppList) //鏈表尾刪
{
    assert(ppList);
    ListNode *tail = *ppList;// 用tail = null 不會改變*ppList的值
    ListNode *pavi = NULL;//用 paci->next = null 幫助置空最後地址
    if(tail == NULL)
        return ;
    else if(tail->next == NULL)
    {
        free(tail);
        *ppList = NULL;
    }
    else
    {
        while(tail->next)
        {
            pavi = tail;
            tail = tail->next;
        }
        free(tail);
        pavi->next = NULL;
        //tail=pavi->next ,但tail是函數內部指針,不會改變實際鏈表,
        //而pavi->next是對內部指針的*引用,改變的是鏈表的值
    }
}

void PushFront(ListNode** ppList, DataType x) //t頭插
{
    assert(ppList);
    ListNode *pavi = NULL;
    Compatibo(&pavi);
    pavi->data = x;
    if(*ppList == NULL)
    {
        *ppList = pavi;
        pavi->next = NULL;
    }
    else 
    {
        pavi->next = *ppList;
        *ppList = pavi;
    }
}


void PopFront(ListNode** ppList) //頭刪
{
    assert(ppList);
    ListNode *pavi = NULL;
    if(*ppList == NULL)
        return ;
    else if((*ppList)->next == NULL)
    {
        free(*ppList);
        *ppList = NULL;
    }
    else 
    {
        pavi = (*ppList)->next;//先將原鏈表的第二個節點的地址保存
        free(*ppList);         //釋放第一個節點
        *ppList = pavi;         //把保存的節點地址再次賦給鏈表的頭
    }

}


ListNode* Find(ListNode* pList, DataType x) //查找第一個爲x的節點
{
    while((pList != NULL)&&(pList->data != x))//若沒這個數
    {
        pList = pList->next;
    }
    return pList;
}

//pos節點的前面插入
void Insert(ListNode** ppList, ListNode* pos, DataType x)
{
    assert(ppList && pos);
    ListNode *tail = *ppList;
    ListNode *tmp = NULL;
    Compatibo(&tmp);
    tmp->data = x;
    if(*ppList == pos)
        PushFront(ppList,x);
    else
    {
        while((tail != NULL)&&(tail->next != pos))
        {
            tail = tail->next;
        }
        if(tail == NULL)//沒有找到節點
            return ;
        tmp->next = pos;
        tail->next = tmp;
    }
}


void Erase(ListNode** ppList, ListNode* pos)//刪除節點
{
assert(ppList);
    ListNode *tail = *ppList;// 用tail = null 不會改變*ppList的值
    if(tail == pos)
    {
        *ppList = pos->next;
        free(pos);
    }

    else
    {
        while((tail != NULL)&&(tail->next  != pos))
        {
            tail = tail->next;
        }
        if(tail == NULL)
            return ;
        tail->next = pos->next;
        free(pos);
    }
}

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