数据结构初阶–单链表(讲解+类模板实现)

概念:链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的 。

值得注意的是:

1.链表的在逻辑是连续的,物理上不一定是连续的;
2.现实中节点是从堆上申请的。

链表的单个结点的定义

就像这个图一样,一个空间用了存放数据(数据域),另一个空间用了存放下一个节点的地址(指针域)。

template <class datetype>
struct LinkNode
{
    //&#x6570;&#x636E;&#x57DF;
    DateType data;
    //&#x6307;&#x9488;&#x57DF;
    LinkNode<datetype>* next;
    //&#x6CE8;&#x610F;&#x4E24;&#x4E2A;&#x4E8B;&#x9879;&#xFF1A;1.&#x5982;&#x679C;&#x7A0B;&#x5E8F;&#x5458;&#x63D0;&#x4F9B;&#x4E86;&#x6709;&#x53C2;&#x6784;&#x9020;&#xFF0C;&#x90A3;&#x4E48;&#x7F16;&#x8BD1;&#x5668;&#x5C31;&#x4E0D;&#x4F1A;&#x63D0;&#x4F9B;&#x9ED8;&#x8BA4;&#x7684;&#x6784;&#x9020;&#x51FD;&#x6570;&#xFF0C;&#x4F46;&#x662F;&#x4F1A;&#x63D0;&#x4F9B;&#x9ED8;&#x8BA4;&#x7684;&#x62F7;&#x8D1D;&#x6784;&#x9020;
    //2.&#x6CE8;&#x610F;&#x4E8B;&#x9879;2&#xFF1A;&#x5982;&#x679C;&#x7A0B;&#x5E8F;&#x5458;&#x63D0;&#x4F9B;&#x4E86;&#x62F7;&#x8D1D;&#x6784;&#x9020;&#xFF0C;&#x90A3;&#x4E48;&#x7F16;&#x8BD1;&#x5668;&#x4E0D;&#x4F1A;&#x63D0;&#x4F9B;&#x9ED8;&#x8BA4;&#x7684;&#x6784;&#x9020;&#x51FD;&#x6570;&#x548C;&#x62F7;&#x8D1D;&#x6784;&#x9020;
    LinkNode(LinkNode<datetype> *ptr = NULL):next(ptr) {  }
    //struct&#x7684;&#x6784;&#x9020;&#x51FD;&#x6570;&#xFF0C;&#x9ED8;&#x8BA4;&#x53C2;&#x6570;&#x6784;&#x9020;, //&#x51FD;&#x6570;&#x53C2;&#x6570;&#x8868;&#x4E2D;&#x7684;&#x5F62;&#x53C2;&#x5141;&#x8BB8;&#x6709;&#x9ED8;&#x8BA4;&#x503C;&#xFF0C;&#x4F46;&#x662F;&#x5E26;&#x9ED8;&#x8BA4;&#x503C;&#x7684;&#x53C2;&#x6570;&#x9700;&#x8981;&#x653E;&#x540E;&#x9762;
    LinkNode(const DateType& item, LinkNode<datetype>* ptr = NULL)
    {
        next = ptr;
        data = item;
    }
};
</datetype></datetype></datetype></class>

链表的小框架

template <class datetype>
class LinkList
{
public:

private:
    //&#x5934;&#x8282;&#x70B9;
    LinkNode<datetype>* head;
};
</datetype></class>

链表的接口

LinkList(); //&#x6784;&#x9020;&#x51FD;&#x6570;,&#x521D;&#x59CB;&#x5316;&#x4E3A;&#x7A7A;&#x94FE;&#x8868;
LinkList(const DateType &item);//&#x6709;&#x53C2;&#x6784;&#x9020;&#xFF0C;&#x521D;&#x59CB;&#x5316;&#x5934;&#x8282;&#x70B9;
LinkList(const LinkList<datetype>& list);//&#x62F7;&#x8D1D;&#x6784;&#x9020;,&#x62F7;&#x8D1D;&#x5355;&#x94FE;&#x8868;
CreateLink(int n);//&#x521B;&#x5EFA;&#x5355;&#x94FE;&#x8868;
~LinkList();//&#x6790;&#x6784;&#x51FD;&#x6570;,&#x5355;&#x94FE;&#x8868;&#x7684;&#x5220;&#x9664;
void PushBack(const DateType& data);//&#x5C3E;&#x63D2;
void PopBack();//&#x5C3E;&#x5220;
void PushFront(const DateType &data)&#xFF1B;//&#x5934;&#x63D2;
void PopFront();//&#x5934;&#x5220;
int Length()const;//&#x6C42;&#x5355;&#x94FE;&#x8868;&#x7684;&#x957F;&#x5EA6;
bool GetElem(int pos, DateType& data);//&#x83B7;&#x5F97;pos&#x4F4D;&#x7F6E;&#x7684;&#x5143;&#x7D20;
LinkNode<datetype>* Locate(int pos);//&#x8FD4;&#x56DE;&#x94FE;&#x8868;&#x4E2D;&#x7B2C;pos&#x4E2A;&#x5143;&#x7D20;&#x7684;&#x5730;&#x5740;&#xFF0C;&#x5982;&#x679C;pos<0或pos超出链表最大个数返回null bool insert(int pos, const datetype &data); 在序号pos位置插入元素值为data的结点 delete(int datetype& data); 删除pos位置的结点,并且返回结点 linknode<datetype>* Locate(int pos);//&#x8FD4;&#x56DE;&#x94FE;&#x8868;&#x4E2D;&#x7B2C;pos&#x4E2A;&#x5143;&#x7D20;&#x7684;&#x5730;&#x5740;&#xFF0C;&#x5982;&#x679C;pos<0或pos超出链表最大个数返回null void clear(); 清空链表 printlist()const; 输出单链表所有结点的元素值 exchangedata(int pos1, int pos2); 进行两结点元素值的交换 < code></0或pos超出链表最大个数返回null></0或pos超出链表最大个数返回null></datetype></datetype>

构造和析构

1.无参构造函数:没什么好说的,用new从堆分配一个结点的空间给我们都头结点指针,注意检查堆是否满是一个很好的习惯

2.含参构造函数:初始化头节点指向第一个结点

3.析构函数(单链表的删除):单链表的删除很简单用两个指针,从头结点开始,一前一后依次释放申请的内存即可

4.拷贝构造:操作都很简单,依次分配内存拷贝链接即可,类似于链表的构建。区别在于拷贝构造还没有LinkList对象,需要创建,而赋值已经有了LinkList对象,需要将其链表删除再重新构造

    //&#x6784;&#x9020;&#x51FD;&#x6570;,&#x521D;&#x59CB;&#x5316;&#x4E3A;&#x7A7A;&#x94FE;&#x8868;
    LinkList()
    {
        head = new LinkNode<datetype>;
        if (head == NULL)
        {
            cout << "&#x5185;&#x5B58;&#x5206;&#x914D;&#x5931;&#x8D25;" << endl;
            exit(-1);
        }
    }
    //&#x6709;&#x53C2;&#x6784;&#x9020;&#xFF0C;&#x521D;&#x59CB;&#x5316;&#x5934;&#x8282;&#x70B9;
    LinkList(const DateType &item)
    {
        //LinkNode&#x4F1A;&#x8C03;&#x7528;&#x6784;&#x9020;&#x51FD;&#x6570;&#xFF0C;&#x521D;&#x59CB;&#x5316;&#x7ED3;&#x70B9;&#x5185;&#x7684;&#x5185;&#x5BB9;
        head = new LinkNode<datetype>();
        LinkNode<datetype> *p = new LinkNode<datetype>(item);
        head->next = p;
        if (head == NULL)
        {
            cout << "&#x5185;&#x5B58;&#x5206;&#x914D;&#x5931;&#x8D25;" << endl;
            exit(-1);
        }
    }
    //&#x62F7;&#x8D1D;&#x6784;&#x9020;,&#x62F7;&#x8D1D;&#x5355;&#x94FE;&#x8868;
    LinkList(const LinkList<datetype>& list)
    {
        LinkNode<datetype>* p = list.head->next;
        if (p == NULL)
        {
            cout << "&#x5185;&#x5B58;&#x5206;&#x914D;&#x5931;&#x8D25;" << endl;
            exit(-1);
        }
        head = new LinkNode<datetype>;
        LinkNode<datetype>* h = head;
        while (p != NULL)
        {
            LinkNode<datetype>* t = new LinkNode<datetype>;
            h->next = t;
            t->data = p->data;
            p = p->next;
            h = h->next;
        }
    }
    //&#x6790;&#x6784;&#x51FD;&#x6570;,&#x5355;&#x94FE;&#x8868;&#x7684;&#x5220;&#x9664;
    ~LinkList()
    {
        //&#x7533;&#x8BF7;&#x4E00;&#x4E2A;&#x6307;&#x9488;&#x6307;&#x5411;&#x5934;&#x8282;&#x70B9;
        LinkNode<datetype>* cur = head;
        LinkNode<datetype>* next;
        while (cur)
        {
            next = cur->next;
            delete cur;
            cur = next;
        }
    }
</datetype></datetype></datetype></datetype></datetype></datetype></datetype></datetype></datetype></datetype></datetype></datetype>

首先,我们先来实现一个尾插的接口,尾插就是在链表的尾部插入一个节点。
在进行尾插的时候我们要考虑的几点:

为了更好的理解尾插,我们先看一个动图展示:

void PushBack(const DateType& data)
   {
      LinkNode<datetype>* p = new LinkNode<datetype>(data);
      if (head->next == NULL)
      {
          head->next = p;
      }
      else
      {
          LinkNode<datetype>* cur = head;
          while (cur->next != NULL)
          {
              cur = cur->next;
          }
          cur->next = p;
      }
   }
</datetype></datetype></datetype>

创建单链表

首先定义一个指向Head的指针q;
然后不断重复以下三个步骤完成单链表的构造:
①用new申请一个LinkNode的空间返回指针p,并输入数据元素;
②q->next=p,将q指针对应结点的后继修改为p;
③q=q->next,将指针指向其直接后继,这样一个结点就被链接进了链表之中

//&#x521B;&#x5EFA;&#x5355;&#x94FE;&#x8868;
    void CreateLink(int n)
    {
        LinkNode<datetype>* q = head;
        DateType* nodetemp = new DateType[n];
        for (size_t i = 0; i < n; i++)
        {
            cout << "Enter the element:  " << endl;
            cin >> nodetemp[i];
        }
        //&#x5C3E;&#x63D2;&#x6CD5;
        for (size_t i = 0; i < n; i++)
        {
            LinkNode<datetype>* p = new LinkNode<datetype>;
            p->data = nodetemp[i];
            p->next = q->next;
            q->next = p;
            q = q->next;
        }
        delete[] nodetemp;
    }
</datetype></datetype></datetype>

尾删无非就是在链表的尾部删除一个节点,听起来很简单,但是有很多细节是我们要注意的,我们要分三种情况来进行讨论:

先看动图演示:

//&#x5C3E;&#x5220;
void PopBack()
{
    //&#x5206;&#x4E09;&#x79CD;&#x60C5;&#x51B5;
    //1.&#x6CA1;&#x6709;&#x7ED3;&#x70B9;
    if (head->next == NULL)
    {
        return;
    }
     //2.&#x53EA;&#x6709;&#x4E00;&#x4E2A;&#x7ED3;&#x70B9;
    else if (head->next->next == NULL) {
        delete head->next;
        head->next= NULL;
     }
     //3.&#x4E24;&#x4E2A;&#x4EE5;&#x53CA;&#x4E24;&#x4E2A;&#x4EE5;&#x4E0A;&#x7684;&#x7ED3;&#x70B9;
     else
     {
         LinkNode<datetype>* prev = NULL;
         LinkNode<datetype>* cur = head;
         while (cur->next != NULL)
         {
             prev = cur;
             cur = cur->next;
         }
         delete cur;
         cur = NULL;
         prev->next = NULL;
     }
}
</datetype></datetype>

先看动图演示:

//&#x5934;&#x63D2;
void PushFront(const DateType &data)
{
    LinkNode<datetype>* p = new LinkNode<datetype>(data);
    p->next = head->next;
    head->next = p;
}
</datetype></datetype>

头删就要分情况讨论:

先看动图演示:

//&#x5934;&#x5220;
void PopFront()
{
     //&#x5206;&#x4E24;&#x79CD;&#x60C5;&#x51B5;
     if (head->next == NULL)
     {
         return;
     }
     else
     {
         LinkNode<datetype>* p = head->next;
         head->next = p->next;
         delete p;
         p = NULL;
    }
}
</datetype>

定位位置

封装一个函数,返回第pos位置的地址,在下面用得到

//&#x8FD4;&#x56DE;&#x94FE;&#x8868;&#x4E2D;&#x7B2C;pos&#x4E2A;&#x5143;&#x7D20;&#x7684;&#x5730;&#x5740;&#xFF0C;&#x5982;&#x679C;pos<0或pos超出链表最大个数返回null linknode<datetype>* Locate(int pos)
    {
        int i = 0;
        LinkNode<datetype>* p = head;
        if (pos < 0)
            return NULL;
        while (NULL != p && i < pos)
        {
            p = p->next;
            i++;
        }
        return p;
    }
</datetype></0或pos超出链表最大个数返回null>

单链表任意位置插入

//&#x5728;&#x5E8F;&#x53F7;index&#x4F4D;&#x7F6E;&#x63D2;&#x5165;&#x5143;&#x7D20;&#x503C;&#x4E3A;data&#x7684;&#x7ED3;&#x70B9;
    bool Insert(int pos, const DateType &data)
    {
        LinkNode<datetype>* p = Locate(pos);
        if (p == NULL)
        {
            return false;
        }
        LinkNode<datetype>* node = new LinkNode<datetype>(data);
        if (NULL == node)
        {
            cerr << "&#x5206;&#x914D;&#x5185;&#x5B58;&#x5931;&#x8D25;!" << endl;
            exit(-1);
        }
        node->next = p->next;
        p->next = node;
        return true;
    }
</datetype></datetype></datetype>

单链表的任意位置删除

先看动图演示:

//&#x5220;&#x9664;pos&#x4F4D;&#x7F6E;&#x7684;&#x7ED3;&#x70B9;&#xFF0C;&#x5E76;&#x4E14;&#x8FD4;&#x56DE;&#x7ED3;&#x70B9;
    bool Delete(int pos, DateType& data)
    {
        LinkNode<datetype>* p = Locate(pos-1);
        if (NULL == p || NULL == p->next)
            return false;
        LinkNode<datetype>* del = p->next;
        p->next = del->next;
        data = del->data;
        delete del;
        return true;
    }
</datetype></datetype>

打印链表

//&#x8F93;&#x51FA;&#x5355;&#x94FE;&#x8868;&#x6240;&#x6709;&#x7ED3;&#x70B9;&#x7684;&#x5143;&#x7D20;&#x503C;
    void PrintList()const
    {
        int count = 0;
        LinkNode<datetype>* p = head->next;
        while (p)
        {
            cout << p->data<<" "; p="p-">next;
            //&#x6253;&#x5370;&#x5341;&#x4E2A;&#x5143;&#x7D20;&#x6362;&#x884C;
            if (++count % 10 == 0)
            {
                cout << endl;
            }
        }
    }
</"></datetype>

清空链表

//&#x6E05;&#x7A7A;&#x94FE;&#x8868;
    void Clear()
    {
        //&#x6240;&#x6709;&#x7ED3;&#x70B9;&#x7684;next&#x6E05;&#x7A7A;&#xFF0C;&#x6700;&#x540E;&#x5934;&#x8282;&#x70B9;head&#x6E05;&#x7A7A;
        LinkNode<datetype>* p = NULL;
        while (head->next != NULL)
        {
            p = head->next;
            head->next = p->next;
            delete p;
        }
    }
</datetype>

单链表的长度

    //&#x6C42;&#x5355;&#x94FE;&#x8868;&#x7684;&#x957F;&#x5EA6;
    int Length()const
    {
        int count = 0;
        LinkNode<datetype>* p = head;
        while (p->next != NULL)
        {
            p = p->next;
            ++count;
        }
        return count;
    }
</datetype>

两结点元素值的互换

    //&#x8FDB;&#x884C;&#x4E24;&#x7ED3;&#x70B9;&#x5143;&#x7D20;&#x503C;&#x7684;&#x4EA4;&#x6362;
    void Exchangedata(int pos1, int pos2)
    {
        LinkNode<datetype>* p1 = Locate(pos1);
        LinkNode<datetype>* p2 = Locate(pos2);
        DateType tmp = p1->data;
        p1->data = p2->data;
        p2->data = tmp;
    }
</datetype></datetype>
#define _CRT_SECURE_NO_WARNINGS
#include<iostream> //&#x5F15;&#x5165;&#x5934;&#x6587;&#x4EF6;
#include<string>//C++&#x4E2D;&#x7684;&#x5B57;&#x7B26;&#x4E32;
using namespace std; //&#x6807;&#x51C6;&#x547D;&#x540D;&#x7A7A;&#x95F4;
template <class datetype>
struct LinkNode
{
    //&#x6570;&#x636E;&#x57DF;
    DateType data;
    //&#x6307;&#x9488;&#x57DF;
    LinkNode<datetype>* next;
    //&#x6CE8;&#x610F;&#x4E24;&#x4E2A;&#x4E8B;&#x9879;&#xFF1A;1.&#x5982;&#x679C;&#x7A0B;&#x5E8F;&#x5458;&#x63D0;&#x4F9B;&#x4E86;&#x6709;&#x53C2;&#x6784;&#x9020;&#xFF0C;&#x90A3;&#x4E48;&#x7F16;&#x8BD1;&#x5668;&#x5C31;&#x4E0D;&#x4F1A;&#x63D0;&#x4F9B;&#x9ED8;&#x8BA4;&#x7684;&#x6784;&#x9020;&#x51FD;&#x6570;&#xFF0C;&#x4F46;&#x662F;&#x4F1A;&#x63D0;&#x4F9B;&#x9ED8;&#x8BA4;&#x7684;&#x62F7;&#x8D1D;&#x6784;&#x9020;
    //2.&#x6CE8;&#x610F;&#x4E8B;&#x9879;2&#xFF1A;&#x5982;&#x679C;&#x7A0B;&#x5E8F;&#x5458;&#x63D0;&#x4F9B;&#x4E86;&#x62F7;&#x8D1D;&#x6784;&#x9020;&#xFF0C;&#x90A3;&#x4E48;&#x7F16;&#x8BD1;&#x5668;&#x4E0D;&#x4F1A;&#x63D0;&#x4F9B;&#x9ED8;&#x8BA4;&#x7684;&#x6784;&#x9020;&#x51FD;&#x6570;&#x548C;&#x62F7;&#x8D1D;&#x6784;&#x9020;
    LinkNode(LinkNode<datetype> *ptr = NULL):next(ptr) {  }
    //struct&#x7684;&#x6784;&#x9020;&#x51FD;&#x6570;&#xFF0C;&#x9ED8;&#x8BA4;&#x53C2;&#x6570;&#x6784;&#x9020;, //&#x51FD;&#x6570;&#x53C2;&#x6570;&#x8868;&#x4E2D;&#x7684;&#x5F62;&#x53C2;&#x5141;&#x8BB8;&#x6709;&#x9ED8;&#x8BA4;&#x503C;&#xFF0C;&#x4F46;&#x662F;&#x5E26;&#x9ED8;&#x8BA4;&#x503C;&#x7684;&#x53C2;&#x6570;&#x9700;&#x8981;&#x653E;&#x540E;&#x9762;
    LinkNode(const DateType& item, LinkNode<datetype>* ptr = NULL)
    {
        next = ptr;
        data = item;
    }
};
template <class datetype>
class LinkList
{
public:
    //&#x6784;&#x9020;&#x51FD;&#x6570;,&#x521D;&#x59CB;&#x5316;&#x4E3A;&#x7A7A;&#x94FE;&#x8868;
    LinkList()
    {
        head = new LinkNode<datetype>;
        if (head == NULL)
        {
            cout << "&#x5185;&#x5B58;&#x5206;&#x914D;&#x5931;&#x8D25;" << endl;
            exit(-1);
        }
    }
    //&#x6709;&#x53C2;&#x6784;&#x9020;&#xFF0C;&#x521D;&#x59CB;&#x5316;&#x5934;&#x8282;&#x70B9;
    LinkList(const DateType &item)
    {
        //LinkNode&#x4F1A;&#x8C03;&#x7528;&#x6784;&#x9020;&#x51FD;&#x6570;&#xFF0C;&#x521D;&#x59CB;&#x5316;&#x7ED3;&#x70B9;&#x5185;&#x7684;&#x5185;&#x5BB9;
        head = new LinkNode<datetype>();
        LinkNode<datetype> *p = new LinkNode<datetype>(item);
        head->next = p;
        if (head == NULL)
        {
            cout << "&#x5185;&#x5B58;&#x5206;&#x914D;&#x5931;&#x8D25;" << endl;
            exit(-1);
        }
    }
    //&#x62F7;&#x8D1D;&#x6784;&#x9020;,&#x62F7;&#x8D1D;&#x5355;&#x94FE;&#x8868;
    LinkList(const LinkList<datetype>& list)
    {
        LinkNode<datetype>* p = list.head->next;
        if (p == NULL)
        {
            cout << "&#x5185;&#x5B58;&#x5206;&#x914D;&#x5931;&#x8D25;" << endl;
            exit(-1);
        }
        head = new LinkNode<datetype>;
        LinkNode<datetype>* h = head;
        while (p != NULL)
        {
            LinkNode<datetype>* t = new LinkNode<datetype>;
            h->next = t;
            t->data = p->data;
            p = p->next;
            h = h->next;
        }
    }
    //&#x521B;&#x5EFA;&#x5355;&#x94FE;&#x8868;
    void CreateLink(int n)
    {
        LinkNode<datetype>* q = head;
        int* nodetemp = new int[n];
        for (size_t i = 0; i < n; i++)
        {
            cout << "Enter the element:  " << endl;
            cin >> nodetemp[i];
        }
        //&#x5C3E;&#x63D2;&#x6CD5;
        for (size_t i = 0; i < n; i++)
        {
            LinkNode<datetype>* p = new LinkNode<datetype>;
            p->data = nodetemp[i];
            p->next = q->next;
            q->next = p;
            q = q->next;
        }
        delete[] nodetemp;
    }
    //&#x6790;&#x6784;&#x51FD;&#x6570;,&#x5355;&#x94FE;&#x8868;&#x7684;&#x5220;&#x9664;
    ~LinkList()
    {
        //&#x7533;&#x8BF7;&#x4E00;&#x4E2A;&#x6307;&#x9488;&#x6307;&#x5411;&#x5934;&#x8282;&#x70B9;
        LinkNode<datetype>* cur = head;
        LinkNode<datetype>* next;
        while (cur)
        {
            next = cur->next;
            delete cur;
            cur = next;
        }
    }
    //&#x5C3E;&#x63D2;
   void PushBack(const DateType& data)
    {
       LinkNode<datetype>* p = new LinkNode<datetype>(data);
       if (head->next == NULL)
       {
           head->next = p;
       }
       else
       {
           LinkNode<datetype>* cur = head;
           while (cur->next != NULL)
           {
               cur = cur->next;
           }
           cur->next = p;
       }
    }
   //&#x5C3E;&#x5220;
   void PopBack()
   {
       //&#x5206;&#x4E09;&#x79CD;&#x60C5;&#x51B5;
       //1.&#x6CA1;&#x6709;&#x7ED3;&#x70B9;
       if (head->next == NULL)
       {
           return;
       }
       //2.&#x53EA;&#x6709;&#x4E00;&#x4E2A;&#x7ED3;&#x70B9;
       else if (head->next->next == NULL) {
           delete head->next;
           head->next= NULL;
       }
       //3.&#x4E24;&#x4E2A;&#x4EE5;&#x53CA;&#x4E24;&#x4E2A;&#x4EE5;&#x4E0A;&#x7684;&#x7ED3;&#x70B9;
       else
       {
           LinkNode<datetype>* prev = NULL;
           LinkNode<datetype>* cur = head;
           while (cur->next != NULL)
           {
               prev = cur;
               cur = cur->next;
           }
           delete cur;
           cur = NULL;
           prev->next = NULL;
       }
   }
    //&#x5934;&#x63D2;
   void PushFront(const DateType &data)
   {
       LinkNode<datetype>* p = new LinkNode<datetype>(data);
       p->next = head->next;
       head->next = p;
   }
    //&#x5934;&#x5220;
   void PopFront()
   {
       //&#x5206;&#x4E24;&#x79CD;&#x60C5;&#x51B5;
       if (head->next == NULL)
       {
           return;
       }
       else
       {
           LinkNode<datetype>* p = head->next;
           head->next = p->next;
           delete p;
           p = NULL;
       }
   }
    //&#x6C42;&#x5355;&#x94FE;&#x8868;&#x7684;&#x957F;&#x5EA6;
    int Length()const
    {
        int count = 0;
        LinkNode<datetype>* p = head;
        while (p->next != NULL)
        {
            p = p->next;
            ++count;
        }
        return count;
    }
    //&#x5F97;&#x5230;&#x5E8F;&#x53F7;&#x4E3A;index&#x7684;&#x7ED3;&#x70B9;&#x5143;&#x7D20;&#x503C;
    bool GetElem(int pos, DateType& data)
    {
        LinkNode<datetype>* p = Locate(pos);
        if (p == NULL)
        {
            return false;
        }
        data = p->data;
        return true;
    }
    //&#x8FD4;&#x56DE;&#x94FE;&#x8868;&#x4E2D;&#x7B2C;pos&#x4E2A;&#x5143;&#x7D20;&#x7684;&#x5730;&#x5740;&#xFF0C;&#x5982;&#x679C;pos<0或pos超出链表最大个数返回null linknode<datetype>* Locate(int pos)
    {
        int i = 0;
        LinkNode<datetype>* p = head;
        if (pos < 0)
            return NULL;
        while (NULL != p && i < pos)
        {
            p = p->next;
            i++;
        }
        return p;
    }
    //&#x5728;&#x5E8F;&#x53F7;index&#x4F4D;&#x7F6E;&#x63D2;&#x5165;&#x5143;&#x7D20;&#x503C;&#x4E3A;data&#x7684;&#x7ED3;&#x70B9;
    bool Insert(int pos, const DateType &data)
    {
        LinkNode<datetype>* p = Locate(pos);
        if (p == NULL)
        {
            return false;
        }
        LinkNode<datetype>* node = new LinkNode<datetype>(data);
        if (NULL == node)
        {
            cerr << "&#x5206;&#x914D;&#x5185;&#x5B58;&#x5931;&#x8D25;!" << endl;
            exit(-1);
        }
        node->next = p->next;
        p->next = node;
        return true;
    }
    //&#x5220;&#x9664;pos&#x4F4D;&#x7F6E;&#x7684;&#x7ED3;&#x70B9;&#xFF0C;&#x5E76;&#x4E14;&#x8FD4;&#x56DE;&#x7ED3;&#x70B9;
    bool Delete(int pos, DateType& data)
    {
        LinkNode<datetype>* p = Locate(pos-1);
        if (NULL == p || NULL == p->next)
            return false;
        LinkNode<datetype>* del = p->next;
        p->next = del->next;
        data = del->data;
        delete del;
        return true;
    }
    //&#x6E05;&#x7A7A;&#x94FE;&#x8868;
    void Clear()
    {
        //&#x6240;&#x6709;&#x7ED3;&#x70B9;&#x7684;next&#x6E05;&#x7A7A;&#xFF0C;&#x6700;&#x540E;&#x5934;&#x8282;&#x70B9;head&#x6E05;&#x7A7A;
        LinkNode<datetype>* p = NULL;
        while (head->next != NULL)
        {
            p = head->next;
            head->next = p->next;
            delete p;
        }
    }
    //&#x8F93;&#x51FA;&#x5355;&#x94FE;&#x8868;&#x6240;&#x6709;&#x7ED3;&#x70B9;&#x7684;&#x5143;&#x7D20;&#x503C;
    void PrintList()const
    {
        int count = 0;
        LinkNode<datetype>* p = head->next;
        while (p)
        {
            cout << p->data<<" "; p="p-">next;
            //&#x6253;&#x5370;&#x5341;&#x4E2A;&#x5143;&#x7D20;&#x6362;&#x884C;
            if (++count % 10 == 0)
            {
                cout << endl;
            }
        }
    }
    //&#x8FDB;&#x884C;&#x4E24;&#x7ED3;&#x70B9;&#x5143;&#x7D20;&#x503C;&#x7684;&#x4EA4;&#x6362;
    void Exchangedata(int pos1, int pos2)
    {
        LinkNode<datetype>* p1 = Locate(pos1);
        LinkNode<datetype>* p2 = Locate(pos2);
        DateType tmp = p1->data;
        p1->data = p2->data;
        p2->data = tmp;
    }
private:
    //&#x5934;&#x8282;&#x70B9;
    LinkNode<datetype>* head;
};
/*
LinkList(); //&#x6784;&#x9020;&#x51FD;&#x6570;,&#x521D;&#x59CB;&#x5316;&#x4E3A;&#x7A7A;&#x94FE;&#x8868;
LinkList(const DateType &item);//&#x6709;&#x53C2;&#x6784;&#x9020;&#xFF0C;&#x521D;&#x59CB;&#x5316;&#x5934;&#x8282;&#x70B9;,      &#x6709;&#x95EE;&#x9898;
LinkList(const LinkList<datetype>& list);//&#x62F7;&#x8D1D;&#x6784;&#x9020;,&#x62F7;&#x8D1D;&#x5355;&#x94FE;&#x8868;
CreateLink(int n);//&#x521B;&#x5EFA;&#x5355;&#x94FE;&#x8868;
~LinkList();//&#x6790;&#x6784;&#x51FD;&#x6570;,&#x5355;&#x94FE;&#x8868;&#x7684;&#x5220;&#x9664;
void PushBack(const DateType& data);//&#x5C3E;&#x63D2;
void PopBack();//&#x5C3E;&#x5220;
void PushFront(const DateType &data)&#xFF1B;//&#x5934;&#x63D2;
void PopFront();//&#x5934;&#x5220;
int Length()const;//&#x6C42;&#x5355;&#x94FE;&#x8868;&#x7684;&#x957F;&#x5EA6;
bool GetElem(int pos, DateType& data);//&#x83B7;&#x5F97;pos&#x4F4D;&#x7F6E;&#x7684;&#x5143;&#x7D20;
LinkNode<datetype>* Locate(int pos);//&#x8FD4;&#x56DE;&#x94FE;&#x8868;&#x4E2D;&#x7B2C;pos&#x4E2A;&#x5143;&#x7D20;&#x7684;&#x5730;&#x5740;&#xFF0C;&#x5982;&#x679C;pos<0或pos超出链表最大个数返回null bool insert(int pos, const datetype &data); 在序号pos位置插入元素值为data的结点 delete(int datetype& data); 删除pos位置的结点,并且返回结点 void clear(); 清空链表 printlist()const; 输出单链表所有结点的元素值 exchangedata(int pos1, int pos2); 进行两结点元素值的交换 * main() { linklist<int> list;
    list.CreateLink(5);
    list.PrintList();
    cout << "-------------------" << endl;
    list.PushBack(299);
    list.PrintList();
    cout << "-------------------" << endl;
    list.PopBack();
    list.PrintList();
    cout << "-------------------" << endl;
    list.PushFront(19);
    list.PrintList();
    cout << "-------------------" << endl;
    list.PopFront();
    cout << list.Length() << endl;
    list.PrintList();
    cout << "-------------------" << endl;
    int b = 0;
    list.GetElem(2,b);
    cout << b << endl;
    list.PrintList();
    cout << "-------------------" << endl;
    list.Insert(2, 99);
    list.PrintList();
    cout << "-------------------" << endl;
    list.Exchangedata(1, 2);
    list.PrintList();
    cout << "-------------------" << endl;
    list.Clear();
    list.PrintList();
    cout << "-------------------" << endl;
    LinkList<int> list2(list);
    list2.PrintList();
    LinkList<int> list(90);
    list.PrintList();
    system("pause");
    return EXIT_SUCCESS;
}
</int></int></0或pos超出链表最大个数返回null></datetype></datetype></datetype></datetype></datetype></"></datetype></datetype></datetype></datetype></datetype></datetype></datetype></datetype></0或pos超出链表最大个数返回null></datetype></datetype></datetype></datetype></datetype></datetype></datetype></datetype></datetype></datetype></datetype></datetype></datetype></datetype></datetype></datetype></datetype></datetype></datetype></datetype></datetype></datetype></datetype></datetype></datetype></class></datetype></datetype></datetype></class></string></iostream>

Original: https://www.cnblogs.com/yzsn12138/p/16924424.html
Author: 一只少年AAA
Title: 数据结构初阶–单链表(讲解+类模板实现)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/797908/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球