連結串列實現模板(參考用)
阿新 • • 發佈:2019-02-19
連結串列想象成火車,火車頭看做是連結串列的表頭,車廂裡載的人和物就是元素的資料域
連線車廂的不見就是元素指標,由此,連結串列的特點是:元素之間前後依賴,串聯而成
還有,我們可以發現,連結串列的元素不能隨機訪問,在火車中行走,只能挨個走過去,而不能直接跳過去
另外,除了火車頭,每節車廂前面之連線一節車廂;除了最後的車廂。這也是連結串列的特點:
元素前面和後面不會出現多個元素相連的情況
- 找到連結串列中要插入的位置
- 令待插入結點的next指標指向插入位置的當前節點
- 令插入位置之前的當前節點的next指標指向待插入結點
插入需要插入在指定位置之前:
連結串列的插入分為三個階段:
- 頭為空:將插入的新元素標誌為頭(注意index 要等於0)
- 只有一個頭的連結串列:將新節點放到頭後面,同時把新節點標誌為頭
- 遍歷操作:index表示要插入的位置,也表示插入後新元素所在的位置
首先遍歷到要被插入元素的前一個元素,然後使新節點指向原index指點
前一個元素指向新節點
連結串列的刪除操作:
- 從表頭遍歷找到要刪除的位置
- 令刪除位置前一個節點的next指標指向待刪除位置後一個節點
- 刪除節點
翻轉連結串列:
- 定義一個用於遍歷的指標,初始指向頭節點後一個節點
- 讓頭節點的next指標制空
- 從當前遍歷指標所指的節點開始遍歷連結串列,將遍歷到的節點next指標指向頭節點。遍歷過程中藉助另外一個指標儲存下一個遍歷到的節點
- 重複步驟3直至表尾,此時新連結串列就是原連結串列反轉後的連結串列
#include<iostream> using namespace std; // 請在下面實現結點類 Node //一般涉及到遍歷或者刪除的操作:一般都要考慮->next template<typename Type> class Node { public: Type data; Node<Type>* next; Node(const Type& _data) { data = _data; next = NULL; } }; // 請在下面實現連結串列類 LinkedList template<typename Type> class LinkedList { private: Node<Type>* head; public: LinkedList() { head = NULL; } ~LinkedList() { Node<Type>* current_node = head; //遍歷指標 while (current_node != NULL) { Node<Type>* delete_node = current_node; current_node = current_node->next; delete delete_node; } } //連結串列的插入 void insert(Node<Type>* node, int index); void output(); void deleteNode(int index); void reverse(); }; template<typename Type> void LinkedList<Type>::reverse() //列表的反轉操作 { //連結串列為空 if (head == nullptr) return; Node<Type>* current_node = head->next; Node<Type>* temp_node = nullptr; //用於暫存資料 head->next = nullptr; //頭節點指標制空 while (current_node != nullptr) { temp_node = current_node->next; current_node->next = head; head = current_node; current_node = temp_node; } } template<typename Type> void LinkedList<Type>::deleteNode(int index) { //兩種特殊情況的處理 //(1)頭為空 if (head == nullptr) { return; } //(2)刪除頭節點 index=0; if (index == 0) { Node<Type>* current_node = head; head = head->next; delete current_node; } //(3)正常刪除操作 Node<Type>* current_node = head; int count = 0; //移動到前一個節點 while (current_node->next != nullptr && count < index - 1) { current_node = current_node->next; count++; } //刪除操作 if (count == index - 1 && current_node->next != nullptr) { Node<Type>* delete_node = current_node->next; current_node->next = delete_node->next; delete delete_node; } } //連結串列的遍歷 template<typename Type> void LinkedList<Type>::output() { if (head == nullptr) { return; } Node<Type>* current_node = head; while (current_node != nullptr) { cout << current_node->data << " "; current_node = current_node->next; } cout << endl; } template<typename Type> void LinkedList<Type>::insert(Node<Type>* node, int index) { //情況1 表頭為空 if (head == nullptr) { if (index != 0) return; head = node; return; } //情況2 只存在一個表頭(插入表頭) if (index == 0) { node->next = head; //指向head所指向的元素 head = node; } //情況3 插入到中間 //從頭開始遍歷 Node<Type>* current_node = head; int count = 0; while (current_node->next != nullptr && count < index - 1) { //遍歷到前一個元素 current_node = current_node->next; count++; } if (count == index - 1) { node->next = current_node->next; current_node->next = node; } } int main() { LinkedList<int> linkedlist; for (int i = 1; i <= 10; ++i) { Node<int>* node = new Node<int>(i); linkedlist.insert(node, i - 1); } linkedlist.output(); linkedlist.deleteNode(3); linkedlist.output(); linkedlist.reverse(); linkedlist.output(); system("PAUSE"); return 0; }