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日

相关文章

  • Lua教程(七):数据结构详解

    Lua教程(七):数据结构详解 Lua 中的数据结构广泛应用于各种计算机程序中。本文将详细介绍 Lua 中的数组、列表、栈、队列、集合和字典等数据结构的使用以及相关的函数。 数组 数组是存储在连续内存位置上的相同数据类型的元素集合。Lua 中的数组索引默认从 1 开始。下面是一些常用的 Lua 数组函数: table.concat(arr[, sep[, i…

    数据结构 2023年5月17日
    00
  • 柏林噪声算法(Perlin Noise)

    概述 引述维基百科的介绍: Perlin噪声(Perlin noise,又称为柏林噪声)指由Ken Perlin发明的自然噪声生成算法,具有在函数上的连续性,并可在多次调用时给出一致的数值。 在电子游戏领域中可以透过使用Perlin噪声生成具连续性的地形;或是在艺术领域中使用Perlin噪声生成图样。 维基百科的介绍相当的官方,其实可以理解为一个随机函数,不…

    算法与数据结构 2023年4月17日
    00
  • C语言数据结构时间复杂度及空间复杂度简要分析

    C语言数据结构时间复杂度及空间复杂度简要分析 什么是时间复杂度和空间复杂度? 在分析算法和数据结构的性能时,时间复杂度和空间复杂度是必须考虑的因素。 时间复杂度:衡量算法执行时间所需的资源,也就是算法的速度。通常使用“大O符号”来表示时间复杂度,例如O(1)、O(n)、O(nlogn)等。 空间复杂度:衡量算法使用的内存资源,也就是算法的空间利用率。通常使用…

    数据结构 2023年5月17日
    00
  • 常用的Java数据结构知识点汇总

    常用的Java数据结构知识点汇总 简介 Java中的数据结构是Java程序开发中非常重要的一部分。掌握常用的数据结构知识点是编写高效、优秀的Java程序的关键之一。本文将详细讲解Java中常用的数据结构知识点,并提供代码示例说明。 数组(Array) 数组是一组相同类型的数据集合,通过数组下标来访问数据,数组长度确定后就无法改变。在Java中,数组可以是基本…

    数据结构 2023年5月17日
    00
  • C语言数据结构算法基础之循环队列示例

    标题:C语言数据结构算法基础之循环队列示例 1. 简介 循环队列是一种常见的数据结构,它采用固定大小的数组来模拟队列的数据结构,可以高效地处理队列的进出操作。本文将会讲解循环队列的实现原理和示例代码。 2. 循环队列基本原理 循环队列通过两个指针front和rear来实现队列的添加和删除操作。在初始化时,front和rear的初始值都为0。每当数据进入队列时…

    数据结构 2023年5月17日
    00
  • 8个简单部分开启Java语言学习之路 附java学习书单

    8个简单部分开启Java语言学习之路 如果你想要学习Java语言,但是不知道从何入手,在这里,我们将为你提供一份简单易懂的攻略,分8个步骤带你开启Java语言学习之路。 1. 安装Java开发工具 Java学习的第一步是安装Java开发工具,目前比较流行的Java开发工具有多种,例如Eclipse、Intellij IDEA、NetBeans等。本攻略以In…

    数据结构 2023年5月17日
    00
  • Java数据结构之双向链表的实现

    Java数据结构之双向链表的实现 一、双向链表的定义 双向链表是一种包含两个指针的链表数据结构,每个节点都有两个指针,一个指向前一个节点,一个指向后一个节点。 二、双向链表的实现 1. 定义节点 首先,我们需要定义一个节点类,包含节点的值,指向前一个节点的指针pre和指向后一个节点的指针next,代码如下: public class Node { int v…

    数据结构 2023年5月17日
    00
  • Python数据结构之二叉排序树的定义、查找、插入、构造、删除

    Python数据结构之二叉排序树 一、定义 二叉排序树(Binary Search Tree,BST),也称为二叉查找树或二叉搜索树,是一种基于二叉树的数据结构,其中每个节点都包含一个键值,且满足: 左子树中所有节点的键值均小于当前节点; 右子树中所有节点的键值均大于当前节点; 这是一种自平衡的数据结构,可以快速地进行查找、插入、删除等操作。 二、查找 查找…

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