C++ 实现静态链表的简单实例

C++ 实现静态链表的简单实例

静态链表是一种用数组模拟链表的数据结构,它可以在不施加缩容操作的情况下随时增长,且可以通过给数组预分配较大的内存空间来节省插入和删除元素时的内存分配操作。下面将介绍如何使用 C++ 实现静态链表,并给出实例说明。

静态链表的实现思路

静态链表由两个数组组成:数据数组和结点数组。结点数组用于描述结点之间的链接关系,数据数组则存储实际的数据。由于静态链表是数组模拟链表,因此需要在结点数组中维护一个指向下一个结点的指针索引,这个指针索引的取值范围是 [0, 数组长度 - 1],其中当指针值为 0 时,表示链表的结尾。下面是静态链表的结点定义:

struct Node {
    int data; // 存储实际数据
    int next; // 存储下一个结点的索引
};

实现过程说明

下面是一个简单的使用 C++ 实现静态链表的过程:

  1. 头文件中定义结点结构体
// list.h
#ifndef LIST_H
#define LIST_H

struct Node {
    int data; // 存储实际数据
    int next; // 存储下一个结点的索引
};

#endif
  1. 实现静态链表类及其方法
// static_list.cpp
#include "list.h"

class StaticList {
public:
    StaticList(int max_size);
    ~StaticList();
    int insert(int index, int value);
    int remove(int index);
    int find(int value);
    void display();

private:
    Node *node_list_; // 结点数组
    int head_; // 链表头结点的索引
    int max_size_; // 结点数组的最大长度
    int size_; // 结点数组的当前长度
};

StaticList::StaticList(int max_size) {
    max_size_ = max_size;
    size_ = 0;
    node_list_ = new Node[max_size_];
    head_ = 0; // 链表初始为空,头结点的 next 指针为 0
    for (int i = 0; i < max_size_; i++) {
        node_list_[i].next = i + 1; // 每个结点的 next 指针指向下一个位置
    }
    node_list_[max_size_ - 1].next = 0; // 最后一个结点的 next 指针指向 0,表示链表结尾
}

StaticList::~StaticList() {
    if (node_list_ != nullptr) {
        delete[] node_list_;
        node_list_ = nullptr;
    }
}

int StaticList::insert(int index, int value) {
    // 链表已满,无法插入新结点
    if (size_ >= max_size_ - 1) {
        return -1;
    }
    // 插入位置不合法
    if (index < 0 || index > size_) {
        return -1;
    }
    int current_index = head_;
    int next_index = node_list_[current_index].next;
    int insert_index = 0;
    // 寻找要插入的结点的前一个结点 current_index 和 next_index
    for (int i = 0; i < index; i++) {
        current_index = next_index;
        next_index = node_list_[current_index].next;
    }
    // 获取一个新的结点插入到 current_index 和 next_index 之间
    insert_index = node_list_[max_size_ - 1].next;
    node_list_[max_size_ - 1].next = node_list_[insert_index].next;
    node_list_[insert_index].data = value;
    node_list_[insert_index].next = next_index;
    node_list_[current_index].next = insert_index;
    size_++;
    return 0;
}

int StaticList::remove(int index) {
    // 插入位置不合法
    if (index < 0 || index >= size_) {
        return -1;
    }
    int current_index = head_;
    int next_index = node_list_[current_index].next;
    // 寻找要删除的结点的前一个结点 current_index 和 next_index
    for (int i = 0; i < index; i++) {
        current_index = next_index;
        next_index = node_list_[current_index].next;
    }
    // 将要删除的结点从链表中去除,并将其放回缓存池中
    node_list_[current_index].next = node_list_[next_index].next;
    node_list_[next_index].next = node_list_[max_size_ - 1].next;
    node_list_[max_size_ - 1].next = next_index;
    size_--;
    return 0;
}

int StaticList::find(int value) {
    int current_index = head_;
    int next_index = node_list_[current_index].next;
    // 遍历整个链表,寻找值为 value 的结点
    while (next_index) {
        if (node_list_[next_index].data == value) {
            return next_index;
        }
        current_index = next_index;
        next_index = node_list_[current_index].next;
    }
    // 遍历完毕,未找到指定值的结点
    return 0;
}

void StaticList::display() {
    int current_index = head_;
    int next_index = node_list_[current_index].next;
    // 遍历整个链表,输出各个结点的值
    while (next_index) {
        std::cout << node_list_[next_index].data << " ";
        current_index = next_index;
        next_index = node_list_[current_index].next;
    }
    std::cout << std::endl;
}

示例说明

下面给出两个使用静态链表的实例:

  1. 求 1~1000000 中所有质数的个数
#include "static_list.h"

bool is_prime(int x) {
    for (int i = 2; i <= sqrt(x); i++) {
        if (x % i == 0) {
            return false;
        }
    }
    return true;
}

int main() {
    const int MAX_SIZE = 1000000;
    StaticList list(MAX_SIZE + 1);
    for (int i = 2; i <= MAX_SIZE; i++) {
        list.insert(i - 2, i);
    }
    int count = 0;
    for (int i = 2; i <= MAX_SIZE; i++) {
        int index = list.find(i);
        if (index) {
            count++;
            int current_index = index;
            int next_index = list.node_list_[current_index].next;
            while (next_index) {
                if (node_list_[next_index].data % i == 0) {
                    list.remove(next_index - 2);
                }
                current_index = next_index;
                next_index = list.node_list_[current_index].next;
            }
        }
    }
    std::cout << count << std::endl;
    return 0;
}
  1. N 个人围成一圈,每 M 个人中选出一个,最后剩下的人的编号
#include "static_list.h"

int last_man_standing(int n, int m) {
    StaticList list(n);
    for (int i = 0; i < n; i++) {
        list.insert(i, i + 1);
    }
    int current_index = 0;
    int next_index = list.node_list_[current_index].next;
    while (next_index != current_index) {
        int count = m % list.size_;
        for (int i = 0; i < count - 1; i++) {
            current_index = next_index;
            next_index = list.node_list_[current_index].next;
        }
        list.remove(next_index);
        current_index = next_index;
        next_index = list.node_list_[current_index].next;
    }
    return next_index + 1;
}

int main() {
    std::cout << last_man_standing(10, 3) << std::endl; // 4
    return 0;
}

以上就是 C++ 实现静态链表的简单实例和攻略。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++ 实现静态链表的简单实例 - Python技术站

(0)
上一篇 2023年6月26日
下一篇 2023年6月26日

相关文章

  • vb的if和elseif

    VB的If和ElseIf 在VB中,If语句是一种常用的控制流程语句,可以根据指定的条件来执行不同的代码块。 If语句的基本用法 If语句的基本语法如下: If condition Then ‘ code block End If 其中,condition是要判断的条件,code block是要执行的代码块。当condition为True时,执行code b…

    其他 2023年3月29日
    00
  • Android PC端用ADB抓取指定应用日志实现步骤

    Android PC端用ADB抓取指定应用日志实现步骤 以下是使用ADB(Android Debug Bridge)在PC端抓取指定应用日志的完整攻略: 安装ADB工具 首先,确保你的PC上已经安装了ADB工具。如果没有安装,你可以从Android开发者网站下载并安装ADB。 连接Android设备 使用USB数据线将你的Android设备连接到PC上,并确…

    other 2023年9月7日
    00
  • iOS App的设计模式开发中对State状态模式的运用

    设计模式是软件开发过程中常用的一种思想,它可以帮助我们在开发过程中更加高效、可靠地实现某些功能或解决特定问题。在iOS App的开发中,设计模式也是一个非常重要的话题。其中,State状态模式是一种常见的设计模式,可以帮助我们实现一些状态机相关的功能。 下面,我将详细讲解“iOS App的设计模式开发中对State状态模式的运用”的完整攻略,包括如何使用St…

    other 2023年6月26日
    00
  • 该如何加载google-analytics(或其他第三方)的JS

    加载google-analytics或其他第三方JS的完整攻略分为以下几个步骤: 1. 获取JS代码 首先需要获取google-analytics或其他第三方JS的代码,可以通过访问对应官网或使用CDN地址来获取。 例如,获取Google Analytics的代码可以参考下面的步骤: 访问Google Analytics官网 创建或登录Google帐号; 配…

    other 2023年6月25日
    00
  • PowerShell小技巧之使用New-Module命令动态创建对象

    以下是使用标准的Markdown格式文本,详细讲解PowerShell中使用New-Module命令动态创建对象的完整攻略: PowerShell小技巧之使用New-Module命令动态创建对象 1. New-Module命令简介 New-Module命令是PowerShell中的一个强大工具,用于动态创建自定义的对象。通过New-Module命令,您可以定…

    other 2023年10月14日
    00
  • vue 2.0 开发实践总结之疑难篇

    Vue 2.0 开发实践总结之疑难篇 前言 在实施 Vue 2.0 项目的过程中,难免会遇到一些疑难问题,本篇文章主要总结和分享在实践中遇到的一些问题及解决方案,供大家参考。 问题一:Vue 设计中如何实现自定义指令? 在 Vue 的设计中,自定义指令是非常重要的概念之一。它可以使得开发者更加方便的扩展 Vue 的功能。自定义指令主要有两种方式:全局注册和局…

    其他 2023年3月28日
    00
  • 在win8.1上玩GTA4 无法识别双显卡的分析和解决方案

    下面是在win8.1上玩GTA4无法识别双显卡的分析和解决方案的完整攻略: 问题分析 在win8.1上玩GTA4时,有用户反映游戏无法识别双显卡,导致游戏画质较差、卡顿等问题。这是因为某些游戏无法识别双显卡的正确驱动程序,从而导致游戏无法充分利用双显卡的性能。 解决方案 方法一:使用可能的兼容模式启动游戏 在此情况下,您可以尝试使用可能的兼容模式启动游戏,这…

    other 2023年6月26日
    00
  • web压力测试工具(小而精)

    以下是关于“Java判断包含contains方法的使用”的完整攻略,包括基本概念、使用方法和两个示例。 基本概念 Java中的contains方法是用于判断一个字符串是否包含另一个字符串的方法。它返回一个布尔值,如果被查找的字符串包含指定的字符串,则返回true,否则返回false。contains方法是Java中常用的字符串操作方法之一,可以用于判断字符串…

    other 2023年5月7日
    00
合作推广
合作推广
分享本页
返回顶部