c++:實現(list)帶頭結點的雙向連結串列
阿新 • • 發佈:2019-02-12
Vector與list的區別:
1.vector資料結構
vector和陣列類似,擁有一段連續的記憶體空間,並且起始地址不變。
因此能高效的進行隨機存取,時間複雜度為o(1);
但因為記憶體空間是連續的,所以在進行插入和刪除操作時,會造成記憶體塊的拷貝,時間複雜度為o(n)。
另外,當陣列中記憶體空間不夠時,會重新申請一塊記憶體空間並進行記憶體拷貝。
2.list資料結構
list是由雙向連結串列實現的,因此記憶體空間是不連續的。
只能通過指標訪問資料,所以list的隨機存取非常沒有效率,時間複雜度為o(n);
但由於連結串列的特點,能高效地進行插入和刪除。
標頭檔案:
#ifndef __LIST_H__ #define __LIST_H__ #include<iostream> using namespace std; typedef int DataType; struct ListNode { ListNode* _next; ListNode* _prev; DataType _data; ListNode(DataType x) :_data(x) , _next(NULL) , _prev(NULL) {} }; class List { typedef ListNode Node; public: List(); //建構函式 List(const List& l); //拷貝建構函式 List& operator=(const List& l); //賦值運算子過載 ~List(); //解構函式 void Swap(List& l); //交換 void show(); //列印 void PushBack(DataType x); //尾插 void PushFront(DataType x); //頭插 void PopBack(); //尾刪 void PopFront(); //頭刪 Node* Find(DataType x); //查詢 void Insert(Node* pos, DataType x);//任意位置插入 void Erase(Node* pos); // 任意位置刪除 private: Node * _head; }; #endif
list.h
#include"List.h" List::List() :_head(new Node(DataType())) { _head->_next = _head; _head->_prev = _head; } List::List(const List& l) { if(l._head == NULL) { return; } _head = new Node(DataType()); _head->_next = _head; _head->_prev = _head; Node* cur = l._head->_next; while(cur != l._head) { PushBack(cur->_data); cur = cur->_next; } } List& List::operator=(const List& l) { if(this != &l) { List tmp(l); Swap(tmp); } return *this; } List::~List() { if(_head == NULL) { return; } Node* del = _head; _head->_prev->_next = NULL; Node* tmp = del; while(del != NULL) { tmp = del->_next; delete del; del = tmp; } } void List::PushBack(DataType x) { if(NULL == _head) { return ; } Node* newNode = new Node(x); Node* tail = _head->_prev;//標記尾節點 newNode->_prev = tail; newNode->_next = _head; _head->_prev = newNode; tail->_next = newNode; } void List::PopBack() { if(_head == NULL || _head->_next == NULL) { return; } Node* del = _head->_prev; _head->_prev = del->_prev; del->_prev->_next = _head; delete del; } void List::PushFront(DataType x) { Node* newNode = new Node(x); newNode->_prev = _head; newNode->_next = _head->_next; _head->_next->_prev = newNode; _head->_next = newNode; } void List::PopFront() { if(_head == NULL || _head->_next == NULL) { return; } Node* del = _head->_next; _head->_next = del->_next; del->_next->_prev = _head; delete del; } void List::Insert(Node* pos ,DataType x) { if(pos == _head->_next) { PushFront(x); } if(pos == _head->_prev) { PushBack(x); } else { Node* newNode = new Node(x); newNode->_prev = pos->_prev; newNode->_next = pos; pos->_prev->_next = newNode; pos->_prev = newNode; } } void List::Erase(Node* pos) { if(pos == _head) { return ; } else if(pos == _head->_next) { PopFront(); } else if(pos == _head->_prev) { PopBack(); } else { pos->_prev->_next = pos->_next; pos->_next->_prev = pos->_prev; delete pos; pos->_next = NULL; pos->_prev = NULL; } } List::Node* List::Find(DataType x) { if(_head == NULL || _head->_next == NULL) { return NULL; } Node* cur = _head->_next; while(cur != _head) { if(cur->_data == x) { return cur; } cur = cur->_next; } return NULL; } void List::Swap(List& l) { swap(_head,l._head); } void List::show() { if(_head->_next == _head) { cout<<"the list is empty"<<endl; return; } else { Node* cur = _head->_next; while(cur != _head) { cout<<cur->_data<<"-"; cur = cur->_next; } cout<<"NULL"<<endl; } } void test() { List t; t.PushBack(1); t.PushBack(2); t.PushBack(4); t.PushBack(5); t.show(); t.Insert(t.Find(4),3); t.show(); t.Erase(t.Find(2)); t.show(); t.PushFront(1); t.PopBack(); t.show(); } int main() { test(); return 0; }