C++实现单链表(1)

1、什么是单链表?

  逻辑结构上一个挨一个的数据,在实际存储时,数据随机分布在内存中的各个位置,这种存储结构称为线型表的链式存储。

  由于分散存储,为了能够体现出数据元素之间的逻辑关系,每个数据元素在存储的同时,要配备一个指针,用于指向它的直接后继元素,即每一个数据元素都指向下一个数据元素(最后一个指向NULL(空))。

  链表中每个元素都被称为结点,结点由数据域以及指针域构成,如下图:

  

2、结点的C++实现

  由于结点中的数据域与指针域类型不一致,我们可以使用结构体作为结点的类型,同时数据域中的数据类型也是不确定的,可以使用模板技术。

#pragma once

//Node.h文件
template<typename Datatype>
struct Node
{
    Datatype Data;      //结点数据域
    Node<Datatype>* next;  //结点指针域

};

3、头指针及头结点

  有时,在链表的第一个结点之前会额外增设一个结点,结点的数据域一般不存放数据(有些情况下也可以存放链表的长度等信息),此结点被称为头结点。

  指向头结点的指针称为头指针。

4、创建LinkList类,成员函数定义和声明统一放在LinkList.hpp文件中

template<typename Datatype>
class LinkList
{
public:
    LinkList();
    ~LinkList();
    LinkList(Datatype Array[], int Array_length);
    const Datatype& Get(int Location)const;
    int Length();
    bool IsEmpty();
    void Insert(const Datatype& insert_data, int insert_location);
    void Delete(int delet_location);
    void Reverse();
    void Empty();
    void PrintList();
private:
    Node<Datatype>* first;    //头指针
};

5、默认构造

  对于链表的默认构造,主要就是使用new为头结点分配堆内存空间,并将头指针指向头结点,并初始化头结点指针域。

template<typename Datatype>
inline LinkList<Datatype>::LinkList()
{
    this->first = new Node<Datatype>;
  this->first->next = nullptr;
}

6、带参构造

  支持传递一个数组,并将数组中的元素按对应的顺序组成一个链表。这里必须传递数组的大小,具体原因在数组指针,指针数组这里已经分析过了。

//头插法
template<typename Datatype>
inline LinkList<Datatype>::LinkList(Datatype Array[], int Array_length)
{
   //初始化头结点
    this->first = new Node<Datatype>;
    this->first->next = nullptr;
  //从后往前遍历依次插入在头结点之后,保证数组顺序与链表顺一致
  for (int i = Array_length - 1; i >= 0; i--)   
  {
     //初始化待插入结点
        Node<Datatype>* s = new Node<Datatype>;
        s->Data = Array[i];
        s->next = this->first->next;
     //头结点指针域指插入结点
        this->first->next = s;
    }
}

7、获取链表指定位置的元素

template<typename Datatype>
inline const Datatype& LinkList<Datatype>::Get(int Location) const
{
    int count = 1;

    //p初始化为头结点的指针域
    Node<Datatype>* p = this->first->next;

    while (nullptr != p && count < Location)
    {
        count++;
        p = p->next;
    }
    /**
     * 结束循环的条件:
     * 1、p指向查找的元素
     * 2、p为尾结点的指针域,指向nullptr
     */
    if (nullptr == p)    throw "数据不存在";
    return p->Data;
}

8、计算链表长度

template<typename Datatype>
inline int LinkList<Datatype>::Length()
{
    int count = 0;
    Node<Datatype>* p = this->first->next;
    while (nullptr != p)
    {
        count++;
        p = p->next;
    }
    return count;
}

9、判断链表是否为空

template<typename Datatype>
inline bool LinkList<Datatype>::IsEmpty()
{
    if (nullptr == this->first->next)    return true;
    return false;
}

10、链表遍历

template<typename Datatype>
inline void LinkList<Datatype>::PrintList()
{
    Node<Datatype>* p = this->first->next;
    while (nullptr != p)
    {
        cout << p->Data;
        p = p->next;
    }
    cout << endl;
}

11、清空链表,记得同时释放堆内存

template<typename Datatype>
inline void LinkList<Datatype>::Empty()
{
    Node<Datatype>* p =  this->first->next, * s = nullptr;

    while (nullptr != p)
    {
        s = p->next;
        delete p;
        p = s;
    }
  //头结点指针域指向nullptr
  this->first->next = nullptr;
}

12、析构函数中同样记得需要释放堆内存

template<typename Datatype>
inline LinkList<Datatype>::~LinkList()
{
    this->Empty();
    delete this->first;
}

 13、测试代码

#include <iostream>
#include <string>
#include "LinkList.hpp"

using namespace std;

int main()
{
    string string_array[] = { "This ", "is ", "string_list ", "test." };
    //使用带参构造数据域为string类型的链表
    LinkList<string>* list_string_p = new LinkList<string>
        (string_array, sizeof(string_array) / sizeof(string_array[0]));

    try 
    {
        list_string_p->PrintList();
        cout << "string链表第4个元素:" << list_string_p->Get(4) << endl;

        list_string_p->Empty();
        cout << list_string_p->Length() << endl;
    }
    catch (const char* catch_string)
    {
        cout << catch_string << endl;
    }

    delete list_string_p;
    system("pause");
    return 0;
}

执行结果

 

 

新人才疏学浅,有错的地方敬请指正!!

本文来自博客园,作者:夏末终年,转载请注明出处:https://www.cnblogs.com/xiamozhongnian/p/15857385.html

 

 

 

 

posted @ 2022-02-13 21:04  夏末终年  阅读(133)  评论(0编辑  收藏  举报