链表的基本操作

(一)实验类型:设计性

(二)实验目的:

  1. 掌握线性表的链式存贮结构及基本操作,深入了解链表的基本特性,以便在实际问题背景下灵活运用它们。

  2. 巩固该存贮结构的构造方法,深入理解和灵活掌握链表的插入、删除等操作。

(三)实验内容:

  1. 建立线性表的链式存储结构。

  2. 完成链表操作:建立,初始化,增加,插入,删除。

cpp 复制代码
#include <iostream>

// 链表节点结构
struct ListNode {
    int val;                // 节点存储的值
    ListNode* next;         // 指向下一个节点的指针
};

// 初始化链表
void initList(ListNode*& head) {
    head = nullptr;
}

// 在链表尾部添加节点
void appendNode(ListNode*& head, int value) {
    ListNode* newNode = new ListNode;      // 创建新节点
    //创建新的空间
    newNode->val = value;
    newNode->next = nullptr;

    if (head == nullptr) {
        head = newNode;                     // 如果链表为空,直接将新节点作为头节点
    }
    else {
        ListNode* tmp = head;
        while (tmp->next != nullptr) {
            tmp = tmp->next;                 // 遍历链表,找到尾部节点
        }
        tmp->next = newNode;                 // 将新节点连接到尾部节点的next指针上
    }
}

// 在指定位置插入节点
void insertNode(ListNode*& head, int value, int pos) {
    if (pos <= 0) {
        ListNode* newNode = new ListNode;  // 创建新节点
        newNode->val = value;
        newNode->next = head;               // 将新节点连接到头节点之前
        head = newNode;                     // 将新节点作为头节点

    }
    else {
        ListNode* tmp = head;
        int count = 1;
        while (tmp != nullptr && count < pos)
        //tmp != nullptr是因为我们插入是必须要左右两边都有数据才能叫插入,
            //不然就只能添加,不可以直接填在一个很远的空间里,不然就浪费空间了
        {
            tmp = tmp->next;                 // 遍历链表,找到指定位置的前一个节点
            count++;
        }
        if (tmp != nullptr)
        //必须是在tmp不为空时,才能算成插入。
            //再次判断是因为我们只选取count遍历到pos的位置的这种情况,而不是空的链表的情况。
            
        {
            ListNode* newNode = new ListNode;  // 创建新节点
            newNode->val = value;
            newNode->next = tmp->next;         // 将新节点连接到当前节点的next指针上
            //这是链接步骤的代码,把数据插入
            //至于next是因为我们是要插入在数据的中间,也就是tmp的next的位置
            tmp->next = newNode;
            //这个是指向新的插入数据的步骤,方便下一次数据的插入。
         
        }
        else {
            std::cout << "插入位置超过链表长度!" << std::endl;
        }
    }
}

// 删除指定位置的节点
void deleteNode(ListNode*& head, int pos) {
    if (head == nullptr) {
        std::cout << "链表为空,无法删除节点!" << std::endl;
        return;
    }

    if (pos <= 0) {
        ListNode* tmp = head;
        head = head->next;          // 删除头节点
        delete tmp;

    }
    else {
        ListNode* tmp = head;
        int count = 1;
        while (tmp->next != nullptr && count < pos) {
            tmp = tmp->next;        // 遍历链表,找到指定位置的前一个节点
            count++;
        }
        if (tmp->next != nullptr) {
            ListNode* delNode = tmp->next;//先指向当前数据
            tmp->next = delNode->next;
            //直接将当前数据跳到下一个,前面已经链接好的数据不会丢失因为都在同一个位置
            //我们不过是把当前数据覆盖成下一个罢了
            delete delNode;
        }
        else {
            std::cout << "删除位置超过链表长度!" << std::endl;
        }
    }
}

// 打印链表
void printList(ListNode* head) {
    ListNode* tmp = head;
    while (tmp != nullptr) {
        std::cout << tmp->val << " ";
        tmp = tmp->next;
    }
    std::cout << std::endl;
}

int main() {
    ListNode* myList;
    initList(myList);

    // 在链表尾部增加节点
    appendNode(myList, 1);
    appendNode(myList, 2);
    appendNode(myList, 3);

    printList(myList);  // 输出:1 2 3

    // 在指定位置插入节点
    insertNode(myList, 4, 2);

    printList(myList);  // 输出:1 4 2 3

    // 删除节点
    deleteNode(myList, 2);

    printList(myList);  // 输出:1 2 3

    return 0;
}
相关推荐
WIN赢27 分钟前
【二叉树的递归算法与层序遍历算法】
数据结构
Zzzzmo_1 小时前
【Java】杨辉三角、洗牌算法
java·数据结构·算法
岑梓铭3 小时前
《考研408数据结构》第四章(串和串的算法)复习笔记
数据结构·笔记·考研·算法
胖咕噜的稞达鸭4 小时前
缝合怪deque如何综合list和vector实现及仿函数模板如何优化priority_queue实现
数据结构·c++·算法·链表·list
暴力求解5 小时前
数据结构---栈和队列详解(下)
数据结构
jinmo_C++5 小时前
数据结构_哈夫曼编码(Huffman)完整指南:从原理到实现,附考研真题详解
数据结构·考研
那我掉的头发算什么5 小时前
【数据结构】优先级队列(堆)
java·开发语言·数据结构·链表·idea
如竟没有火炬6 小时前
LRU缓存——双向链表+哈希表
数据结构·python·算法·leetcode·链表·缓存
爱吃生蚝的于勒7 小时前
【Linux】零基础学会Linux之权限
linux·运维·服务器·数据结构·git·算法·github
爱编程的化学家8 小时前
代码随想录算法训练营第27天 -- 动态规划1 || 509.斐波那契数列 / 70.爬楼梯 / 746.使用最小花费爬楼梯
数据结构·c++·算法·leetcode·动态规划·代码随想录