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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux c 算法与数据结构--双向链表

發布時間:2023/12/9 linux 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux c 算法与数据结构--双向链表 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

鏈表是linux c中非常重要的數據結構,雙向鏈表與單向鏈表的區別,是它每個節點有兩個指針域,分別指向該節點的前一個節點與后一個節點;

而鏈表的操作主要是查詢、插入、刪除、遍歷等,下面來看一個雙向鏈表,主要是進行寫小練習,加深印象!

代碼如下:

Dlist.h

[cpp]?view plaincopy
  • #ifndef?DList_H??
  • #define?DList_H??
  • typedef??int?Item;??
  • typedef?struct?Node?*?PNode;??
  • typedef?PNode?Position;??
  • /*定義節點類型*/??
  • typedef?struct?Node??
  • {??
  • ????Item?data;????????/*數據域*/??
  • ????PNode?previous;?/*指向前驅*/??
  • ????PNode?next;????????/*指向后繼*/??
  • }Node;??
  • /*定義鏈表類型*/??
  • typedef?struct??
  • {??
  • ????PNode?head;????????/*指向頭節點*/??
  • ????PNode?tail;????????/*指向尾節點*/??
  • ????int?size;??
  • }DList;??
  • ??
  • /*分配值為i的節點,并返回節點地址*/??
  • Position?MakeNode(Item?i);??
  • ??
  • /*釋放p所指的節點*/??
  • void?FreeNode(PNode?p);??
  • ??
  • /*構造一個空的雙向鏈表*/??
  • DList*?InitList();??
  • ??
  • /*摧毀一個雙向鏈表*/??
  • void?DestroyList(DList?*plist);??
  • ??
  • /*將一個鏈表置為空表,釋放原鏈表節點空間*/??
  • void?ClearList(DList?*plist);??
  • ??
  • /*返回頭節點地址*/??
  • Position?GetHead(DList?*plist);??
  • ??
  • /*返回尾節點地址*/??
  • Position?GetTail(DList?*plist);??
  • ??
  • /*返回鏈表大小*/??
  • int?GetSize(DList?*plist);??
  • ??
  • /*返回p的直接后繼位置*/??
  • Position?GetNext(Position?p);??
  • ??
  • /*返回p的直接前驅位置*/??
  • Position?GetPrevious(Position?p);??
  • ??
  • /*將pnode所指節點插入第一個節點之前*/??
  • PNode?InsFirst(DList?*plist,PNode?pnode);??
  • ??
  • /*將鏈表第一個節點刪除并返回其地址*/??
  • PNode?DelFirst(DList?*plist);??
  • ??
  • /*獲得節點的數據項*/??
  • Item?GetItem(Position?p);??
  • ??
  • /*設置節點的數據項*/??
  • void?SetItem(Position?p,Item?i);??
  • ??
  • /*刪除鏈表中的尾節點并返回其地址,改變鏈表的尾指針指向新的尾節點*/??
  • PNode?Remove(DList?*plist);??
  • ??
  • /*在鏈表中p位置之前插入新節點S*/??
  • PNode?InsBefore(DList?*plist,Position?p,PNode?s);??
  • ??
  • /*在鏈表中p位置之后插入新節點s*/??
  • PNode?InsAfter(DList?*plist,Position?p,PNode?s);??
  • ??
  • /*返回在鏈表中第i個節點的位置*/??
  • PNode?LocatePos(DList?*plist,int?i);??
  • ??
  • /*依次對鏈表中每個元素調用函數visit()*/??
  • void?ListTraverse(DList?*plist,void?(*visit)());??
  • #endif??
  • DList.c ?

    [cpp]?view plaincopy
  • #include"DList.h"??
  • #include<malloc.h>??
  • #include<stdlib.h>??
  • /*分配值為i的節點,并返回節點地址*/??
  • Position?MakeNode(Item?i)??
  • {??
  • ????PNode?p?=?NULL;???
  • ????p?=?(PNode)malloc(sizeof(Node));??
  • ????if(p!=NULL)??
  • ????{??
  • ????????p->data?=?i;??
  • ????????p->previous?=?NULL;??
  • ????????p->next?=?NULL;??
  • ????}??????
  • ????return?p;??
  • }??
  • /*釋放p所指的節點*/??
  • void?FreeNode(PNode?p)??
  • {??
  • ?????free(p);??
  • }??
  • /*構造一個空的雙向鏈表*/??
  • DList?*?InitList()??
  • {??
  • ????DList?*plist?=?(DList?*)malloc(sizeof(DList));??
  • ????PNode?head?=?MakeNode(0);???
  • ????if(plist!=NULL)??
  • ????{??
  • ????????if(head!=NULL)??
  • ????????{??
  • ????????????plist->head?=?head;??
  • ????????????plist->tail?=?head;??
  • ????????????plist->size?=?0;??
  • ????????}??
  • ????????else??
  • ????????????return?NULL;??
  • ????}??
  • ????return?plist;??
  • }??
  • ??
  • /*摧毀一個雙向鏈表*/??
  • void?DestroyList(DList?*plist)??
  • {??
  • ????ClearList(plist);??
  • ????free(GetHead(plist));??
  • ????free(plist);??
  • }??
  • ??
  • /*判斷鏈表是否為空表*/??
  • int?IsEmpty(DList?*plist)??
  • {??
  • ????if(GetSize(plist)==0&&GetTail(plist)==GetHead(plist))??
  • ????????return?1;??
  • ????else??
  • ????????return?0;??
  • }??
  • /*將一個鏈表置為空表,釋放原鏈表節點空間*/??
  • void?ClearList(DList?*plist)??
  • {??
  • ????PNode?temp,p;??
  • ????p?=?GetTail(plist);??
  • ????while(!IsEmpty(plist))??
  • ????{??????
  • ????????temp?=?GetPrevious(p);??
  • ????????FreeNode(p);??
  • ????????p?=?temp;??
  • ????????plist->tail?=?temp;??
  • ????????plist->size--;??
  • ????}??
  • }??
  • ??
  • /*返回頭節點地址*/??
  • Position?GetHead(DList?*plist)??
  • {??
  • ????return?plist->head;??
  • }??
  • ??
  • /*返回尾節點地址*/??
  • Position?GetTail(DList?*plist)??
  • {??
  • ????return?plist->tail;??
  • }??
  • ??
  • /*返回鏈表大小*/??
  • int?GetSize(DList?*plist)??
  • {??
  • ????return?plist->size;??
  • }??
  • ??
  • /*返回p的直接后繼位置*/??
  • Position?GetNext(Position?p)??
  • {??
  • ????return?p->next;??
  • }??
  • ??
  • /*返回p的直接前驅位置*/??
  • Position?GetPrevious(Position?p)??
  • {??
  • ????return?p->previous;??
  • }??
  • ??
  • /*將pnode所指節點插入第一個節點之前*/??
  • PNode?InsFirst(DList?*plist,PNode?pnode)??
  • {??
  • ????Position?head?=?GetHead(plist);??
  • ??
  • ????if(IsEmpty(plist))??
  • ????????plist->tail?=?pnode;??
  • ????plist->size++;??
  • ??
  • ????pnode->next?=?head->next;??
  • ????pnode->previous?=?head;??
  • ??
  • ????if(head->next!=NULL)??
  • ????????head->next->previous?=?pnode;??
  • ????head->next?=?pnode;??
  • ??????
  • ????return?pnode;???
  • }??
  • ??
  • /*將鏈表第一個節點刪除,返回該節點的地址*/??
  • PNode?DelFirst(DList?*plist)??
  • {??
  • ????Position?head?=?GetHead(plist);??
  • ????Position?p=head->next;??
  • ????if(p!=NULL)??
  • ????{??
  • ????????if(p==GetTail(plist))??
  • ????????????plist->tail?=?p->previous;??
  • ????????head->next?=?p->next;??
  • ????????head->next->previous?=?head;??
  • ????????plist->size--;??
  • ??????????
  • ????}??????
  • ????return?p;??
  • }??
  • ??
  • /*獲得節點的數據項*/??
  • Item?GetItem(Position?p)??
  • {??
  • ????return?p->data;??
  • }??
  • ??
  • /*設置節點的數據項*/??
  • void?SetItem(Position?p,Item?i)??
  • {??
  • ????p->data?=?i;??
  • }??
  • ??
  • /*刪除鏈表中的尾節點并返回地址,改變鏈表的尾指針指向新的尾節點*/??
  • PNode?Remove(DList?*plist)??
  • {??
  • ????Position?p=NULL;??
  • ????if(IsEmpty(plist))??
  • ????????return?NULL;??
  • ????else??
  • ????{??
  • ????????p?=?GetTail(plist);??
  • ????????p->previous->next?=?p->next;??
  • ????????plist->tail?=?p->previous;??
  • ????????plist->size--;??
  • ????????return?p;??
  • ????}??
  • }??
  • /*在鏈表中p位置之前插入新節點s*/??
  • PNode?InsBefore(DList?*plist,Position?p,PNode?s)??
  • {??
  • ????s->previous?=?p->previous;??
  • ????s->next?=?p;??
  • ????p->previous->next?=?s;??????
  • ????p->previous?=?s;??
  • ??
  • ????plist->size++;??
  • ????return?s;??
  • }??
  • /*在鏈表中p位置之后插入新節點s*/??
  • PNode?InsAfter(DList?*plist,Position?p,PNode?s)??
  • {??
  • ????s->next?=?p->next;??
  • ????s->previous?=?p;??
  • ??????
  • ????if(p->next?!=?NULL)??
  • ????????p->next->previous?=?s;??
  • ????p->next?=?s;??
  • ??????
  • ????if(p?=?GetTail(plist))??
  • ????????plist->tail?=?s;??
  • ??????
  • ????plist->size++;??
  • ????return?s;??
  • }??
  • ??
  • /*返回在鏈表中第i個節點的位置*/??
  • PNode?LocatePos(DList?*plist,int?i)??
  • {??
  • ????int?cnt?=?0;??
  • ????Position?p?=?GetHead(plist);??
  • ????if(i>GetSize(plist)||i<1)??
  • ????????return?NULL;??
  • ??
  • ????while(++cnt<=i)??
  • ????{??
  • ????????p=p->next;??
  • ????}??
  • ??
  • ????return?p;??
  • }??
  • ??
  • /*依次對鏈表中每個元素調用函數visit()*/??
  • void?ListTraverse(DList?*plist,void?(*visit)())??
  • {??
  • ????Position?p?=?GetHead(plist);??
  • ????if(IsEmpty(plist))??
  • ????????exit(0);??
  • ????else??
  • ????{??
  • ??????????
  • ????????while(p->next!=NULL)??
  • ????????{??
  • ????????????p?=?p->next;??
  • ????????????visit(p->data);??????????????
  • ????????}??????????
  • ????}??
  • }??
  • test.c

    [cpp]?view plaincopy
  • #include"DList.h"??
  • #include<stdio.h>??
  • void?print(Item?i)??
  • {??
  • ????printf("數據項為%d?\n",i);??
  • }??
  • main()??
  • {??
  • ????DList?*plist?=?NULL;??
  • ????PNode?p?=?NULL;??
  • ??????
  • ????plist?=?InitList();??
  • ????p?=?InsFirst(plist,MakeNode(1));??
  • ????InsBefore(plist,p,MakeNode(2));??
  • ????InsAfter(plist,p,MakeNode(3));??
  • ??
  • ????printf("p前驅位置的值為%d\n",GetItem(GetPrevious(p)));??
  • ????printf("p位置的值為%d\n",GetItem(p));??
  • ????printf("p后繼位置的值為%d\n",GetItem(GetNext(p)));??
  • ??????
  • ??????
  • ????printf("遍歷輸出各節點數據項:\n");??
  • ????ListTraverse(plist,print);??
  • ????printf("除了頭節點該鏈表共有%d個節點\n",GetSize(plist));??
  • ????FreeNode(DelFirst(plist));??
  • ????printf("刪除第一個節點后重新遍歷輸出為:\n");??
  • ????ListTraverse(plist,print);??
  • ????printf("除了頭節點該鏈表共有%d個節點\n",GetSize(plist));??
  • ????DestroyList(plist);??
  • ????printf("鏈表已被銷毀\n");??
  • }??
  • 執行結果如下:

    總結

    以上是生活随笔為你收集整理的Linux c 算法与数据结构--双向链表的全部內容,希望文章能夠幫你解決所遇到的問題。

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