现在有一个排好序的若干个元素(升序),现在要插入一个元素啊,请你输入插入该元素后的序列(升序)
请分别用单链表实现,和数组模拟单链表实现
为什么要用数组模拟单链表
1.内存局部性:数组在内存中是连续存储的,因此在访问元素时可以充分利用缓存,提升访问效率。而链表由于节点不连续,可能导致更多的缓存未命中。
2.减少内存碎片:链表的节点分散在内存中,可能会导致内存碎片,而使用数组可以保证内存的有效利用。
3.简化实现:在某些情况下,使用数组来模拟链表的操作(如插入、删除等)可以简化代码逻辑,因为数组的索引可以直接用于访问和修改元素。
固定大小的结构:如果知道链表的最大大小,可以预先定义一个足够大的数组,避免在运行时频繁分配和释放内存,这样可以提高效率。
4.特定应用场景:在某些特定的应用场景中,比如实现队列或栈等数据结构,使用数组可能更为合适。
在我们构建单链表的时候我们应该如何插入新的节点呢?
此时链表已经构建好了我们怎么插入新节点呢?
单链表实现代码如下:
#include<iostream>
using namespace std;
// 定义链表节点结构体
struct node {
int data; // 节点数据
struct node* next; // 指向下一个节点的指针
};
struct node* head, * p, * r;
int main() {
int n;
cin >> n;
head = new node; // 创建头节点
head->next = NULL; // 头节点的 next 初始为空
r = head;
// 创建 n 个元素的链表
for (int i = 1; i <= n; i++) {
p = new node; // 分配新节点
cin >> p->data; // 输入节点数据
p->next = NULL; // 新节点的 next 设为 NULL
r->next = p; // 将新节点接到前一个节点的 next
r = p; // r 前移到新节点
}
int t;
cin >> t; // 读取要插入的数值
struct node* q = new node;
q->data = t;
q->next = NULL;
// 插入操作,处理链表为空或插入到头部的情况
if (head->next == NULL || head->next->data > t) {
// 如果链表为空,或者要插入的值比第一个节点的值小,则插入到头节点后
q->next = head->next; // q 的 next 指向头节点的下一个节点
head->next = q; // 头节点的 next 指向 q
}
else {
// 遍历链表找到合适的位置进行插入
p = head->next; // p 指向第一个有效节点
while (p->next != NULL && p->next->data <= t) {
p = p->next; // 找到第一个比 t 大的节点
}
// 将 q 插入到 p 之后
q->next = p->next;
p->next = q;
}
// 输出链表中的所有元素
p = head->next; // 从第一个有效节点开始遍历
while (p != NULL) {
cout << p->data << " ";
p = p->next;
}
cout << endl;
return 0;
}
数组模拟单链表
数组模拟单链表代码如下:
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
using namespace std;
int main() {
// 存储数据值的数组
int data[101];
// 存储链表结构的“右指针”数组
int right[101];
int n, len, t;
// 将“右指针”数组初始化为 -1
memset(right, -1, sizeof(right));
// 读取元素个数
cin >> n;
// 将初始的有序数据读取到 data 数组中
for (int i = 1; i <= n; i++) {
cin >> data[i];
}
// 将长度设置为读取的元素个数
len = n;
// 设置链表的“右指针”
for (int i = 0; i < n; i++) {
right[i] = i + 1; // 将每个索引连接到下一个索引
}
right[n] = -1; // 最后一个元素指向 -1,表示结束
// 输入要插入的新元素
len++; // 增加长度以考虑新元素
cin >> data[len];
// 找到正确的插入位置
t = 0; // 从链表的头部开始
// 遍历链表以找到插入点
while (true) {
// 检查是否应该在当前节点后插入新元素
if (right[t] == -1 || data[right[t]] > data[len]) {
// 设置新元素的右指针
right[len] = right[t];
right[t] = len; // 将当前节点连接到新元素
break; // 插入完成,退出循环
}
t = right[t]; // 移动到下一个节点
}
// 输出包含新插入元素的有序链表
t = right[0]; // 从链表的头部开始
while (t != -1) {
cout << data[t] << " "; // 打印当前元素
t = right[t]; // 移动到下一个元素
}
return 0; // 程序结束
}
单链表和数组模拟单链表gitee源码