1. 程式人生 > 其它 >帶頭結點單鏈表模板

帶頭結點單鏈表模板

#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):前插法建立
*/