C++實(shí)現(xiàn)雙向循環(huán)鏈表
本文實(shí)例為大家分享了C++實(shí)現(xiàn)雙向循環(huán)鏈表的具體代碼,供大家參考,具體內(nèi)容如下
一、概念
1.在雙鏈表中的每個(gè)結(jié)點(diǎn)應(yīng)有兩個(gè)鏈接指針:
lLink -> 指向前驅(qū)結(jié)點(diǎn) (前驅(qū)指針或者左鏈指針)
rLink->指向后繼結(jié)點(diǎn)(后驅(qū)指針或者右鏈指針)
2.雙鏈表常采用帶附加頭結(jié)點(diǎn)的循環(huán)鏈表方式:
first:頭指針,不存放數(shù)據(jù),或者存放特殊要求的數(shù)據(jù)。它的lLink指向雙鏈表的尾結(jié)點(diǎn)(最后一個(gè)結(jié)點(diǎn)),
它的rLink指向雙鏈表的首結(jié)點(diǎn)(第一個(gè)有效結(jié)點(diǎn))。鏈表的首結(jié)點(diǎn)的左鏈指針lLink和尾結(jié)點(diǎn)的右鏈指針
rLink都指向附加頭結(jié)點(diǎn)。
二、實(shí)現(xiàn)程序
1.DblList.h
#ifndef DblList_h #define DblList_h #include <iostream> using namespace std; template <class T> struct DblNode { // 鏈表結(jié)點(diǎn)定義 T data; DblNode<T> *lLink, *rLink; // 鏈表前驅(qū)(左鏈)和后繼(右鏈)指針 DblNode(DblNode<T> *left = NULL, DblNode<T> *right = NULL):lLink(left), rLink(right){} // 構(gòu)造函數(shù) DblNode(T value, DblNode<T> *left = NULL, DblNode<T> *right = NULL):data(value), lLink(left), rLink(right){} // 構(gòu)造函數(shù) }; template <class T> class DblList { // 雙鏈表(雙向循環(huán)鏈表) public: DblList(); // 構(gòu)造函數(shù):建立附加頭結(jié)點(diǎn) ~DblList(); // 析構(gòu)函數(shù):釋放所有存儲(chǔ) void createDblList(); // 創(chuàng)建雙向鏈表 int Length()const; // 計(jì)算雙鏈表的長(zhǎng)度 bool isEmpty(); // 判雙鏈表空否 DblNode<T> *getHead()const; // 取附加頭結(jié)點(diǎn) void setHead(DblNode<T> *ptr); // 設(shè)置附加頭結(jié)點(diǎn)地址 DblNode<T> *Search(const T x); // 在鏈表中沿后繼方向?qū)ふ业扔诮o定值x的結(jié)點(diǎn) DblNode<T> *Locate(int i, int d); // 在鏈表中定位第i個(gè)結(jié)點(diǎn),d=0按前驅(qū)方向,否則按后繼方向 bool Insert(int i, const T x, int d); // 在第i個(gè)結(jié)點(diǎn)后插入x,d=0按前驅(qū)方向,否則按后繼方向 bool Remove(int i, T &x, int d); // 刪除第i個(gè)結(jié)點(diǎn),x帶回刪除其值,d=0按前驅(qū)方向,否則按后繼方向 void Output(); // 輸出雙鏈表中的數(shù)據(jù) private: DblNode<T> *first; // 附加頭結(jié)點(diǎn) }; template <class T> DblList<T>::DblList() { // 構(gòu)造函數(shù):建立附加頭結(jié)點(diǎn) first = new DblNode<T>(); if(NULL == first) { cerr << "動(dòng)態(tài)分配內(nèi)存空間失??!" << endl; exit(1); } first->rLink = first->lLink = first; // 指向自身 } template <class T> DblList<T>::~DblList() { // 析構(gòu)函數(shù):釋放所有存儲(chǔ) 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() { // 創(chuàng)建雙向鏈表 int n, val; DblNode<T> *current = first; cout << "請(qǐng)輸入要輸入的個(gè)數(shù)n:"; cin >> n; cout << "請(qǐng)輸入要輸入的數(shù):" << endl; for(int i = 0; i < n; i++) { cin >> val; DblNode<T> *newNode = new DblNode<T>(val); if(NULL == newNode) { cerr << "動(dòng)態(tài)分配內(nèi)存空間失?。? << endl; exit(1); } // 尾插入 while(current->rLink != first) current = current->rLink; // 往后繼方向移動(dòng) 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 { // 計(jì)算雙鏈表的長(zhǎng)度 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 { // 取附加頭結(jié)點(diǎn) return first; } template <class T> void DblList<T>::setHead(DblNode<T> *ptr) { // 設(shè)置附加頭結(jié)點(diǎn)地址 first = ptr; } template <class T> DblNode<T> *DblList<T>::Search(const T x) { // 在鏈表中沿后繼方向?qū)ふ业扔诮o定值x的結(jié)點(diǎn) 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; // 搜索前驅(qū)方向 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, const T x, int d) { // 插入 DblNode<T> *current = Locate(i, d); // 查找第i個(gè)結(jié)點(diǎn) if(current == NULL) // i不合理,插入失敗 return false; DblNode<T> *newNode = new DblNode<T>(x); if(newNode == NULL) { cerr << "內(nèi)存空間分配失敗!" << endl; exit(1); } if(d == 0) { // 前驅(qū)方向插入 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, T &x, int d) { // 刪除 DblNode<T> *current = Locate(i, d); // 查找第i個(gè)結(jié)點(diǎn) 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() { // 輸出雙鏈表中的數(shù)據(jù) 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存儲(chǔ)第i個(gè),d:存儲(chǔ)方向 -》0表示前驅(qū)方向,否則為后繼方向 DblList<int> L; DblNode<int> *head = NULL, *current; while(!finished) { cout << "\n*********菜單*********\n"; cout << "1:建立雙鏈表\n"; cout << "2:雙鏈表的長(zhǎng)度\n"; cout << "3:雙鏈表是否為空?\n"; cout << "4:取附加頭結(jié)點(diǎn)\n"; cout << "5:設(shè)置附加頭結(jié)點(diǎn)地址\n"; cout << "6:在鏈表中沿后繼方向?qū)ふ业扔诮o定值x的結(jié)點(diǎn)\n"; cout << "7:在鏈表中定位第i個(gè)結(jié)點(diǎn),d=0按前驅(qū)方向,否則按后繼方向\n"; cout << "8:在第i個(gè)結(jié)點(diǎn)后插入x,d=0按前驅(qū)方向,否則按后繼方向\n"; cout << "9:刪除第i個(gè)結(jié)點(diǎn),x帶回刪除其值,d=0按前驅(qū)方向,否則按后繼方向\n"; cout << "10:輸出雙鏈表中的數(shù)據(jù):\n"; cout << "11:退出\n"; cout << "請(qǐng)輸入選擇[1-11]:\n"; cin >> choice; switch(choice) { case 1: L.createDblList(); // 建立雙鏈表 break; case 2: len = L.Length(); // 雙鏈表的長(zhǎng)度 cout << "雙鏈表的長(zhǎng)度為:" << 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); // 設(shè)置附加頭結(jié)點(diǎn)地址 break; case 6: cout << "請(qǐng)輸入要查找的值x:"; cin >> x; if(L.Search(x) != NULL) cout << "查找成功!" << endl; else cout << "查找失敗!" << endl; break; case 7: cout << "請(qǐng)輸入要定位第i個(gè)結(jié)點(diǎn)的i和方向d(d=0按前驅(qū)方向,否則按后繼方向):"; cin >> i >> d; current = L.Locate(i, d); if(current == NULL) cout << "定位失敗!" << endl; else cout << "定位成功!" << endl; break; case 8: cout << "在第i個(gè)結(jié)點(diǎn)后插入x,d=0按前驅(qū)方向,否則按后繼方向。請(qǐng)輸入i, x和d:"; cin >> i >> x >> d; if(L.Insert(i, x, d)) cout << "插入成功!" << endl; else cout << "插入失??!" << endl; break; case 9: cout << "刪除第i個(gè)結(jié)點(diǎn),x帶回刪除其值,d=0按前驅(qū)方向,否則按后繼方向。請(qǐng)輸入i和d:"; cin >> i >> d; if(L.Remove(i, x, d)) cout << "刪除成功,刪除的值為:" << x << endl; else cout << "刪除失?。? << endl; break; case 10: cout << "雙鏈表中的數(shù)據(jù)為:" << endl; L.Output(); break; case 11: finished = 1; break; default: cout << "輸入錯(cuò)誤, 請(qǐng)重新輸入!" << endl; } // switch } // while return 0; }
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
QTableWidget設(shè)置只讓某一列可編輯的實(shí)現(xiàn)
本文介紹了如何將QTableWidget的某一列設(shè)置為可編輯,以便用戶可以輸入自定義數(shù)據(jù),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-08-08C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)與算法之鏈表(一)
鏈表是線性表的鏈?zhǔn)酱鎯?chǔ)方式。鏈表的內(nèi)存是不連續(xù)的,前一個(gè)元素存儲(chǔ)地址的下一個(gè)地址中存儲(chǔ)的不一定是下一個(gè)元素。小編今天就將帶大家深入了解一下鏈表,快來學(xué)習(xí)吧2021-12-12C++利用鏈表寫一個(gè)簡(jiǎn)單的棧實(shí)例詳解
這篇文章主要介紹了C++利用鏈表寫一個(gè)簡(jiǎn)單的棧實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2017-05-05c++中為什么可以通過指針或引用實(shí)現(xiàn)多態(tài)詳解
這篇文章主要給大家介紹了關(guān)于c++中為何可以通過指針或引用實(shí)現(xiàn)多態(tài),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04Cocos2d-x學(xué)習(xí)筆記之CCScene、CCLayer、CCSprite的默認(rèn)坐標(biāo)和默認(rèn)錨點(diǎn)實(shí)驗(yàn)
這篇文章主要介紹了Cocos2d-x學(xué)習(xí)筆記之CCScene、CCLayer、CCSprite的默認(rèn)坐標(biāo)和默認(rèn)錨點(diǎn)實(shí)驗(yàn),這是一個(gè)非常值得研究的問題,需要的朋友可以參考下2014-09-09C++實(shí)現(xiàn)LeetCode(21.混合插入有序鏈表)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(21.混合插入有序鏈表),本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07C語(yǔ)言函數(shù)調(diào)用底層實(shí)現(xiàn)原理分析
這篇文章主要介紹了C語(yǔ)言函數(shù)調(diào)用底層實(shí)現(xiàn)原理,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02