单向链表C++模板实现

单向链表的C++模板实现,实现了插入,删除,查找等链表常用功能,代码已编译通过,若有问题,欢迎读者交流指正。

#include<iostream>
template <class T>
struct Node
{
    T data;
    Node<T>* next;

    Node();
    Node(T val, Node<T>* link = nullptr);
};

template <class T>
Node<T>::Node()
{
    next = nullptr;
}

template <class T>
Node<T>::Node(T val, Node<T>* link)
{
    data = val;
    next = link;
}

template <class T>
class LinkList
{
    protected:
        Node<T>* head;
        int length;

    public:
        LinkList();
        LinkList(T data[], int len);
        virtual ~LinkList();
        LinkList(const LinkList<T>& lk);//赋值构造
        LinkList<T> &operator = (const LinkList<T>& lk);//重载=操作符

        /*功能实现*/
        int GetLinkLen()const;
        bool IsEmpty()const;
        void clear();//清空
        void Traverse(void(*Vist)(const T&))const;//遍历
        int locateElem(const T& link);//查找位置

        void GetElem(int pos, T& val);//获取pos位置的元素


        int deleteElem(int pos, T& t);//删除pos位置的节点
        int insertEle(int pos, const T& t);//任意pos位置插入
        int insertEle(const T& t);//尾插


};

template <class T>
LinkList<T>::LinkList()
{
    head = new Node<T>;
    length = 0;
}

template <class T>
LinkList<T>::LinkList(T data[], int len)//传入数组及数组长度
{
    Node<T>* p = nullptr;
    p = head = new Node<T>;
    for (int i = 0; i < len; i++)
    {
        p->next = new Node<T>(data[i], nullptr);
        p = p->next;
    }
    length = len;
}

template <class T>
LinkList<T>::LinkList(const LinkList<T>& lk)
{
    int lklen = lk.length;
    T val;
    head = new Node<T>;
    length = 0;

    for (int i = 1; i < lklen; i++)
    {
        lk.GetElem(i, val);
        insertEle(val);
    }
}

template <class T>
LinkList<T> &LinkList<T>::operator =(const LinkList<T> & lk)
{
    if (lk != this)
    {
        //开始赋值
        int len = lk.GetLinkLen();

        T val;
        clear();

        for (int i = 1; i <= len; i++)
        {
            lk.GetElem(i, val);
            insertEle(val);
        }
    }
    else
    {
        return *this;
    }
}

template <class T>
LinkList<T>::~LinkList()
{
    clear();
    delete head;
}

template <class T>
int LinkList<T>::GetLinkLen()const
{
    return length;
}

template <class T>
void LinkList<T>::clear()
{
    Node<T>* p = head->next;
    while (p != nullptr)
    {
        //TODO
        head->next = p->next;
        delete p;
        p = head->next;
    }


    length = 0;
}

template <class T>
bool LinkList<T>::IsEmpty()const
{
    return head->next == nullptr;
}

template <class T>
int LinkList<T>::locateElem(const T& elm)
{
    Node<T>* p = head->next;
    int count = 0;
    while (p != nullptr && p->data != elm)
    {
        count++;
        p = p->next;
    }

    return p == nullptr ? 0 : count;
}
template <class T>
void LinkList<T>::Traverse(void(*Vist)(const T&))const
{
    Node<T>* p = head->next;
    while ( p != nullptr)
    {
        //TODO
        (*Vist)(p->data);
        p = p->next;
    }
}

template <class T>
void LinkList<T>::GetElem(int pos, T& val)
{
    Node<T>* p = head->next;
    if ( pos < 1 || pos > length)
    {
        return;
    }
    for (int i = 1; i < pos; i++)
    {
        p = p->next;
    }
    val = p->data;
}

template <class T>
int LinkList<T>::deleteElem(int pos, T& val)
{
    if (pos < 1 || pos > length )
    {
        return -1;
    }
    Node<T>* p = head->next;

    std::cout << "start loc:" <<  p->data << std::endl;
    for (int i = 1; i < pos; i++)
    {
        p = p->next;
    }

    std::cout << "delete loc" <<  p->data << std::endl;
    
    Node<T>* q = p->next;
    p->next = q->next;
    val = q->data;
    delete q;

    length--;
    return 0;
}

template<class T>
int LinkList<T>::insertEle(int pos, const T& val)
{
    if (pos < 1 || pos > length)
    {
        return -1;
    }

    Node<T>* p = head->next, *q;

    for ( int i = 1; i < pos; i++)
    {
        p = p->next;
    }
    std::cout << "insert pos" << p->data << std::endl;
    q = new Node<T>(val, p->next);
    p->next = q;
    length++;
    return 0;
}

template <class T>
int LinkList<T>::insertEle(const T& val)
{
    Node<T>* p = head, *q;

    while (p->next != nullptr)
    {
        //TODO
        p = p->next;
    }

    q = new Node<T>(val, nullptr);
    p->next = q;
    length++;
    return 0;
}
//测试程序
int main ()
{
    int val = 0;
    int arr[] = {1, 3, 5, 7, 8, 10, 12};
    LinkList<int> list(arr, 7);


    list.insertEle(2);
    list.insertEle(5);
    list.insertEle(6);
    list.insertEle(10);

    int pos = list.locateElem(10);
    std::cout << "pos:"<< pos << std::endl;

    for (int i = 1 ; i <= list.GetLinkLen(); i++)
    {
        list.GetElem(i, val);
        std::cout << val << std::endl;
    }
    val = 10;
    list.deleteElem(6, val);
    std::cout << "***" << std::endl;
    for (int i = 1 ; i <= list.GetLinkLen(); i++)
    {
        list.GetElem(i, val);
        std::cout << val << std::endl;
    }
    val = 99;
    list.insertEle(6, val);
    std::cout << "***" << std::endl;
    for (int i = 1 ; i <= list.GetLinkLen(); i++)
    {
        list.GetElem(i, val);
        std::cout << val << std::endl;
    }
    return 0;
}
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值