链表常用操作的实现-C++模板实现

来源:互联网 发布:阿里云redis 怎么使用 编辑:程序博客网 时间:2024/05/17 02:35

注:该贴为本人在温习数据结构的过程中自娱自乐编写的代码,如有错误欢迎纠正:)

链表节点声明

template <class T>class LinkNode{public:    LinkNode(T v) { value=v; }    T value;    LinkNode<T>* next;};

链表类的声明

template <class T>class LinkList{    public:        LinkList();        LinkList(const LinkList& list);        virtual ~LinkList();        void clear();        int length() const;        bool is_empty() const;        LinkNode<T>* push_back(T value);        LinkNode<T>* insert(T value, int pos);        LinkNode<T>* remove(T value);        LinkNode<T>* find(T value) const;        //查找链表的中间节点        LinkNode<T>* find_middle() const;        //查找链表的倒数第N个节点        LinkNode<T>* find_reverse_nth(int n) const;        //链表反转        LinkList<T>& reverse();        //在链表中创建环,n表示交点相对于头节点的位置        LinkNode<T>* make_cycle(int n);        //在链表中解除环,cycle_entry表示环的入口点        void LinkList<T>::clear_cycle(LinkNode<T>* cycle_entry);        //检查链表是否有环        LinkNode<T>* check_cycle() const;        //检查链表环的入口节点        LinkNode<T>* find_cycle_entry() const;        //合并两个链表,假设两个链表都已经排序        template<class U> //这里这样定义才能编译通过,具体问题参见http://blog.csdn.net/dongzhongshu/article/details/6200466        friend LinkList<U>& mergelist(const LinkList<U>& list1, const LinkList<U>& list2);        //链表冒泡排序        LinkList<T>& bubble_sort();        //链表选择排序        LinkList<T>& select_sort();        void output() const;    private:        LinkNode<T>* head;};

构造函数和析构函数

template <class T>LinkList<T>::LinkList(){    this->head=NULL;    T tmp;    LinkNode<T> *r, *p=this->head;    cin >> tmp;    while(tmp != MIN_INT) //此处先争对int型,以后再修改    {        r=new LinkNode<T>(tmp);        r->next=NULL;        if(head==NULL)            head=r;        else            p->next=r;        p=r;        cin >> tmp;    }}template <class T>LinkList<T>::LinkList(const LinkList& list){    LinkNode<T> *p=list.head;    LinkNode<T> *q=NULL, *r=NULL;    head=NULL;    while(p!=NULL)    {        r=new LinkNode<T>(p->value);        r->next=NULL;        if(head==NULL)        {            head=r;        }        if(q!=NULL)        {            q->next=r;        }        q=r;        p=p->next;    }}template <class T>void LinkList<T>::clear(){    LinkNode<T>* p=this->head;    while(head!=NULL)    {        head=head->next;        p->next=NULL;        delete p;        p=head;    }}
template <class T>LinkList<T>::~LinkList(){    clear();}

检查链表是否为空

template <class T>bool LinkList<T>::is_empty() const{    return head==NULL;}template <class T>

链表的长度

int LinkList<T>::length() const{    int size=0;    LinkNode<T>* p=head;    while(p!=NULL)    {        size++;        p=p->next;    }    return size;}



链表的插入和删除

template <class T>LinkNode<T>* LinkList<T>::push_back(T value){    LinkNode<T>* p=head,q;    while(p!=NULL && p->next!=NULL)        p=p->next;    q=new LinkNode<T>(value);    q->next=NULL;    if(p!=NULL)        p->next=q;    else        head=q;    return q;}template <class T>LinkNode<T>* LinkList<T>::insert(T value, int pos){    LinkNode<T>* p=head, q=p, r;    for(int i=0; i<pos && p!=NULL; i++)    {        q=p;        p=p->next;    }    r=new LinkNode<T>(value);    if(!q)        head=r;    else        q->next=r;    r->next=p;    return r;}template <class T>LinkNode<T>* LinkList<T>::remove(T value){    LinkNode<T>* p=head, q;    while(p)    {        if(p->value==value)        {            if(q)            {                q->next=p->next;            }            p->next=NULL;            delete p;        }        q=p;        p=p->next;    }}

查找,包括普通查找,查找中间节点以及查找倒数第N个节点

关于后面两个查找的原理请参考链表笔试面试题

template <class T>LinkNode<T>* LinkList<T>::find(T value) const{    LinkNode<T>* p=head;    while(p)    {        if(p->value==value)            return p;        p=p->next;    }    return NULL;}template <class T>LinkNode<T>* LinkList<T>::find_middle() const{    LinkNode<T>* p=head,*q=head;    while(q!=NULL)    {        if(q->next!=NULL)            q=q->next->next;        else            break;        p=p->next;    }    return p;}template <class T>LinkNode<T>* LinkList<T>::find_reverse_nth(int n) const{    if(n>length())        return NULL;    LinkNode<T> *p=head,*q=head;    for(int i=0; i<n; i++)    {        if(p!=NULL)            p=p->next;        else            return NULL;    }    while(p!=NULL)    {        p=p->next;        q=q->next;    }    return q;}

链表倒转

template <class T>LinkList<T>& LinkList<T>::reverse(){    LinkNode<T> *p=head,*q=NULL,*r=NULL;    if(p!=NULL)        q=p->next;    while(q!=NULL)    {        r=q->next;        q->next=p;        p=q;        q=r;    }    head->next=NULL;    head=p;    return *this;}template <class T>LinkNode<T>* LinkList<T>::_reverse(LinkNode<T>* pNode){    if(pNode==NULL)        return NULL;    else if(pNode->next==NULL)}

去除链表中存在的环

template <class T>void LinkList<T>::clear_cycle(LinkNode<T>* cycle_entry){    LinkNode<T>*q=cycle_entry;    while(q->next!=cycle_entry)        q=q->next;    q->next=NULL;}

检查链表中是否有环

template <class T>LinkNode<T>* LinkList<T>::check_cycle() const{    LinkNode<T> *p=head, *q=(head==NULL)?NULL:p->next;    while(p!=q)    {        if(p)            p=p->next;        else            break;        if(q)            q=q->next;        else            break;        if(q)            q=q->next;        else            break;    }    if(!p || !q) return NULL;    return p;}

查找链表中环的入口节点

template <class T>LinkNode<T>* LinkList<T>::find_cycle_entry() const{    LinkNode<T>* jointNode=check_cycle();    if(jointNode==NULL)        return NULL;    LinkNode<T>* p=jointNode->next;    LinkNode<T>* q=head;    while(p!=q)    {        p=p->next;        q=q->next;    }    return p;}

合并两个有序列表

template <class T>LinkList<T>& mergelist(const LinkList<T>& list1, const LinkList<T>& list2){    LinkList<T>* pNewList;    if(list1.is_empty())    {        pNewList=new LinkList<T>(list2);        return *pNewList;    }    pNewList=new LinkList<T>(list1);    if(list2.is_empty())        return *pNewList;    LinkNode<T> *p=pNewList->head, *q, *r=list2.head, *s;    while(r)    {        if(p && p->value<=r->value)        {            q=p;            p=p->next;        }        else        {            s=new LinkNode<T>(r->value);            q->next=s;            s->next=p;            q=s;            r=r->next;        }    }    return *pNewList;}

链表的插入排序和选择排序

template <class T>LinkList<T>& LinkList<T>::bubble_sort(){    LinkNode<T> *p,*q;    for(p=head;p;p=p->next) //这个循环只是为了让循环达到和链表中节点相等的个数,p不会被实际用到        for(q=head;q->next;q=q->next)    {        if(q->value>q->next->value)        {            T tmp=q->value;            q->value=q->next->value;            q->next->value=tmp;        }    }}template <class T>LinkList<T>& LinkList<T>::select_sort(){    LinkNode<T> *p=head,*q, *smallest;    for(;p;p=p->next)    {        smallest=p;        for(q=p->next;q;q=q->next)        {            if(q->value<smallest->value)                smallest=q;        }        if(smallest!=p)        {            T tmp=smallest->value;            smallest->value=p->value;            p->value=tmp;        }    }    return *this;}

链表的输出

template <class T>void LinkList<T>::output() const{    LinkNode<T>* p=head;    while(p)    {        cout << p->value << " ";        p=p->next;    }    cout << endl;}



原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 au没有波形 没有声音怎么办 屏幕驱动板坏了怎么办 安吉星流量超了怎么办 网络被伪基站覆盖怎么办 骨头渣子卡嗓子里怎么办 执法仪记录仪关不了机怎么办 执法记录仪开不了机怎么办 华为警务通丢了怎么办 华德安执法记录仪死机怎么办 行车仪内存满了怎么办 海康威视摄像头没有通道怎么办 电脑屏膜变大了怎么办 手机2g模块坏了怎么办 腾讯大王卡是2g怎么办 华为手机4g坏了怎么办 优盘中毒打不开怎么办 vr头戴链接不起怎么办 人在缺氧的时候怎么办 脑缺氧供血不足怎么办 睡多了大脑缺氧怎么办 吃了过期的东西怎么办 吃了过期的牛肉怎么办 生存战争肉腐烂了怎么办? 家里进了蝙蝠找不到了怎么办 方舟手游恐龙找不到了怎么办 这是我的战争怎么办 小孩吃坏东西呕吐发烧怎么办 睿芽密码忘了怎么办 做绿豆糕太稀了怎么办 自热火锅吃完后怎么办 自煮火锅吃完了怎么办 自热火锅没熟怎么办 厕所被米饭堵了怎么办 减完肥肉特别松怎么办 新开的熟食店没人光顾怎么办 吃剩的软炸里脊怎么办 小火锅加热时胀盒该怎么办 天丝面料容易皱怎么办 快递员拒不送件怎么办 鞋店里面买到假鞋子了怎么办 孕吐伤了胃疼怎么办