日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

带头节点单链表的增删改查

發布時間:2023/11/27 生活经验 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 带头节点单链表的增删改查 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

單鏈表有很多結構循環單鏈表,有頭節點的單鏈表,無頭節點的單鏈表,雙節點單鏈表,以下源碼是以有一個頭節點的單鏈表為例寫的增刪改查的各種功能,就是下圖

?然后各個注釋也在函數后面寫著,這玩意確實還挺難,源碼均已測試,vs2019運行妥妥的

?

廢話不多說直接來看全部源碼

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
typedef int ElemType;          //后期修改程序方便
typedef struct ListNode               //定義結構體
{ElemType data;struct ListNode* next;
}ListNode;typedef struct                //頭節點
{struct ListNode* head;int cursize;
}LinkList;struct ListNode* BuyNode()           //購買節點,用malloc向堆區申請空間
{struct ListNode* s = (struct ListNode*)malloc(sizeof(struct ListNode));if (NULL == s){exit(1);}memset(s, 0, sizeof(struct ListNode));return s;
};void FreeNode(struct ListNode* p)         //堆區申請完之后必須得free
{free(p);
}int GetSize(const LinkList* plist)        //獲得cursize的大小
{assert(plist != NULL);return plist->cursize;
}bool IsEmpty(const LinkList* plist)       //判斷cursize是否為空
{assert(plist != NULL);return GetSize(plist) == 0;
}void InitList(LinkList* plist)            //初始化函數,malloc購買節點之后用memset初始化為0
{assert(plist != NULL);plist->head = BuyNode();plist->cursize = 0;
}void Print(LinkList* plist)              //輸出函數
{assert(plist != NULL);ListNode* p = plist->head->next;while (p != NULL){printf("%d ", p->data);p = p->next;}printf("\n");
}ListNode* FindeValue(LinkList* plist, ElemType val)         //找到當前值的地址
{assert(plist != NULL);ListNode* p = plist->head->next;while (plist != NULL && p->data != val){p = p->next;}return p;
}ListNode* FindeValue_Prev(LinkList* plist, ElemType val)        //查找輸入val的前驅地址
{assert(plist != NULL);ListNode* pre = plist->head;ListNode* p = plist->head->next;while (p != NULL && p->data != val){pre = p;}if (p == NULL){pre = NULL;}return p;
}bool Insert_Next(LinkList* plist, ListNode* ptr, ElemType val)         //在ptr節點后面插入val值
{assert(plist != NULL);if (ptr == NULL){return false;}ListNode* s = BuyNode();s->next = ptr->next;ptr->next = s;s->data = val;plist->cursize += 1;return true;
}void Push_Front(LinkList* plist, ElemType val)         //頭插法   
{Insert_Next(plist, plist->head, val);}void Push_Back(LinkList* plist, ElemType val)        //尾插法
{assert(plist != NULL);ListNode* p = plist->head;while (p->next != NULL){p = p->next;}Insert_Next(plist, p, val);
}void InsertItem(LinkList* plist, ElemType x, ElemType val)      //在指定x的之后插入val值
{assert(plist != NULL);ListNode* p = FindeValue(plist, x);Insert_Next(plist, p, val);
}ListNode* FindPos(const LinkList* plist, ElemType pos)        //返回當前節點
{assert(plist != NULL);if (pos<1 || pos>plist->cursize){return NULL;}int i = 1;ListNode* p = plist->head->next;while (p!=NULL && i < pos){p = p->next;i++;}return p;
}ListNode* FindPos_Prev(const LinkList* plist, ElemType pos)      //返回前驅節點
{assert(plist != NULL);if (pos<1 || pos>plist->cursize + 1){return NULL;}ListNode* p = plist->head;int i = 1;while (i < pos){p = p->next;i++;}return p;
}bool Erase_Next(LinkList* plist, ListNode* ptr)       //刪除ptr之后的節點
{assert(plist != NULL);if (NULL == ptr || NULL == ptr->next) return false;ListNode* q = ptr->next;ptr->next = q->next;FreeNode(q);plist->cursize -= 1;return true;
}void Pop_Front(LinkList* plist)          //頭刪法
{assert(plist != NULL);Erase_Next(plist, plist->head);
}void Pop_Back(LinkList* plist)           //尾刪法
{assert(plist != NULL);ListNode* p = FindeValue_Prev(plist, plist->cursize);Erase_Next(plist, p);
}void MergerList(LinkList* palist, LinkList* pblist, LinkList* pclist)        //兩個數組的有序合并
{assert(palist != NULL && pblist != NULL && pclist != NULL);ListNode* pa = palist->head->next;ListNode* pb = pblist->head->next;ListNode* pc = pclist->head;while (pa != NULL && pb != NULL){if (pa->data >= pb->data){pc->next = pb;pb = pb->next;}else{pc->next = pa;pa = pa->next;}pc = pc->next;}if (pa != NULL){pc->next = pa;}else{pc->next = pb;}pclist->cursize = palist->cursize + pblist->cursize;palist->head->next = NULL;pblist->head->next = NULL;
}int main()
{int ar[] = { 12,23,34,45,56,67,78,89,90,100 };int n = sizeof(ar) / sizeof(ar[0]);LinkList mylist;InitList(&mylist);for (int i = 0; i < n; i++){Push_Front(&mylist, ar[i]);Print(&mylist);}return 0;
}

其中函數的復用程度較高,值得仔細學習一下,初入編程的小白一個,歡迎大家來評論區交流學習。

???????乾坤穩定,你我皆是黑馬,加油!

總結

以上是生活随笔為你收集整理的带头节点单链表的增删改查的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。