c++中的雙向鏈表寫法,主要實現(增刪查改,鏈表逆置,構造函數,運算符重載,等)
本文主要內容
1)介紹c++中雙向鏈表的寫法。
2)實現雙向鏈表中數據的增、刪、查、改、鏈表逆置、鏈表輸出
3)介紹類中構造函數、析構函數、運算符重載函數的寫法
接下來介紹雙向鏈表的成員函數:這寫函數放在頭文件中,方便編寫
#pragma once #include<iostream> using namespace std; #include<assert.h> typedef int DataType; class ListNode //節點 { public: ListNode(DataType x) :_data(x), _next(NULL), _prev(NULL) {} ListNode*_next; ListNode*_prev; DataType _data; }; class List //雙向鏈表 { public: List(); List(List&s); List&operator=(const List&s); ~List(); void PushBack(DataType x); void PopBack(); void PushFront(DataType x); void PopFront(); void Insert(ListNode *pos, DataType x); void Erase(ListNode*pos); ListNode* Find(DataType x); void Reverse(); void PrintList(); void Clear(); void PrintReverseList(); private: ListNode*_head; ListNode* _tail; };
接下來介紹各個函數,
1)構造函數(此處寫了一種,因爲只用到了這一種)
List::List() :_head(NULL), _tail(NULL) {}
2)構造函數中的拷貝構造
List::List(List&s) :_head(NULL), _tail(NULL) { ListNode*cur = s._head; while (cur) { PushBack(cur->_data); cur = cur->_next; } }
3)賦值運算符重載
List& List::operator=(const List&s) { _head = NULL; _tail = NULL; ListNode*cur = s._head; while (cur) { PushBack(cur->_data); cur = cur->_next; } return *this; }
4)析構函數
List::~List() { Clear(); } void List::Clear() { cout << "~Clear() "; ListNode*cur = _head; while (cur) { ListNode*del = cur; cur = cur->_next; delete del; } cout << " clear is NULL" << endl; }
5)增加節點的函數(三種,前增、後增、給定節點後插入)
void List::PushFront(DataType x) { if (_head == NULL) { _head = new ListNode(x); _tail = _head; } else { ListNode*temp = new ListNode(x); _head->_prev = temp; temp->_next = _head; _head = temp; } } void List::PushBack(DataType x)//後增 { if (_head == NULL) { _head = new ListNode(x); _tail = _head; } else { ListNode*temp = new ListNode(x); _tail->_next = temp; temp->_prev = _tail; _tail = temp; } } void List::Insert(ListNode *pos, DataType x) { assert(pos); if (pos == _tail) { PushBack(x); } else { ListNode*cur = pos->_next; ListNode*temp = new ListNode(x); temp->_next = cur; temp->_prev = pos; pos->_next = temp; cur->_prev = temp; } }
6)刪除節點(三種,前刪、後刪、刪除給定節點)
void List::PopFront() { if (_head == NULL) { cout << "空鏈表!" << endl; return; } else { if (_head->_next) { ListNode *temp = _head; _head = _head->_next; _head->_prev = NULL; delete temp; } else { delete _head; _head = _tail = NULL; } } } void List::PopBack() { if (_head == NULL) { cout << "空鏈表!" << endl; return; } else { if (_tail->_prev) { ListNode *temp = _tail; _tail = _tail->_prev; _tail->_next = NULL; delete temp; } else { delete _tail; _head = _tail = NULL; } } } void List::Erase(ListNode*pos) { assert(pos); if (pos == _head) { PopFront(); } else if (pos == _tail) { PopBack(); } else { ListNode*temp = pos->_prev; ListNode*next = pos->_next; temp->_next = next; next->_prev = temp; delete pos; } }
7)尋找節點
ListNode* List::Find(DataType x) { if (_head == NULL) { cout << "空鏈表!" << endl; return NULL; } ListNode*cur = _head; while (cur) { if (cur->_data == x) return cur; cur = cur->_next; } }
8)雙向鏈表逆置(兩種方法)
方法一:交換每個節點的前驅和後繼。
方法二:創建新的鏈表,從遠鏈表上摘節點然後補到新鏈表上
//void List::Reverse() //方法 一 //{ // if (_head == NULL) // { // cout << "空鏈表!" << endl; // return; // } // else if (_head == _tail) // return; // else // { // swap(_tail,_head); // ListNode *cur = _head; // while (cur) // { // swap(cur->_prev, cur->_next); // cur = cur->_next; // } // } //} void List::Reverse()//方法二 { if (_head == NULL) { cout << "空鏈表!" << endl; return; } else if (_head == _tail) return; else { ListNode*cur = _tail; ListNode *newhead = NULL; while (cur) { if (newhead == NULL) { newhead = new ListNode(cur->_data); _head = newhead; } else { ListNode*temp = new ListNode(cur->_data); newhead->_next = temp; temp->_prev = newhead; newhead = temp; _tail = temp; } ListNode* del = cur; cur = cur->_prev; delete del; } } }
9)打印鏈表(兩種,順序打印、逆序打印)
void List::PrintList()//順序打印 { ListNode*cur = _head; while (cur) { cout << cur->_data << "->"; cur = cur->_next; } cout << "NULL" << endl; } void List::PrintReverseList()//逆序打印 { cout << "從後向前:"; ListNode*cur = _tail; while (cur) { cout << cur->_data << "->"; cur = cur->_prev; } cout << "NULL" << endl; }
當然還有主函數(測試用例)
#include"List.h" void Test3() { cout << endl; List l1; l1.PushFront(1); l1.PushBack(2); l1.PushBack(3); l1.PushBack(4); l1.PushBack(5); l1.PushBack(6); //l1.PushFront(4); //l1.PopFront();//前刪 //l1.PopBack();//後刪 //ListNode *pos = l1.Find(3); //l1.Insert(pos, 5); //l1.Erase(pos); cout << "l1 :"; l1.PrintList(); l1.PrintReverseList(); cout << "逆置l1 :"; l1.Reverse(); l1.PrintList(); l1.PrintReverseList(); cout << "拷貝構造-》 l2 :"; List l2(l1); l2.PrintList(); cout << "賦值運算符重載 -》 l3 :"; List l3; l3 = l2; l3.PrintList(); } int main() { Test3(); system("pause"); return 0; }
以上函數均是在學習的過程中總結寫出的,肯定會有一些疏漏或者錯誤之處,所以敬請各位大神的批評指正,謝謝