首页 > 编程语言 >C++实现静态链表

C++实现静态链表

时间:2024-08-03 21:55:07浏览次数:12  
标签:cout 静态 value next 链表 int C++ 节点

#include <iostream>
using namespace std;

// 定义静态链表的最大容量
const int MAX_SIZE = 100;

// 节点类
class Node {
public:
    int data;  // 节点存储的数据
    int next;  // 节点指向下一个节点的索引(在数组中的位置)

    // 默认构造函数
    Node() : data(0), next(-1) {}
};

// 静态链表类
class StaticLinkedList {
private:
    Node nodes[MAX_SIZE]; // 存储链表节点的数组
    int head;             // 链表的头节点索引
    int freeIndex;        // 可用节点的索引

public:
    // 构造函数,初始化静态链表
    StaticLinkedList() {
        head = -1;           // 初始化头节点索引为 -1,表示链表为空
        freeIndex = 0;       // 自由节点的索引从0开始
        // 初始化所有节点的 next 为 -1,表示链表的末尾
        for (int i = 0; i < MAX_SIZE; ++i) {
            nodes[i].next = -1;
        }
    }

    // 检查链表是否为空
    bool isEmpty() const {
        return head == -1;
    }

    // 检查链表是否已满
    bool isFull() const {
        return freeIndex >= MAX_SIZE;
    }

    // 插入节点到链表末尾
    void append(int value) {
        if (isFull()) {
            cout << "链表已满,无法插入新节点" << endl;
            return;
        }

        int newNodeIndex = freeIndex; // 获取新节点的索引
        nodes[newNodeIndex].data = value;   // 设置节点数据
        nodes[newNodeIndex].next = -1;      // 新节点的 next 设为 -1(即链表末尾)

        if (isEmpty()) {
            head = newNodeIndex; // 如果链表为空,新节点成为头节点
        }
        else {
            int current = head; // 从头节点开始遍历
            while (nodes[current].next != -1) {
                current = nodes[current].next; // 移动到下一个节点
            }
            nodes[current].next = newNodeIndex; // 将新节点连接到链表末尾
        }

        ++freeIndex; // 更新自由节点索引
    }

    // 删除链表中指定值的节点
    void deleteNode(int value) {
        if (isEmpty()) {
            cout << "链表为空,无法删除节点" << endl;
            return;
        }

        int current = head;
        int previous = -1;

        while (current != -1 && nodes[current].data != value) {
            previous = current;
            current = nodes[current].next;
        }

        if (current == -1) {
            cout << "未找到值为 " << value << " 的节点" << endl;
            return;
        }

        if (previous == -1) {
            head = nodes[current].next; // 删除的是头节点
        }
        else {
            nodes[previous].next = nodes[current].next; // 删除非头节点
        }

        // 将删除的节点放回自由节点数组
        nodes[current].next = freeIndex;
        freeIndex = current;
    }

    // 查找链表中是否存在指定值的节点
    bool search(int value) const {
        int current = head;
        while (current != -1) {
            if (nodes[current].data == value) {
                return true; // 找到节点
            }
            current = nodes[current].next; // 移动到下一个节点
        }
        return false; // 未找到节点
    }

    // 打印链表中的所有节点
    void display() const {
        if (isEmpty()) {
            cout << "链表为空" << endl;
            return;
        }

        int current = head;
        while (current != -1) {
            cout << nodes[current].data << " -> "; // 输出当前节点的数据
            current = nodes[current].next; // 移动到下一个节点
        }
        cout << "NULL" << endl; // 链表末尾
    }

    // 逆置链表
    void reverse() {
        if (isEmpty() || nodes[head].next == -1) {
            // 空链表或仅有一个节点,不需要逆置
            return;
        }

        int prev = -1;
        int current = head;
        int nextNode = nodes[current].next;

        while (current != -1) {
            nodes[current].next = prev; // 逆置当前节点的指针
            prev = current; // 移动 prev 到当前节点
            current = nextNode; // 移动到下一个节点
            if (current != -1) {
                nextNode = nodes[current].next; // 更新 next 指针
            }
        }

        head = prev; // 更新头节点为最后一个节点
    }
};

// 主函数
int main() {
    StaticLinkedList list; // 创建静态链表实例
    int choice, value;

    do {
        cout << "菜单:" << endl;
        cout << "1. 添加节点" << endl;
        cout << "2. 删除节点" << endl;
        cout << "3. 查找节点" << endl;
        cout << "4. 显示链表" << endl;
        cout << "5. 逆置链表" << endl;
        cout << "0. 退出" << endl;
        cout << "请输入您的选择: ";
        cin >> choice; // 获取用户选择

        switch (choice) {
        case 1:
            cout << "请输入要添加的值: ";
            cin >> value; // 获取用户输入的值
            list.append(value); // 调用添加函数
            break;
        case 2:
            cout << "请输入要删除的值: ";
            cin >> value; // 获取用户输入的值
            list.deleteNode(value); // 调用删除函数
            break;
        case 3:
            cout << "请输入要查找的值: ";
            cin >> value; // 获取用户输入的值
            if (list.search(value)) {
                cout << "值在链表中找到。" << endl;
            }
            else {
                cout << "值不在链表中。" << endl;
            }
            break;
        case 4:
            list.display(); // 调用显示函数
            break;
        case 5:
            list.reverse(); // 调用逆置函数
            cout << "链表已逆置。" << endl;
            break;
        case 0:
            cout << "退出程序。" << endl;
            break;
        default:
            cout << "无效选择,请重新输入。" << endl;
        }
    } while (choice != 0); // 用户选择0时退出

    return 0; // 返回0表示程序正常结束
}

标签:cout,静态,value,next,链表,int,C++,节点
From: https://blog.csdn.net/w1277256813/article/details/140897800

相关文章

  • 链表part01
    今天是8月2日,学习了链表的基础知识。题目主要是链表的基础操作和反转链表,注意虚拟头节点的使用、next的顺序和tmp的灵活使用。1.移除元素题目:给一个链表的头节点head和整数val,请删除链表中所有满足Node.val==val的节点,并返回新的头节点。删除的方法,cur指针挨个遍......
  • c++三国杀
    废话不多说,直接上代码!!!#include<iostream>#include<time.h>#include<stdio.h>#include<stdlib.h>usingnamespacestd;structpai{intpaifu;inthuase;intyanse;intdianshu;intleixing;intchangdu;voidKanpai(){if(paifu==0||paifu==......
  • 「字符串」实现Trie(字典树|前缀树)的功能 / 手撕数据结构(C++)
    概述在浏览器搜索栏里输入几个字,就弹出了以你的输入为开头的一系列句子。浏览器是怎么知道你接下来要输什么的?来看看字典树干了什么。字典树是一种高效记录字符串和查找字符串的数据结构。它以每个字符作为一个节点对字符串进行分割记录,节点形成树状结构,在录入或查找时只......
  • 【leetcode详解】正方形中的最多点数【中等】(C++思路精析)
    思路精析:自定义结构体解读:一个点是否在题给正方形中,只取决于其横纵坐标的最大值,记为dis沟通二位数组points和字符串s的桥梁,就是这个点的序号,记为idx由此自定义结构体,储存dis和idx//其中booloperator部分的功能:重载小于操作符“<”,使sort(vc.begin(),vc.end());按dis......
  • 结构体与共用体,链表的学习
    结构体定义        C语言允许用户自己定义一种数据结构,称为结构体。        声明一个结构体类型一般形式为:                strcut 结构体名                {                    成员列表......
  • 整数二分(c++)
    1、什么是整数二分:即可以看做成找数字那个游戏在一百个数字中找到指定的数字(66)A出题B:50A50太小了B:(50+100)/2=75A75太大了B:(50+75)/2=62…所以也可以知道一个结论:有单调性,一定可以二分。可以二分的题目,不一定有单调性。2、代码思路:1、寻找到满足......
  • 【C++BFS】802. 找到最终的安全状态
    本文涉及知识点C++BFS算法LeetCode802.找到最终的安全状态有一个有n个节点的有向图,节点按0到n-1编号。图由一个索引从0开始的2D整数数组graph表示,graph[i]是与节点i相邻的节点的整数数组,这意味着从节点i到graph[i]中的每个节点都有一条边。如果一......
  • 离散化-c++
    离散化:一、使用情景值域大e.g.0~1e9个数少e.g.0~1e5二、使用方法将数组中的数映射到从0开始的自然数a[]:1、3、100、2000、50000映射到从0开始的自然数:0,1,2,3,4这个过程就是离散化三、两个问题:1.a数组中最开始可能有重复元素,需要去重vector<int>alls;//存......
  • C++ 面向对象基础-构造函数
    目录1.构造函数1.1基本使用1.2函数参数默认值1.3构造初始化列表 1.4隐式调用构造函数2.拷贝构造函数2.1概念2.2浅拷贝2.3深拷贝3.析构函数1.构造函数1.1基本使用构造函数是一种特殊的成员函数,用于创建对象时初始化,写法上有以下要求:●函数名称必......
  • 【C++】实验十五
    题目:1、求一元二次方程ax2+bx+c=0的实根。如果方程没有实根,则利用异常处理处理机制输出有关警告信息2、学校的人事部门保留了有关学生的部分数据(学号、姓名、年龄、住址)。教务部门也保留了学生的另一些数据(学号、姓名、性别,成绩),两个部门分别编写了本部门的学生数据管理程序,其......