帶頭結點單鏈表模板
阿新 • • 發佈:2022-03-19
#include <bits/stdc++.h> using namespace std; template<class Type> struct Node{ Type data; Node<Type> *next; Node(Node<Type> *ptr = nullptr):next(ptr){} Node(const Type &val,Node<Type> *ptr = nullptr):data(val),next(ptr){} }; template<class Type> class List{ Node<Type> *head,*tail; int len; public: List(){ head = new Node<Type>; tail = head; len = 0; } List(const List<Type> &src){ head = new Node<Type>; tail = head; len = 0;///要先初始化本身,不然會賦值失敗,clear的問題 *this = src; } ~List(){ clear(); delete head; tail = head = nullptr; } List<Type> & operator=(const List<Type> &src){ clear(); Node<Type> *p = src.head->next; while(p){ (*this).push_back(p->data); p = p->next; } return *this; } void push_front(const Type &val){ head->next = new Node<Type>(val,head->next); if(!len) tail = head->next; len++; } void push_back(const Type &val){ tail = tail->next = new Node<Type>(val); len++; } void insert(int pos,const Type &val){ assert(pos>=0 && pos<len); Node<Type> *p = findPtr(pos-1); p->next = new Node<Type>(val,p->next); len++; } void clear(){ Node<Type> *p = head->next; while(p){ Node<Type> *ptmp = p; p = p->next; delete ptmp; } head->next = nullptr; tail = head; len = 0; } void erase(int pos){ assert(pos>=0 && pos<len); Node<Type> *p; if(pos == 0) p = head; else p = findPtr(pos - 1); Node<Type> *ptmp = p->next; p->next = p->next->next; delete ptmp; if(pos == len - 1) tail = p; len--; } void pop_front(){erase(0);} void pop_back(){erase(len-1);} void replace(int pos,const Type &val){ assert(pos>=0&&pos<len); Node<Type> *p = findPtr(pos); p->data = val; } Node<Type> *findPtr(int pos)const{ if(pos<-1 && pos>=len) return nullptr; Node<Type> *p = head; int i = -1; while(i<pos && p){ p = p->next; i++; } return p; } int find(const Type &val)const{ Node<Type> *p = head->next; int j = 0; while(p && p->data != val) { p = p->next; j++; } return j<len?j:-1; } int find(const Type &val,bool(*cmp)(Type,Type))const{ Node<Type> *p = head->next; int j = 0; while(p && !cmp(p->data,val)) { p = p->next; j++; } return j<len?j:-1; } int size()const{return len;} bool empty()const{return !len;} void createList_front(const vector<Type> &src){ clear(); for(int i = 0;i<src.size();i++) (*this).push_front(src[i]); } void createList_back(const vector<Type> &src){ clear(); for(int i = 0;i<src.size();i++) (*this).push_back(src[i]); } void write()const{ Node<Type> *p = head->next; while(p){ cout<<p->data<<(p->next?"->":""); p = p->next; } cout<<endl; } }; int main(){ vector<int> v; for(int i = 0;i<10;i++) v.push_back(i); List<int> l; l.createList_back(v); l.write(); l.pop_back(); l.write(); l.pop_front(); l.write(); l.erase(4); l.write(); l.insert(2,100); l.write(); cout<<l.size()<<endl; l.replace(7,2000); l.write(); l.push_back(1000000); l.write(); l.push_front(-1000); l.write(); const List<int> lc = l; lc.write(); cout<<lc.find(-1000)<<' '<<lc.find(1000000)<<endl; l.createList_front(v); l.write(); l.clear(); cout<<l.empty()<<endl; return 0; } /** 節點 資料 後指標 構造(後指標) 構造(資料,後指標) 單鏈表 頭指標,尾指標 構造:初始化 拷貝構造:深複製 析構:銷燬 =過載:深複製 insert(下標,值):增加節點 push_back(值):尾部增加節點 push_front(值):首部增加節點 erase(下標):刪除節點 clear:刪除所有元素 pop_front:首部刪除節點 pop_back:尾部刪除節點 replace(下標):修改節點 findPtr(下標):找到元素地址 find(值):找到元素下標 find(值,比較函式):找到符合比較的元素下標 size:返回元素個數 empty:返回是否為空 createList_back(vector):後插法建立 createLIst_front(vector):前插法建立 */