首页 > 其他分享 >数据结构链表入门指南 链表基本代码实现以及测试步骤

数据结构链表入门指南 链表基本代码实现以及测试步骤

时间:2024-08-22 13:52:17浏览次数:4  
标签:Node head temp 测试步骤 next 链表 数据结构 节点

链表介绍

链表是一种数据结构,它由一系列节点组成,每个节点包含数据部分和指向下一个节点的指针。链表的基本特性包括:

  1. 动态大小:链表的大小可以根据需要动态调整,不像数组那样需要事先定义固定大小。
  2. 节点连接:每个节点通过指针连接到下一个节点,从而形成一个链状结构。
  3. 灵活插入和删除:在链表中插入和删除节点通常比数组更高效,因为这些操作不需要移动其他元素。

链表的类型

  1. 单向链表(Singly Linked List):每个节点包含一个指针,指向链表中的下一个节点。最后一个节点的指针指向 null,表示链表的结束。

  2. 双向链表(Doubly Linked List):每个节点包含两个指针,一个指向前一个节点,一个指向下一个节点。这样可以在两个方向上遍历链表。

  3. 循环链表(Circular Linked List):链表的最后一个节点指向第一个节点,形成一个循环结构。它可以是单向或双向的。

  4. 双向循环链表(Doubly Circular Linked List):结合了双向链表和循环链表的特性,既可以在两个方向上遍历,又形成了一个循环结构。

链表的基本操作
  1. 插入:在链表的任意位置插入新节点。
  2. 删除:从链表中删除指定节点。
  3. 查找:在链表中查找指定值的节点。
  4. 遍历:访问链表中所有节点,通常用来打印或处理数据。
  5. 更新:修改链表中某个节点的数据。
C++ 实现链表

下面是一个包含基本操作的链表实现代码:

#include <iostream>

class Node {
public:
    int data;
    Node* next;
    Node(int val) : data(val), next(nullptr) {}
};

class LinkedList {
private:
    Node* head;
public:
    LinkedList() : head(nullptr) {}

    // 插入节点到链表头部
    void insertAtHead(int val) {
        Node* newNode = new Node(val);
        newNode->next = head;
        head = newNode;
    }

    // 插入节点到链表尾部
    void insertAtTail(int val) {
        Node* newNode = new Node(val);
        if (!head) {
            head = newNode;
            return;
        }
        Node* temp = head;
        while (temp->next) {
            temp = temp->next;
        }
        temp->next = newNode;
    }

    // 删除指定值的节点
    void deleteValue(int val) {
        if (!head) return;
        if (head->data == val) {
            Node* temp = head;
            head = head->next;
            delete temp;
            return;
        }
        Node* temp = head;
        while (temp->next && temp->next->data != val) {
            temp = temp->next;
        }
        if (temp->next) {
            Node* nodeToDelete = temp->next;
            temp->next = temp->next->next;
            delete nodeToDelete;
        }
    }

    // 查找指定值的节点
    bool search(int val) {
        Node* temp = head;
        while (temp) {
            if (temp->data == val) return true;
            temp = temp->next;
        }
        return false;
    }

    // 遍历链表并打印数据
    void traverse() {
        Node* temp = head;
        while (temp) {
            std::cout << temp->data << " -> ";
            temp = temp->next;
        }
        std::cout << "nullptr" << std::endl;
    }

    ~LinkedList() {
        while (head) {
            Node* temp = head;
            head = head->next;
            delete temp;
        }
    }
};

int main() {
    LinkedList list;

    // 插入数据
    list.insertAtHead(1);
    list.insertAtHead(2);
    list.insertAtTail(3);
    list.insertAtTail(4);

    // 遍历链表
    std::cout << "Linked List: ";
    list.traverse();

    // 查找数据
    std::cout << "Searching for 3: " << (list.search(3) ? "Found" : "Not Found") << std::endl;

    // 删除数据
    list.deleteValue(2);
    std::cout << "After deleting 2, Linked List: ";
    list.traverse();

    return 0;
}

代码说明

  1. Node 类:定义了链表节点的结构。
  2. LinkedList 类
    • insertAtHead(int val):在链表头部插入新节点。
    • insertAtTail(int val):在链表尾部插入新节点。
    • deleteValue(int val):删除链表中第一个匹配值的节点。
    • search(int val):查找链表中是否存在指定值的节点。
    • traverse():遍历并打印链表所有节点的数据。
    • 析构函数~LinkedList():释放链表占用的内存。

编译代码

使用 C++ 编译器(如 g++)编译这个文件。打开终端或命令提示符,执行以下命令:

g++ -o linked_list linked_list.cpp -o linked_list

指定输出文件的名称为 linked_list。
linked_list.cpp 是你保存的代码文件名。

代码输出结果

Linked List: 2 -> 1 -> 3 -> 4 -> nullptr
Searching for 3: Found
After deleting 2, Linked List: 1 -> 3 -> 4 -> nullptr

链表与其他数据结构的优缺点

优点
  1. 动态大小:链表可以动态分配内存,避免了固定大小数组的限制。
  2. 高效插入和删除:在链表中插入和删除节点比数组高效(O(1)时间复杂度),特别是在头部或中间位置。
  3. 无需预定义大小:链表不需要定义固定的大小,可以根据需要扩展。
缺点
  1. 内存开销:每个节点需要额外的指针,导致比数组占用更多的内存。
  2. 随机访问困难:链表不支持直接索引,必须从头部开始逐一遍历(O(n)时间复杂度)。
  3. 访问速度慢:由于节点分散在内存中,链表的遍历比数组慢。

总结

链表是一种灵活且高效的动态数据结构,适用于需要频繁插入和删除操作的应用场景。尽管它的内存开销和访问速度可能不如数组,但它的动态特性和高效的插入/删除操作使其在某些情况下非常有用。了解链表的基本操作和特性,可以帮助在不同的应用场景中选择合适的数据结构。

标签:Node,head,temp,测试步骤,next,链表,数据结构,节点
From: https://blog.csdn.net/weixin_44251074/article/details/141426214

相关文章

  • java创建链表异常解决
    问题解决问题解释该错误表明,在试图创建非静态类实例时,没有正确引用外部类的实例。源代码如下packagevjudge;importjava.util.Scanner;publicclasstest{//节点类publicclassNode{intdata;Nodenext;Node(intdata){......
  • 单链表入门
    1.概念与结构概念:链表是⼀种物理存储结构上⾮连续、⾮顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。2.结点与顺序表不同的是,链表⾥的每一个都是独⽴申请下来的空间,我们称之为“结点/结点”结点的组成主要有两个部分:当前结点要保存的数据......
  • 数据结构初阶(2)——链表OJ
    目录1.面试题02.02.返回倒数第k个节点2.OR36链表的回文结构3.160.相交链表1.面试题02.02.返回倒数第k个节点思路:快慢指针,快指针先走k格,慢指针同步/***Definitionforsingly-linkedlist.*structListNode{*intval;*structListNode......
  • 数据结构day03(栈 Stack 顺序栈、链式栈 )内含具体详细代码实现
    目录【1】栈 Stack1》栈的定义 2》顺序栈 2》链式栈 4》顺序栈的链式栈的区别【1】栈 Stack1》栈的定义栈:是只允许在一端进行插入或删除的线性表,首先栈是一种线性表,但限定这种线性表只能在某一端进行插入和删除操作。栈顶:线性表允许进行插入删除的一端......
  • 数据结构之跳表SkipList、ConcurrentSkipListMap
    概述SkipList,跳表,跳跃表,在LevelDB和Lucene中都广为使用。跳表被广泛地运用到各种缓存实现当中,跳跃表使用概率均衡技术而不是使用强制性均衡,因此对于插入和删除结点比传统上的平衡树算法更为简洁高效。Skiplistsaredatastructuresthatuseprobabilisticbalancingrather......
  • 面试+算法之回文(Java):验证回文串、回文数、最长回文子串、回文链表、分割成回文串、
    概述算法是一个程序员的核心竞争力,也是面试最重要的考查环节。本文整理一些与回文相关的基础算法题。注:本文语言为Java。验证回文串如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个回文串。给定一个字符......
  • 基础数据结构——二分算法及时间复杂度
    这个算法的前提是,数组是升序排列的算法描述:i和j是指针可以表示查找范围m为中间值当目标值targat比m大时,设置查找范围在m右边:i=m-1当目标值targat比m小时,设置查找范围在m左边:j=m+1当targat的值等于m时,返回m的下标如果最终没找到就返回-1;算法实现:publicintbir......
  • 知识改变命运 数据结构【栈和队列】
    1.栈(Stack)1.1概念栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(LastInFirstOut)的原则。压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。出栈:栈的删......
  • 可持久化数据结构1
    非持久化数据结构一般需要维护数据集最新状态,而可持久化要求查询历史状态。可持久化Trie树朴素:每次修改重新存一遍\(->MLE\)。正解:只存被修改部分,其余不变,即第\(i\)次修改后,树变为第\(i\)次修改产生新的部分加上前\(i-1\)次修改产生部分。增长同规模。用普通线段树维......
  • 【数据结构】栈和队列的实现
    正文1.栈1.1概念与结构栈:⼀种特殊的线性表,其只允许在固定的⼀端进⾏插⼊和删除元素操作。进⾏数据插⼊和删除操作的⼀端称为栈顶,另⼀端称为栈底。栈中的数据元素遵守后进先出LIFO(LastInFirstOut)的原则。压栈:栈的插⼊操作叫做进栈/压栈/⼊栈,⼊数据在栈顶......