雙向迴圈連結串列C++實現(完整版)
阿新 • • 發佈:2019-02-07
#include<iostream> using namespace std; /* *節點類 */ struct DCNode { int data; DCNode * prior; DCNode * next; }; /* *連結串列類 */ struct DCList { DCList() { size = 0; } size_t size;//記錄節點數的個數 DCNode * head;//指向連結串列的頭結點 }; /* *分配一個節點,並給該節點的資料域賦值,預設值為0; */ DCNode * MakeNode(int t=0) { DCNode * p = (DCNode *)malloc(sizeof(DCNode)); p->data = t; return p; } //初始化一個空的雙向迴圈連結串列 void InitDCList(DCList &list) { //分配一個頭結點 DCNode * p = MakeNode(); list.head = p; list.size = 0; p->next = p; p->prior = p; } //釋放所指向的節點 void FreeNode(DCNode * p) { delete p; } //清空一個線性表 void clear(DCList &list) { DCNode * p = list.head; p = p->next; while(p!= list.head) { DCNode * p1 = p->next; delete p; p = p1; } list.size = 0; } //將s所指向的節點插入到連結串列的第一個節點之前 bool InsFirst(DCList &list,DCNode * s) { s->next = list.head->next; list.head->next->prior = s; list.head->next = s; s->prior = list.head; list.size++; return true; } //刪除連結串列中的第一個節點並以q指標返回 bool DelFirst(DCList &list,DCNode * & q) { if(list.head->next==list.head)//如果連結串列為空 { q = 0; return false; } q = list.head->next; list.head->next->next->prior = list.head; list.head->next = list.head->next->next; list.size--; return true; } //將s所指向的節點串接在連結串列的最後一個節點之後 bool Append(DCList &list,DCNode * s) { s->prior = list.head->prior; s->next = list.head; list.head->prior->next = s; list.head->prior = s; list.size++; return true; } //刪除連結串列中的尾節點,並以指標q返回 bool Remove(DCList &list,DCNode * & q) { if(list.head->next==list.head)//如果連結串列為空 { q = 0; return false; } q = list.head->prior; list.head->prior->prior->next = list.head; list.head->prior = list.head->prior->prior; list.size--; return true; } //將s所指向的節點插入連結串列中p所指向的節點之前 bool InsBefore(DCList &list,DCNode * p,DCNode * s) { DCNode * p1 = list.head->next; while(p1!=list.head) { if(p1==p)//找到該連結串列中是否存在p所指向的節點 { s->next = p; s->prior = p->prior; p->prior->next = s; p->prior = s; list.size++; return true; } p1 = p1->next; } //沒找到 return false; } //將s所指向的節點插入連結串列中p所指向的節點之後 bool InsAfter(DCList &list,DCNode * p,DCNode * s) { DCNode * p1 = list.head->next; while(p1!=list.head) { if(p1==p)//找到該連結串列中是否存在p所指向的節點 { s->next = p->next; s->prior = p; p->next->prior = s; p->next = s; list.size++; return true; } p1 = p1->next; } //沒找到 return false; } //判斷連結串列是否為空 bool Empty(DCList &list) { if(list.size==0) return true; else return false; } //返回連結串列的長度 int GetLength(DCList &list) { return list.size; } //返回連結串列中第i個節點的指標 DCNode * LocatePos(DCList &list,int i) { if(i<=0&&i>(int)list.size ) return 0;//如果不存在第i個節點則返回一個0指標 int n = 0; DCNode * p1 = list.head->next; while(p1!=list.head) { n++; if(n==i)//找到 { return p1; } p1 = p1->next; } return 0; } //在連結串列中查詢第一個元素值與t相等的節點指標 DCNode * LocateElem(DCList &list,int t) { if(list.head->next==list.head)//如果連結串列為空 { return 0; } DCNode * p1 = list.head->next; while(p1!=list.head) { if(p1->data==t)//找到 { return p1; } p1 = p1->next; } return 0; } //在連結串列中查詢第一個元素值與t滿足compare函式關係的節點指標 DCNode * LocateElem(DCList &list,int t,bool (* compare)(int ,int)) { if(list.head->next==list.head)//如果連結串列為空 { return 0; } DCNode * p1 = list.head->next; while(p1!=list.head) { if((*compare)(p1->data,t))//找到了 { return p1; } p1 = p1->next; } return 0; } //依次對連結串列中的每一個元素呼叫visit函式,一旦visit函式呼叫失敗,則整個操作失敗 bool ListTraverse(DCList &list,bool (*visit)(int &)) { DCNode * p1 = list.head->next; while(p1!=list.head) { if(!(*visit)(p1->data))//找到了 { return false; } p1 = p1->next; } return true; } //合併兩個雙向迴圈連結串列 DCList & MergeList(DCList &list1,DCList &list2) { if(Empty(list1)) { return list2; } if(Empty(list2)) { return list1; } list1.head->prior->next = list2.head->next; list2.head->next->prior = list1.head->prior; list1.head->prior = list2.head->prior; list2.head->prior->next = list1.head; return list1; } //判斷是否一個數為偶數 bool judge(int a,int b) { if(a%b==0) return true; return false; } bool visit(int & t) { t = t+1; return true; } int main() { //建立並初始化一個空的雙向迴圈連結串列 DCList myList; InitDCList(myList); //在連結串列的尾端新增元素 //現分配一個節點 DCNode * s = MakeNode(1); Append(myList,s); s = MakeNode(3); Append(myList,s); s = MakeNode(5); Append(myList,s); s = MakeNode(7); Append(myList,s); //遍歷該連結串列,並輸出該連結串列的元素個數 DCNode * p1 = myList.head->next; cout<<"新建一個雙向連結串列,並初始化元素值為1,3,5,7"<<endl; while(p1!=myList.head) { cout<<p1->data<<" "; p1 = p1->next; } cout<<endl; cout<<"連結串列的元素個數為:"<<GetLength(myList)<<endl; //在連結串列的第一個資料節點之前插入兩個元素 s = MakeNode(9); InsFirst(myList,s); s = MakeNode(0); InsFirst(myList,s); cout<<"在連結串列的第一個資料節點之前插入兩個元素值為0,9的節點:"<<endl; p1 = myList.head->next; while(p1!=myList.head) { cout<<p1->data<<" "; p1 = p1->next; } cout<<endl; //刪除連結串列中的第一個節點和尾節點 cout<<"刪除的第一個節點"<<endl; if(DelFirst(myList,s)) { cout<<"被刪除的第一個節點資料為:"<<s->data<<endl; } p1 = myList.head->next; while(p1!=myList.head) { cout<<p1->data<<" "; p1 = p1->next; } cout<<endl; //釋放被刪除的節點空間 FreeNode(s); cout<<"刪除的尾節點"<<endl; if( Remove(myList,s) ) { cout<<"被刪除的尾節點資料為:"<<s->data<<endl; } p1 = myList.head->next; while(p1!=myList.head) { cout<<p1->data<<" "; p1 = p1->next; } cout<<endl; //釋放被刪除的節點空間 FreeNode(s); //在第二個節點之前插入元素 p1 = LocatePos(myList,2); cout<<"第二個節點資料為:"<<p1->data<<endl; s = MakeNode(11); InsBefore(myList,p1,s); cout<<"在第二個節點之前插入一個元素值為11的新節點:"<<endl; p1 = myList.head->next; while(p1!=myList.head) { cout<<p1->data<<" "; p1 = p1->next; } cout<<endl; //在第二個節點之後插入元素 s = MakeNode(16); p1 = LocatePos(myList,2); InsAfter(myList,p1,s); cout<<"再在第二個節點之後插入一個元素值為16的新節點:"<<endl; p1 = myList.head->next; while(p1!=myList.head) { cout<<p1->data<<" "; p1 = p1->next; } cout<<endl; //查詢第一個元素值為4的倍數的節點 p1 = LocateElem(myList,4,judge); cout<<"找到第一個元素值為4的倍數的節點資料為:"<<p1->data<<endl; //將連結串列中所有的元素值都增加1 ListTraverse(myList,visit); cout<<"將連結串列中所有的元素值都增加1:"<<endl; p1 = myList.head->next; while(p1!=myList.head) { cout<<p1->data<<" "; p1 = p1->next; } cout<<endl; //新建一個元素值為1,3,9的連結串列 DCList myList2; InitDCList(myList2); //在連結串列的尾端新增元素 //現分配一個節點 s = MakeNode(1); Append(myList2,s); s = MakeNode(3); Append(myList2,s); s = MakeNode(9); Append(myList2,s); //遍歷該連結串列,並輸出該連結串列的元素個數 cout<<"新建一個元素值為1,3,9的連結串列:"<<endl; p1 = myList2.head->next; while(p1!=myList2.head) { cout<<p1->data<<" "; p1 = p1->next; } cout<<endl; //合併兩個連結串列 myList = MergeList(myList,myList2); cout<<"合併兩個連結串列:"<<endl; p1 = myList.head->next; while(p1!=myList.head) { cout<<p1->data<<" "; p1 = p1->next; } cout<<endl; cout<<"最後清空myList連結串列!"<<endl; clear(myList); }