C++實現雙向迴圈連結串列
阿新 • • 發佈:2020-04-28
本文例項為大家分享了C++實現雙向迴圈連結串列的具體程式碼,供大家參考,具體內容如下
一、概念
1.在雙鏈表中的每個結點應有兩個連結指標:
lLink -> 指向前驅結點 (前驅指標或者左鏈指標)
rLink->指向後繼結點(後驅指標或者右鏈指標)
2.雙鏈表常採用帶附加頭結點的迴圈連結串列方式:
first:頭指標,不存放資料,或者存放特殊要求的資料。它的lLink指向雙鏈表的尾結點(最後一個結點),
它的rLink指向雙鏈表的首結點(第一個有效結點)。連結串列的首結點的左鏈指標lLink和尾結點的右鏈指標
rLink都指向附加頭結點。
二、實現程式
1.DblList.h
#ifndef DblList_h #define DblList_h #include <iostream> using namespace std; template <class T> struct DblNode { // 連結串列結點定義 T data; DblNode<T> *lLink,*rLink; // 連結串列前驅(左鏈)和後繼(右鏈)指標 DblNode(DblNode<T> *left = NULL,DblNode<T> *right = NULL):lLink(left),rLink(right){} // 建構函式 DblNode(T value,DblNode<T> *left = NULL,DblNode<T> *right = NULL):data(value),lLink(left),rLink(right){} // 建構函式 }; template <class T> class DblList { // 雙鏈表(雙向迴圈連結串列) public: DblList(); // 建構函式:建立附加頭結點 ~DblList(); // 解構函式:釋放所有儲存 void createDblList(); // 建立雙向連結串列 int Length()const; // 計算雙鏈表的長度 bool isEmpty(); // 判雙鏈表空否 DblNode<T> *getHead()const; // 取附加頭結點 void setHead(DblNode<T> *ptr); // 設定附加頭結點地址 DblNode<T> *Search(const T x); // 在連結串列中沿後繼方向尋找等於給定值x的結點 DblNode<T> *Locate(int i,int d); // 在連結串列中定位第i個結點,d=0按前驅方向,否則按後繼方向 bool Insert(int i,const T x,int d); // 在第i個結點後插入x,d=0按前驅方向,否則按後繼方向 bool Remove(int i,T &x,int d); // 刪除第i個結點,x帶回刪除其值,d=0按前驅方向,否則按後繼方向 void Output(); // 輸出雙鏈表中的資料 private: DblNode<T> *first; // 附加頭結點 }; template <class T> DblList<T>::DblList() { // 建構函式:建立附加頭結點 first = new DblNode<T>(); if(NULL == first) { cerr << "動態分配記憶體空間失敗!" << endl; exit(1); } first->rLink = first->lLink = first; // 指向自身 } template <class T> DblList<T>::~DblList() { // 解構函式:釋放所有儲存 DblNode<T> *current = first->rLink; while(current != first) { current->rLink->lLink = current->lLink; // 從lLink鏈中摘下 current->lLink->rLink = current->rLink; // 從rLink鏈中摘下 delete current; // 釋放空間 current = first->rLink; } delete first; first = NULL; } template <class T> void DblList<T>::createDblList() { // 建立雙向連結串列 int n,val; DblNode<T> *current = first; cout << "請輸入要輸入的個數n:"; cin >> n; cout << "請輸入要輸入的數:" << endl; for(int i = 0; i < n; i++) { cin >> val; DblNode<T> *newNode = new DblNode<T>(val); if(NULL == newNode) { cerr << "動態分配記憶體空間失敗!" << endl; exit(1); } // 尾插入 while(current->rLink != first) current = current->rLink; // 往後繼方向移動 newNode->rLink = current->rLink; current->rLink = newNode; newNode->rLink->lLink = newNode; newNode->lLink = current; current = current->rLink; // current往後移 } } template <class T> int DblList<T>::Length()const { // 計算雙鏈表的長度 DblNode<T> *current = first->rLink; int count = 0; while(current != first) { current = current->rLink; count++; } return count; } template <class T> bool DblList<T>::isEmpty() { // 判雙鏈表空否 return first->rLink == first; } template <class T> DblNode<T> *DblList<T>::getHead()const { // 取附加頭結點 return first; } template <class T> void DblList<T>::setHead(DblNode<T> *ptr) { // 設定附加頭結點地址 first = ptr; } template <class T> DblNode<T> *DblList<T>::Search(const T x) { // 在連結串列中沿後繼方向尋找等於給定值x的結點 DblNode<T> *current = first->rLink; while(current != first && current->data != x) current = current->rLink; if(current != first) return current; // 搜尋成功 else // 搜尋失敗 return NULL; } template <class T> DblNode<T> *DblList<T>::Locate(int i,int d) { // 定位 if((first->rLink == first) || (i = 0)) return first; DblNode<T> *current; if(d == 0) current = first->lLink; // 搜尋前驅方向 else current = first->rLink; for(int j = 1; j < i; j++) { if(current == first) break; else if(d == 0) current = current->lLink; else current = current->rLink; } if(current != first) // 定位成功 return current; else return NULL; } template <class T> bool DblList<T>::Insert(int i,int d) { // 插入 DblNode<T> *current = Locate(i,d); // 查詢第i個結點 if(current == NULL) // i不合理,插入失敗 return false; DblNode<T> *newNode = new DblNode<T>(x); if(newNode == NULL) { cerr << "記憶體空間分配失敗!" << endl; exit(1); } if(d == 0) { // 前驅方向插入 newNode->lLink = current->lLink; current->lLink = newNode; newNode->lLink->rLink = newNode; newNode->rLink = current; } else { // 後繼方向插入 newNode->rLink = current->rLink; current->rLink = newNode; newNode->rLink->lLink = newNode; newNode->lLink = current; } return true; } template <class T> bool DblList<T>::Remove(int i,int d) { // 刪除 DblNode<T> *current = Locate(i,d); // 查詢第i個結點 if(current == NULL) // i不合理,插入失敗 return false; current->rLink->lLink = current->lLink; // 從lLink鏈中摘下 current->lLink->rLink = current->rLink; // 從rLink鏈中摘下 x = current->data; delete current; // 釋放空間 current = NULL; // 指向空 return true; // 刪除成功 } template <class T> void DblList<T>::Output() { // 輸出雙鏈表中的資料 DblNode<T> *current = first->rLink; while(current != first) { cout << current->data << " "; current = current->rLink; } cout << endl; } #endif /* DblList_h */
2.main.cpp
#include "DblList.h" using namespace std; int main(int argc,const char * argv[]) { int finished = 0,choice,i,x,d,len; // i儲存第i個,d:儲存方向 -》0表示前驅方向,否則為後繼方向 DblList<int> L; DblNode<int> *head = NULL,*current; while(!finished) { cout << "\n*********選單*********\n"; cout << "1:建立雙鏈表\n"; cout << "2:雙鏈表的長度\n"; cout << "3:雙鏈表是否為空?\n"; cout << "4:取附加頭結點\n"; cout << "5:設定附加頭結點地址\n"; cout << "6:在連結串列中沿後繼方向尋找等於給定值x的結點\n"; cout << "7:在連結串列中定位第i個結點,d=0按前驅方向,否則按後繼方向\n"; cout << "8:在第i個結點後插入x,d=0按前驅方向,否則按後繼方向\n"; cout << "9:刪除第i個結點,x帶回刪除其值,d=0按前驅方向,否則按後繼方向\n"; cout << "10:輸出雙鏈表中的資料:\n"; cout << "11:退出\n"; cout << "請輸入選擇[1-11]:\n"; cin >> choice; switch(choice) { case 1: L.createDblList(); // 建立雙鏈表 break; case 2: len = L.Length(); // 雙鏈表的長度 cout << "雙鏈表的長度為:" << len << endl; break; case 3: if(L.isEmpty()) // 雙鏈表是否為空 cout << "雙鏈表為空" << endl; else cout << "雙鏈表不空" << endl; break; case 4: head = L.getHead(); break; case 5: L.setHead(head); // 設定附加頭結點地址 break; case 6: cout << "請輸入要查詢的值x:"; cin >> x; if(L.Search(x) != NULL) cout << "查詢成功!" << endl; else cout << "查詢失敗!" << endl; break; case 7: cout << "請輸入要定位第i個結點的i和方向d(d=0按前驅方向,否則按後繼方向):"; cin >> i >> d; current = L.Locate(i,d); if(current == NULL) cout << "定位失敗!" << endl; else cout << "定位成功!" << endl; break; case 8: cout << "在第i個結點後插入x,d=0按前驅方向,否則按後繼方向。請輸入i,x和d:"; cin >> i >> x >> d; if(L.Insert(i,d)) cout << "插入成功!" << endl; else cout << "插入失敗!" << endl; break; case 9: cout << "刪除第i個結點,x帶回刪除其值,d=0按前驅方向,否則按後繼方向。請輸入i和d:"; cin >> i >> d; if(L.Remove(i,d)) cout << "刪除成功,刪除的值為:" << x << endl; else cout << "刪除失敗!" << endl; break; case 10: cout << "雙鏈表中的資料為:" << endl; L.Output(); break; case 11: finished = 1; break; default: cout << "輸入錯誤,請重新輸入!" << endl; } // switch } // while return 0; }
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。