首先編寫頭文件,頭文件裏做相關的定義和聲明,DList.h內容如下:
- #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內容如下:
- #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.h內容如下:
- #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");
- }