C++数据结构之链表详解

C++数据结构之链表详解

链表是一种重要的数据结构,它可以动态的分配内存空间,实现灵活的元素插入,删除等操作。本文将详细讲解链表的定义、实现、常见操作以及链表的应用。

定义与特点

链表是一种线性表数据结构,由一系列节点组成,每个节点包含数据和指向下一个节点的指针。链表分为单向链表和双向链表,其中单向链表的每个节点只包含一个指针,指向下一个节点,而双向链表的每个节点包含两个指针,分别指向前一个节点和后一个节点。

链表的特点:
- 空间动态分配。
- 灵活的插入和删除操作。
- 随机访问效率较低,但插入和删除操作的效率很高。

实现

链表的实现需要定义一个节点结构体,包含数据和指针部分。下面是单向链表实现的代码:

struct ListNode {
    int val;        //数据部分
    ListNode* next; //指针部分
    ListNode(int x) : val(x), next(nullptr) {} //构造函数
};

常见操作

链表操作包括节点的插入、删除、查找等,下面介绍常用的操作:

节点的插入

链表的节点插入操作包括头部插入和尾部插入两种方式,可以通过指针操作实现。

//头部插入
ListNode* insertHead(ListNode* head, int val) {
    ListNode* new_node = new ListNode(val);
    new_node->next = head;
    return new_node;
}

//尾部插入
ListNode* insertTail(ListNode* head, int val) {
    if (!head) {
        return new ListNode(val);
    }
    ListNode* curr = head;
    while (curr->next) {
        curr = curr->next;
    }
    curr->next = new ListNode(val);
    return head;
}

节点的删除

链表的节点删除同样包括头部删除和尾部删除两种方式,需要将指针指向下一个节点或前一个节点,再释放删除的节点。

//头部删除
ListNode* deleteHead(ListNode* head) {
    if (!head) {
        return nullptr;
    }
    ListNode* temp = head->next;
    delete head;
    return temp;
}

//尾部删除
ListNode* deleteTail(ListNode* head) {
    if (!head) {
        return nullptr;
    }
    if (!head->next) {
        delete head;
        return nullptr;
    }
    ListNode* curr = head;
    while (curr->next->next) {
        curr = curr->next;
    }
    delete curr->next;
    curr->next = nullptr;
    return head;
}

节点的查找

链表的节点查找包括按值查找和按位置查找两种方式。

//按值查找
ListNode* findByValue(ListNode* head, int val) {
    ListNode* curr = head;
    while (curr && curr->val != val) {
        curr = curr->next;
    }
    return curr;
}

//按位置查找
ListNode* findByIndex(ListNode* head, int index) {
    ListNode* curr = head;
    int i = 0;
    while (curr && i != index) {
        curr = curr->next;
        i++;
    }
    return curr;
}

链表的应用

链表可用于实现栈、队列、哈希表等数据结构,同时也可以用于解决一些算法问题,如链表反转、链表合并等问题。

下面是链表合并的实现:

ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
    ListNode dummy(0);
    ListNode* curr = &dummy;
    while (l1 && l2) {
        if (l1->val < l2->val) {
            curr->next = l1;
            l1 = l1->next;
        } else {
            curr->next = l2;
            l2 = l2->next;
        }
        curr = curr->next;
    }
    curr->next = l1 ? l1 : l2;
    return dummy.next;
}

示例说明

假设现在有两个单向链表,l1表示[1,2,4],l2表示[1,3,4],需要将这两个链表合并成一个新的链表。

ListNode* l1 = new ListNode(1);
l1->next = new ListNode(2);
l1->next->next = new ListNode(4);

ListNode* l2 = new ListNode(1);
l2->next = new ListNode(3);
l2->next->next = new ListNode(4);

ListNode* l3 = mergeTwoLists(l1, l2);

最终得到的合并后的链表l3表示[1,1,2,3,4,4]。

另外一个示例是如何使用链表实现栈数据结构,下面是代码示例:

class MyStack {
public:
    /** Initialize your data structure here. */
    MyStack() {
        top_ = nullptr;
    }

    /** Push element x onto stack. */
    void push(int x) {
        ListNode* new_node = new ListNode(x);
        new_node->next = top_;
        top_ = new_node;
    }

    /** Removes the element on top of the stack and returns that element. */
    int pop() {
        if (!top_) {
            return -1;
        }
        ListNode* temp = top_;
        top_ = top_->next;
        int val = temp->val;
        delete temp;
        return val;
    }

    /** Get the top element. */
    int top() {
        return top_->val;
    }

    /** Returns whether the stack is empty. */
    bool empty() {
        return top_ == nullptr;
    }

private:
    ListNode* top_;
};

总结

链表是一种十分重要的数据结构,在算法问题中也非常常见。本文介绍了链表的定义、实现、常见操作和应用,并给出了两个示例说明链表的使用。希望本文可以帮助读者更好的掌握链表的知识。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++数据结构之链表详解 - Python技术站

(0)
上一篇 2023年5月17日
下一篇 2023年5月17日

相关文章

  • C语言实现数据结构迷宫实验

    C语言实现数据结构迷宫实验攻略 简介 迷宫是计算机图形学中的一个经典问题,也是数据结构和算法中常见的题目。C语言是一种广泛使用的编程语言,具有充分的编程接口和功能,可以方便地实现迷宫算法和数据结构。 本文将详细讲解C语言实现数据结构迷宫实验的完整攻略,让读者能够更加深入地理解迷宫算法和数据结构的应用。 实现步骤 1. 创建迷宫结构体 首先需要创建一个迷宫结构…

    数据结构 2023年5月17日
    00
  • 带你了解Java数据结构和算法之队列

    带你了解Java数据结构和算法之队列 一、介绍 队列是已知的最古老和最常用的数据结构之一。它是一个线性结构,它遵循一个先进先出的原则,在日常生活中我们也很容易碰到队列。比如:在银行排队办理业务、队列中的电影厅、厨房中的菜单等等。 队列的操作主要有两种:入队(enqueue)和出队(dequeue)。插入操作只能在队尾进行,删除操作只能在队头进行。还有一些常用…

    数据结构 2023年5月17日
    00
  • 详解python数据结构之队列Queue

    详解Python数据结构之队列 (Queue) 在计算机科学中,队列(Queue)是一种数据结构,可以用于按顺序存储和访问元素。该数据结构遵循先进先出(FIFO)原则,人们可以从队列的前面插入元素,从队列的后面删除元素。Python内置了队列模块(queue),这个模块实现了多线程安全队列、同步机制及相关数据结构。Queue模块提供了三种队列类型: FIFO…

    数据结构 2023年5月17日
    00
  • 自制PHP框架之模型与数据库

    很好,下面我将为您详细讲解如何自制PHP框架中的模型与数据库部分。 什么是模型和数据库? 在讲解自制PHP框架的模型和数据库前,我们需要先了解什么是模型和数据库。在PHP框架架构中,模型是用来操作数据库的一种机制,用来处理对数据表的增删改查等操作,并且与数据库的连接是一定的。而数据库是一种数据存储工具,用于存储数据并提供数据操作的方法,例如数据的增删改查等。…

    数据结构 2023年5月17日
    00
  • Leetcode Practice — 栈和队列

    目录 155. 最小栈 思路解析 20. 有效的括号 思路解析 1047. 删除字符串中的所有相邻重复项 思路解析 1209. 删除字符串中的所有相邻重复项 II 思路解析 删除字符串中出现次数 >= 2 次的相邻字符 剑指 Offer 09. 用两个栈实现队列 239. 滑动窗口最大值 思路解析 155. 最小栈 设计一个支持 push ,pop ,…

    算法与数据结构 2023年4月17日
    00
  • 实际问题中用到的算法——递归算法确定插帧顺序

    问题: 现在需要给一个视频序列插帧,插帧算法要求每次只能由两帧输入插值得到其中间帧。如果现在需要给一个视频做 4 倍(或者更高的 8,16 倍等类似)的插帧,则一个插帧的思路是当前视频每相邻帧之间插入 3 帧,即:假设插帧前视频帧序号是 0,4,8,12…,则插帧时补充相邻帧跨过的 3 个序号,得到插帧后的视频帧序号为 0,1,2,3,4,5,6,.. 即可…

    算法与数据结构 2023年4月18日
    00
  • C语言类的双向链表详解

    C语言类的双向链表详解 基本概念 什么是双向链表? 双向链表是链表的一种,它有两个指针域:一个指向前一个结点,一个指向后一个结点。每个结点包含两个部分:数据和指针域,指针域分别指向前一个结点和后一个结点,所以每个结点都是由数据和两个指针域构成的。 双向链表的作用? 双向链表可以支持O(1)时间复杂度的在任何一个结点前或后插入一个结点。 双向链表的实现方式? …

    数据结构 2023年5月17日
    00
  • 详解C语言实现空间索引四叉树

    详解C语言实现空间索引四叉树攻略 四叉树是一种常见的空间索引方法,可以有效地处理二维或三维空间中的数据。本攻略将详细介绍使用C语言实现空间索引四叉树的方法,包括数据结构的设计,插入和查询操作的实现。 数据结构设计 结点结构体 struct QuadtreeNode { int depth; // 结点深度 double x, y; // 结点中心坐标 dou…

    数据结构 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部