《数据结构》期末提纲之链表

1.链表简介

链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。(百度百科

2.链表的基本操作

  • 创建链表
    首先要创建链表节点结构体,链表的单个节点由两部分构成,即数据域与指针域。数据域用来存储数据,指针域存储后继的地址。(本博文仅讨论单向链表)
    创建链表时,需要声明一个头节点。一般情况下,头节点不含数据,并且指向存储第一个数据的节点。

  • 插入数据
    对链表进行数据插入操作时,需要分配一个新的存储空间存储新的节点,并且使插入位置的前驱指向新节点,新节点指针域指向后继。如图所示:
    链表的插入操作

  • 删除数据
    对链表中的数据进行删除时,只需要其前驱直接指向后继,打断被删除节点与后继的连接,并释放该节点即可,如图所示:
    链表的删除操作

  • 遍历
    遍历链表的重要依据就是其指针域指向其后继,只需访问每个节点指针域指向节点即可完成遍历。

3.链表的C++实现

  • 构造链表类以及节点结构体
template<class DataType>
struct node //节点
{
    DataType data; //数据域
    node<DataType> *next; //指针域
};

template<class DataType>
class LinkList //链表类
{
public:
    LinkList(); //无参数构造
    LinkList(DataType a[], int n); //按数组构造
    ~LinkList(); //析构
    int length(); //返回长度
    DataType get(int i); //按位查值
    int locate(DataType x); //按值查位
    void insert(int i, DataType x); //插值
    void del_loc(int i); //按位删值
    void del_data(DataType x); //按值删值
    void clear(); //清空
private:
    node<DataType> *head; //头节点
};
  • 构造方法
template<class DataType>
LinkList<DataType>::LinkList()
{
    head = new node<DataType>; //为头节点分配内存空间完成构造
    head->next = NULL;
    cout << "LinkList Constructed" << endl;
}

template<class DataType>
LinkList<DataType>::LinkList(DataType a[], int n)
{
    head = new node<DataType>;
    head->next = NULL;
    for (int i = n - 1;i >= 0;i--) //依次头插
    {
        node<DataType> *s = new node<DataType>;
        s->data = a[i];
        s->next = head->next;
        head->next = s;
    }
    cout << "LinkList Constructed" << endl;
}
  • 析构方法
template<class DataType>
LinkList<DataType>::~LinkList()
{
    while (head != NULL) //依次释放空间
    {
        node<DataType>* q = head;
        head = head->next;
        delete q;
    }
    cout << "LinkList Distructed!" << endl;
}
  • 返回长度
template<class DataType>
int LinkList<DataType>::length()
{
    node<DataType>* p = head->next; //通过遍历求长度
    int cnt = 0;
    while (p != NULL)
    {
        p = p->next;
        cnt++;
    }
    return cnt;
}
  • 按位查值与按值查位
template<class DataType>
DataType LinkList<DataType>::get(int i) //按位查值
{
    node<DataType>* p = head->next;
    int cnt = 1;
    while (p != NULL && cnt < i) //遍历到需要查找的位置
    {
        p = p->next;
        cnt++;
    }
    if (p == NULL)
        throw "Location Error!";
    else
        return p->data;
}

template<class DataType>
int LinkList<DataType>::locate(DataType x) //按值查位
{
    node<DataType> *p = head->next;
    int cnt = 1;
    while (p != NULL) //遍历查找需要查的值
    {
        if (p->data == x)
            return cnt;
        p = p->next;
        cnt++;
    }
    return 0;
}
  • 插入
template<class DataType>
void LinkList<DataType>::insert(int i, DataType x)
{
    node<DataType> *p = head;
    int cnt = 0;
    while (p != NULL && cnt < i - 1)
    {
        p = p->next;
        cnt++; //遍历到要插入的位置
    }
    if (p == NULL)
        throw "Location Error!";
    else
    {
        node<DataType> *s = new node<DataType>;
        s->data = x;
        s->next = p->next; //这是关键语句,时新节点指向后继
        p->next = s; //使前驱指向新节点
    }
}
  • 按位删值与按值删值
template<class DataType>
void LinkList<DataType>::del_loc(int i) //按位删值
{
    node<DataType> *p = head;
    int cnt = 0;
    while (p != NULL && cnt < i - 1) //遍历到需要删除的节点
    {
        p = p->next;
        cnt++;
    }
    if (p == NULL || p->next == NULL)
        throw "Location Error!";
    else
    {
        node<DataType> *q = p->next;
        // int x = q->data;
        p->next = q->next; //使该节点前驱直接指向后继
        delete q; //释放空间
    }
}

template<class DataType>
void LinkList<DataType>::del_data(DataType x)
{
    node<DataType> *q = head->next;
    int index = 1;
    while(q != NULL) //相似的方法,遍历删除每一个符合条件的节点
    {
        if(q->data == x)
        {
            q = q->next;
            node<DataType> *p = head;
            for(int i = 1;i < index;i++)
            {
                p = p->next;
            }
            node<DataType> *r = p->next;
            p->next = r->next;
            delete r;
        }
        else
        {
            index++;
            q=q->next;
        }
    }
}
  • 清空链表
template<class DataType>
void LinkList<DataType>::clear()
{
    while (head != NULL) //依次释放空间
    {
        node<DataType>* q = head->next;
        head = head->next;
        delete q;
    }
    cout << "LinkList cleared!" << endl;
}
  • 调试函数
void LinkList_debug()
{
    LinkList<int> a;
    int sw;
    cout << "LinkList Options:\n1.Insert data\n2.Delete data by location\n3.Delete data by value\n4.Find data by location\n5.Find location by data\n6.Get the length\n7.Clear the list\n8.Print the list\n9.Exit\n";
    while (cin >> sw)
    {
        if (sw == 1)
        {
            int loc,da;
            cout << "Please input the location and data: ";
            cin >> loc >> da;
            a.insert(loc,da);
        }
        else if (sw == 2)
        {
            int loc;
            cout << "Please input the location: ";
            cin >> loc;
            a.del_loc(loc);
        }
        else if (sw == 3)
        {
            int x;
            cout << "Please input the data: ";
            cin >> x;
            a.del_data(x);
        }
        else if (sw == 4)
        {
            int loc,x;
            cout << "Please input the location: ";
            cin >> loc;
            x = a.get(loc);
            cout << x << endl;
        }
        else if (sw == 5)
        {
            int loc,x;
            cout << "Please input the data: ";
            cin >> x;
            loc = a.locate(x);
            cout << loc << endl;
        }
        else if (sw == 6)
        {
            cout << a.length() << endl;
        }
        else if (sw == 7)
        {
            a.clear();
        }
        else if (sw == 8)
        {
            for(int i = 1;i <= a.length();++i)
                cout << a.get(i) << " ";
            cout << endl;
        }
        else
        {
            break;
        }
        cout << "LinkList Options:\n1.Insert data\n2.Delete data by location\n3.Delete data by value\n4.Find data by location\n5.Find location by data\n6.Get the length\n7.Clear the list\n8.Print the list\n9.Exit\n";
    }
}

4.小结

相比于线性表顺序结构,操作复杂。由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比另一种线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而线性表和顺序表相应的时间复杂度分别是O(logn)和O(1)。

总提纲:《数据结构》期末提纲小结

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值