【演算法】C++連結串列的實現以及常見的連結串列操作和測試
阿新 • • 發佈:2019-01-08
自己實現連結串列常見的操作,用作記錄,以備以後檢視
#include <iostream> #include <string.h> using namespace std; //定義節點 class Node { public: int m_data; Node *m_next; Node(int data):m_data(data),m_next(NULL){} }; class List { public: //建構函式 List():m_head(NULL){} ~List(); bool isEmpty(){return m_head;} //連結串列長度 int Length(); //列印連結串列 void Print(); //插入元素 bool Insert(int data,int pos); //查詢位置的元素 Node* FindByPos(int pos); void Delete(int pos); //逆序 void Reverse(); //插入並排序 void InsertSort(int data); //判斷連結串列中是否存在環 bool IsLoop(); //有序的兩個連結串列進行合併 Node* Combine(Node *first); public: Node *m_head; }; Node* List::Combine(Node *first) { //合併之後的頭節點 Node *head = NULL; //採用遞迴的方式進行合併 if(this->m_head == NULL) return first; if(first == NULL) return this->m_head; if(m_head->m_data < first->m_data) { head = m_head; m_head = m_head->m_next; head->m_next = Combine(first); } else { head = first; head->m_next = Combine(first->m_next); } return head; } bool List::IsLoop() { //設定兩個指標,一個走一步,一個走兩步,如果能重合,說明有環 Node *first = m_head,*second = m_head; do { first = first->m_next; second = second->m_next->m_next; }while(second != NULL && second->m_next != NULL && first != second); if(first == second) { return true; } else return false; } //插入並排序 void List::InsertSort(int data) { Node *tmp = m_head; Node *pre; //生成新的節點 Node *node = new Node(data); //判斷是不是空節點 if(m_head == NULL) { m_head = node; return; } //判斷是不是在頭插 if(data < m_head->m_data) { node->m_next = m_head; m_head = node; return; } while(tmp != NULL && tmp->m_data < data) { pre = tmp; tmp = tmp->m_next; } if(NULL == tmp) //說明到了結尾,就在尾部插入 { pre->m_next = node; return; } else //在pre和tmp之間插入 { node->m_next = pre->m_next; pre->m_next = node; } } void List::Reverse() { if(Length() < 2) return; Node *cur = m_head,*next = m_head->m_next,*tmp; while(next != NULL) { tmp = next->m_next; next->m_next = cur; cur = next; next = tmp; } m_head->m_next = NULL; m_head = cur; } //刪除給定位置後面的元素(後刪) void List::Delete(int pos) { if(Length() <= pos) { cout << "給定刪除位置超出陣列大小,刪除失敗!" << endl; return; } Node *tmp = m_head; int index = 1; //刪除頭節點 if(0 == pos) { m_head = tmp->m_next; delete tmp; return; } while(tmp != NULL && index < pos) { tmp = tmp->m_next; index++; } if(NULL == tmp) { cout << "給定刪除位置超出陣列範圍,刪除失敗!" << endl; return; } Node *de = tmp->m_next; tmp->m_next = tmp->m_next->m_next; delete de; } //查詢給定位置的元素 Node* List::FindByPos(int pos) { Node *tmp = m_head; if(tmp == NULL) { return NULL; } int index = 1; while(tmp != NULL && index < pos) { tmp = tmp->m_next; index++; } if(tmp == NULL) { return NULL; } return tmp; } //根據位置插入節點(後插),0表示在頭節點插入 bool List::Insert(int data,int pos) { Node *tmp = m_head; //生成節點 Node *node = new Node(data); //空連結串列 if(m_head == NULL) { m_head = node; return 1; } if(0 == pos) { node->m_next = m_head; m_head = node; return 1; } else { int index = 1; while(tmp != NULL && index < pos) { tmp = tmp->m_next; index++; } if(NULL == tmp) return 0; node->m_next = tmp->m_next; tmp->m_next = node; return 1; } } //列印 void List::Print() { if(m_head == NULL) cout << "空連結串列" << endl; Node *tmp = m_head; while(tmp != NULL) { cout << tmp->m_data << " "; tmp = tmp->m_next; } cout << endl; } List::~List() { Node *tmp = NULL; while(m_head != NULL) { tmp = m_head->m_next; delete m_head; m_head = tmp; } cout << "~List 被呼叫" << endl; } int List::Length() { int len = 0; Node *tmp = m_head; if(tmp == NULL) return len; else { while(tmp != NULL) { tmp = tmp->m_next; len++; } } return len; } void print(Node *p) { if(NULL == p) { cout << "節點為空" << endl; return; } while(p!=NULL) { cout << p->m_data << " "; p = p->m_next; } cout << endl; } int main() { List list; /* list.Insert(10,3); list.Insert(30,1); list.Insert(40,2); if(0 == list.Insert(20,2)) cout << "插入失敗!" << endl; list.Print(); Node *find = list.FindByPos(5); if(NULL == find) cout << "查詢失敗" << endl; // cout << "查詢的結果為:" << find->m_data << endl; int len = list.Length(); cout << "連結串列長度為:" << len << endl; list.Delete(0); list.Insert(10,1); list.Insert(50,3); list.Print(); cout << "逆序後:" << endl; list.Reverse(); list.Print();*/ list.InsertSort(10); list.InsertSort(50); list.InsertSort(80); list.InsertSort(30); list.InsertSort(20); cout << "list:"; list.Print(); /* Node *start = l ist.m_head->m_next->m_next->m_next; start->m_next = list.m_head->m_next; if(list.IsLoop()) cout << "連結串列有環" << endl; else cout << "連結串列沒有環" << endl; // list.Print();*/ List list2; list2.InsertSort(11); list2.InsertSort(44); list2.InsertSort(33); list2.InsertSort(22); cout << "list2:" ; list2.Print(); cout << "合併後:" << endl; Node *head = list.Combine(list2.m_head); print(head); return 0; }