生活随笔
收集整理的這篇文章主要介紹了
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;?? ?? ?? Position?MakeNode(Item?i);?? ?? ?? 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);?? ?? ?? Position?GetNext(Position?p);?? ?? ?? Position?GetPrevious(Position?p);?? ?? ?? PNode?InsFirst(DList?*plist,PNode?pnode);?? ?? ?? PNode?DelFirst(DList?*plist);?? ?? ?? Item?GetItem(Position?p);?? ?? ?? void?SetItem(Position?p,Item?i);?? ?? ?? PNode?Remove(DList?*plist);?? ?? ?? PNode?InsBefore(DList?*plist,Position?p,PNode?s);?? ?? ?? PNode?InsAfter(DList?*plist,Position?p,PNode?s);?? ?? ?? PNode?LocatePos(DList?*plist,int?i);?? ?? ?? void?ListTraverse(DList?*plist,void?(*visit)());?? #endif??
DList.c ?
[cpp]?view plaincopy
#include"DList.h"?? #include<malloc.h>?? #include<stdlib.h>?? ?? 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;?? }?? ?? 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;?? }?? ?? ?? Position?GetNext(Position?p)?? {?? ????return?p->next;?? }?? ?? ?? Position?GetPrevious(Position?p)?? {?? ????return?p->previous;?? }?? ?? ?? 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;?? ????}?? }?? ?? 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;?? }?? ?? 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;?? }?? ?? ?? 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;?? }?? ?? ?? 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 算法与数据结构--双向链表的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。