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

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

链表节点声明

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;
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值