C++使用静态数组模拟单链表

这是一个学习笔记,笔者在学习了数据结构的单链与acwing的课程后所写。

为什么使用数组来模拟链表

一般面试会采用如下方法。

struct Node 
{
    int data;
    Node* next;
};

但是,我们每一次创建一个新的链表的时候会调用一次new函数

new Node();

该操作非常慢,在面对大量的数据时会非常的耗时间,所以我们采用数组的形式来模拟。

单链表的原理

使用两个数组。一个数组(Data[N])来存储数据,等价于数据结构的数据域;另一个数据(Next[N])来存储该点下一个数据的下标,等价于数据结构的指针域。

 准备工作

/*
head表示头结点的下标
Data[i]表示节点i的元素值
Next[i]表示节点i的Next指针是多少
idx储存当前用到了哪一个点
*/
#define N 10
int head, Data[N], Next[N], idx;

 初始化

void init()
{
    head = -1;//此时链表为空,所以头节点指向空集
    idx = 0;//此时链表为空,所以用到了第0个点
}

插入操作

插入操作有一以下三种,头插 尾插 按位插入

头插操作

// 将x插入到链表的头部
void add_to_head(int x)
{
    if (idx >= N)//增加判断操作,以提高代码的健壮性
    {
        cout << "错误: add_too_head 中数组溢出" << endl;
        return;
    }
    Data[idx] = x;//第一步
    Next[idx] = head;//第二步
    head = idx;//第三步
    idx++;
}

 尾插操作

// 将x插入到链表的尾部
void add_to_tail(int x)
{
    if (idx >= N)
    {
        cout << "错误: add_too_tail 中数组溢出" << endl;
        return;
    }
    Data[idx] = x;
    Next[idx] = -1;
    if (head == -1)//增加判断,检查链表是否为空,并在链表为空的情况下,将新节点设置为链表的第一个节点
    {
        head = idx;//说白了,就是头插操作
    }
    else
    {
        int i = head;
        while (Next[i] != -1)// 遍历链表,找到最后一个节点
        {
            i = Next[i];
        }
        Next[i] = idx;// 将新节点插入到链表的末尾
    }
    idx++;
}

不画图啦,和头插操作类似。 

按位插入

在第k个结点后添加某个数据元素。

// 在第k个节点后插入x
void add_to_kth(int k, int x)
{
    if (k < 0 || k >= idx)//防止
    {
        cout << "错误: add  中的索引无效" << endl;
        return;
    }
    if (idx >= N)
    {
        cout << "错误: add  中数组溢出" << endl;
        return;
    }
    //储存
    Data[idx] = x;//第一步
    //将新节点的Next指针指向原第k个节点的Next指针所指向的节点
    Next[idx] = Next[k];//第二步
    //将第k个节点的Next指针指向新节点
    Next[k] = idx;//第三步
    idx++;
}

按位删除

// 删除第k个节点
void remove(int k)
{
    if (k < 0 || k >= idx)// 检查k是否正确
    {
        cout << "错误: remove  中的索引无效" << endl;
        return;
    }
    if (Next[k] == -1)// 检查要删除的节点是否有下一个元素
    {
        cout << "错误: 无法删除无下一元素的节点" << endl;
        return;
    }
    Next[k] = Next[Next[k]];// 将第k个节点的Next指针指向其下一个节点的下一个节点
    //一般在做题的过程中,我们不考虑内存的问题,链表中没有出现该元素,即为已删除
}

 测试环节

在测试中添加了如下代码用于打印链表

void print_list()
{
    int i = head;
    while (i != -1)
    {
        cout << Data[i] << " ";
        i = Next[i];
    }
    cout << endl;
}

测试代码

    init(); // 初始化链表

    // 测试插入操作
    add_to_head(1); // 插入到头部
    add_to_tail(2); // 插入到尾部
    add_to_kth(0, 3); // 在第0个节点后插入3
    add_to_kth(1, 4); // 在第1个节点后插入4

    // 打印链表
    cout << "链表内容: ";
    print_list();

    // 测试删除操作
    remove(1); // 删除第1个节点

    // 打印链表
    cout << "删除第1个节点后的链表内容: ";
    print_list();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值