数据结构 链表

Posted 上山打老虎D

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构 链表相关的知识,希望对你有一定的参考价值。

1. DS单链表–类实现

题目描述

用C++语言和类实现单链表,含头结点

属性包括:data数据域、next指针域

操作包括:插入、删除、查找

注意:单链表不是数组,所以位置从1开始对应首结点,头结点不放数据

输入

n

第1行先输入n表示有n个数据,接着输入n个数据

第2行输入要插入的位置和新数据

第3行输入要插入的位置和新数据

第4行输入要删除的位置

第5行输入要删除的位置

第6行输入要查找的位置

第7行输入要查找的位置

输出

n

数据之间用空格隔开,

第1行输出创建后的单链表的数据

每成功执行一次操作(插入或删除),输出执行后的单链表数据

每成功执行一次查找,输出查找到的数据

如果执行操作失败(包括插入、删除、查找等失败),输出字符串error,不必输出单链表

输入样例

6 11 22 33 44 55 66
3 777
1 888
1
11
0
5

输出样例

11 22 33 44 55 66
11 22 777 33 44 55 66
888 11 22 777 33 44 55 66
11 22 777 33 44 55 66
error
error
44

参考代码

#include <bits/stdc++.h>

using namespace std;


#define ok 0
#define error -1

//链表结点类定义
class ListNode {
public:
    int data;
    ListNode *next;

    ListNode() {
        next = NULL;
    }
};

//带头结点的单链表类定义
class LinkList {
public:
    ListNode *head;
    int len;

    //操作定义
    LinkList() {
        head = new ListNode();
        len = 0;
    }

    //链表回收,要逐个结点回收
    ~LinkList() {
        ListNode *p, *q;
        p = head;
        while (p != NULL) {
            q = p;
            p = p->next;
            delete q;
        }
        len = 0;
        head = NULL;
    }

    //返回第i个结点的指针,如果不存在返回NULL
    ListNode *LL_index(int i) {
        if (i < 0 || i > len)
            return NULL;

        int k = 0;
        ListNode *p = head;
        while (p && k < i) {
            p = p->next;
            k++;
        }
        return p;
    }

    //获取第i个元素的数据
    int LL_get(int i) {
        ListNode *p = LL_index(i);
        return p->data;
    }

    //把数值item插入第i个位置
    int LL_insert(int i, int item) {
        if (i <= 0 || i > len + 1)
            return error;


        ListNode *p = LL_index(i - 1);

        ListNode *newNode = new ListNode();

        newNode->data = item;
        newNode->next = p->next;
        p->next = newNode;

        len++;


        return ok;
    }

    //删除第i个结点
    int LL_del(int i) {
        if (i <= 0 || i > len)
            return error;

        ListNode *p = LL_index(i - 1);
        ListNode *q = p->next;
        p->next = q->next;
        delete q;

        return ok;

    }

    //输出单链表的内容
    void LL_display() {
        ListNode *p;
        p = head->next;
        while (p) {
            cout << p->data << " ";
            p = p->next;
        }
        cout << endl;
    }

    //结点交换
    int swap(int pa, int pb) {
        ListNode *pa_point = LL_index(pa);
        ListNode *pb_point = LL_index(pb);
        if (!pa_point || !pb_point)
            return error;

        ListNode *front_pa = LL_index(pa - 1);

        ListNode *front_pb = LL_index(pb - 1);

        ListNode *temp = pa_point->next;
        pa_point->next = pb_point->next;
        pb_point->next = temp;

        front_pa->next = pb_point;
        front_pb->next = pa_point;

        return ok;
    }

    //两个单链表的合并
    int LL_merge(ListNode *La, ListNode *Lb) {
        ListNode *p = head;

        while (La && Lb) {
            if (La->data < Lb->data) {
                ListNode *temp = new ListNode();
                temp->data = La->data;
                temp->next = La->next;
                p->next = temp;
                p = p->next;
                La = La->next;
                len++;
            } else {
                ListNode *temp = new ListNode();
                temp->data = Lb->data;
                temp->next = Lb->next;
                p->next = temp;
                p = p->next;
                Lb = Lb->next;
                len++;
            }
        }
        while (La) {
            ListNode *temp = new ListNode();
            temp->data = La->data;
            temp->next = La->next;
            p->next = temp;
            p = p->next;
            La = La->next;
            len++;
        }
        while (Lb) {
            ListNode *temp = new ListNode();
            temp->data = Lb->data;
            temp->next = Lb->next;
            p->next = temp;
            p = p->next;
            Lb = Lb->next;
            len++;
        }

        return 1;
    }
};

int main() {
    int n;
    cin >> n;
    LinkList ex;
    //输入数据
    for (int i = 0; i < n; i++) {
        int data;
        cin >> data;
        ex.LL_insert(i + 1, data);
    }
    ex.LL_display();
    int index, data;

    //插入
    cin >> index >> data;
    if (ex.LL_insert(index, data) == 0)
        ex.LL_display();
    else
        cout << "error" << endl;

    cin >> index >> data;
    if (ex.LL_insert(index, data) == 0)
        ex.LL_display();
    else
        cout << "error" << endl;

    //删除
    cin >> index;
    if (ex.LL_del(index) == 0)
        ex.LL_display();
    else
        cout << "error" << endl;

    cin >> index;
    if (ex.LL_del(index) == 0)
        ex.LL_display();
    else
        cout << "error" << endl;

    //查找
    cin >> index;
    if (ex.LL_index(index) && ex.LL_index(index) != ex.head)
        cout << ex.LL_get(index) << endl;
    else
        cout << "error" << endl;

    cin >> index;
    if (ex.LL_index(index) && ex.LL_index(index) != ex.head)
        cout << ex.LL_get(index) << endl;
    else
        cout << "error" << endl;
}

2. DS单链表–结点交换

题目描述

用C++实现含头结点的单链表,然后实现单链表的两个结点交换位置。

注意不能简单交换两个结点包含数据,必须通过修改指针来实现两个结点的位置交换

交换函数定义可以参考:

swap(int pa, int pb) //pa和pb表示两个结点在单链表的位置序号

swap (ListNode * p, ListNode * q) //p和q表示指向两个结点的指针

输入

第1行先输入n表示有n个数据,接着输入n个数据

第2行输入要交换的两个结点位置

第3行输入要交换的两个结点位置

输出

第一行输出单链表创建后的所有数据,数据之间用空格隔开

第二行输出执行第1次交换操作后的单链表数据,数据之间用空格隔开

第三行输出执行第2次交换操作后的单链表数据,数据之间用空格隔开

如果发现输入位置不合法,输出字符串error,不必输出单链表

输入样例

5 11 22 33 44 55
1 4
2 6

输出样例

11 22 33 44 55
44 22 33 11 55
error

参考代码

#include <bits/stdc++.h>

using namespace std;


#define ok 0
#define error -1

//链表结点类定义
class ListNode {
public:
    int data;
    ListNode *next;

    ListNode() {
        next = NULL;
    }
};

//带头结点的单链表类定义
class LinkList {
public:
    ListNode *head;
    int len;

    //操作定义
    LinkList() {
        head = new ListNode();
        len = 0;
    }

    //链表回收,要逐个结点回收
    ~LinkList() {
        ListNode *p, *q;
        p = head;
        while (p != NULL) {
            q = p;
            p = p->next;
            delete q;
        }
        len = 0;
        head = NULL;
    }

    //返回第i个结点的指针,如果不存在返回NULL
    ListNode *LL_index(int i) {
        if (i < 0 || i > len)
            return NULL;

        int k = 0;
        ListNode *p = head;
        while (p && k < i) {
            p = p->next;
            k++;
        }
        return p;
    }

    //获取第i个元素的数据
    int LL_get(int i) {
        ListNode *p = LL_index(i);
        return p->data;
    }

    //把数值item插入第i个位置
    int LL_insert(int i, int item) {
        if (i <= 0 || i > len + 1)
            return error;


        ListNode *p = LL_index(i - 1);

        ListNode *newNode = new ListNode();

        newNode->data = item;
        newNode->next = p->next;
        p->next = newNode;

        len++;


        return ok;
    }

    //删除第i个结点
    int LL_del(int i) {
        if (i <= 0 || i > len)
            return error;

        ListNode *p = LL_index(i - 1);
        ListNode *q = p->next;
        p->next = q->next;
        delete q;

        return ok;

    }

    //输出单链表的内容
    void LL_display() {
        ListNode *p;
        p = head->next;
        while (p) {
            cout << p->data << " ";
            p = p->next;
        }
        cout << endl;
    }

    //结点交换
    int swap(int pa, int pb) {
        ListNode *pa_point = LL_index(pa);
        ListNode *pb_point = LL_index(pb);
        if (!pa_point || !pb_point)
            return error;

        ListNode *front_pa = LL_index(pa - 1);

        ListNode *front_pb = LL_index(pb - 1);

        ListNode *temp = pa_point->next;
        pa_point->next = pb_point->next;
        pb_point->next = temp;

        front_pa->next = pb_point;
        front_pb->next = pa_point;

        return ok;
    }

    //两个单链表的合并
    int LL_merge(ListNode *La, ListNode *Lb) {
        ListNode *p = head;

        while (La && Lb) {
            if (La->data < Lb->data) {
                ListNode *temp = new ListNode();
                temp->data = La->data;
                temp->next = La->next;
                p->next = temp;
                p = p->next;
                La = La->next;
                len++;
            } else {
                ListNode *temp = new ListNode();
                temp->data = Lb->data;
                temp->next = Lb->next;
                p->next = temp;
                p = p->next;
                Lb = Lb->next;
                len++;
            }
        }
        while (La) {
            ListNode *temp = new ListNode();
            temp->data = La->data;
            temp->next = La->next;
            p->next = temp;
            p = p->next;
            La = La->next;
            len++;
        }
        while (Lb) {
            ListNode *temp = new ListNode();
            temp->data = Lb->data;
            temp->next = Lb->next;
            p->next = temp;
            p = p->next;
            Lb = Lb->next;
            len++;
        }

        return 1;
    }
};

int main() {
    int n;
    cin >> n;
    LinkList ex;
    //输入数据
    for (int i = 0; i < n; i++) {
        int data;
        cin >> data;
        ex.LL_insert(i + 1, data);
    }
    ex.LL_display();

    int index1, index2;
    cin >> index1 >> index2;
    if (ex.swap(index1, index2) == 0)
        ex.LL_display();
    else
        cout << "error" << endl;

    cin >> index1 >> index2;
    if (ex.swap(index1, index2) == 0)
        ex.LL_display();
    else
        cout << "error" << endl;
}

3. DS单链表–合并

题目描述

假定两个单链表是递增有序,定义并实现以下函数,完成两个单链表的合并,继续保持递增有序

int LL_merge(ListNode *La, ListNode *Lb)

输入

第1行先输入n表示有n个数据,接着输入n个数据

第2行先输入m表示有M个数据,接着输入m个数据

输出

输出合并后的单链表数据,数据之间用空格隔开

输入样例

3 11 33 55
4 22 44 66 88

输出样例

11 22 33 44 55 66 88

参考代码

#include <bits/stdc++.h>

using namespace std;

#define ok 0
#define error -1

//链表结点类定义
class ListNode {
public:
    int data;
    ListNode *next;

    ListNode() {
        next = NULL;
    }
};

//带头结点的单链表类定义
class LinkList {
public:
    ListNode *head;
    int len;

    //操作定义以上是关于数据结构 链表的主要内容,如果未能解决你的问题,请参考以下文章

NC41 最长无重复子数组/NC133链表的奇偶重排/NC116把数字翻译成字符串/NC135 股票交易的最大收益/NC126换钱的最少货币数/NC45实现二叉树先序,中序和后序遍历(递归)(代码片段

JDK常用数据结构

817. Linked List Components - LeetCode

VSCode自定义代码片段5——HTML元素结构

VSCode自定义代码片段5——HTML元素结构

VSCode自定义代码片段5——HTML元素结构