一、实验要求
构造一个线性表,要求能够完成插入、删除操作,可以输出全部项的数据,并可以将两个线性表归并到第三个空表中。
二、参考代码
本代码通过构造一些随机数输入线性表来完成演示。导入 random 头文件后,构造随机均匀整数分布
std::uniform_int_distribution<unsigned int> u(a, b);
来获得一个均匀整数分布,范围是离散闭区间 [a, b] 。
此外,还需要声明一个随机引擎
std::default_random_engine d;
来获取随机数。通过调用 u(d) 就可以返回一个 [a, b] 范围内的随机整数。
随机引擎需要通过不同的种子来获取不同的随机数序列,这里采用 clock() 函数获得程序启动以来的毫秒数作为随机数种子。
为了训练读者阅读代码的能力,将不对代码作详细解释,只是提一些比较容易出错的地方:
1、函数
void *__cdecl malloc(size_t _Size)
的 _Size 参数是字节数,而不是数组长度。如果分配的空间不足导致写入超过已分配(已授予权限)内存的末端,将会出错。当然这个出错常常不是会立即终止程序并提示的,而是会在执行若干语句后才报错。越界访问可能会提示 Access Violation 或 0xC0000005 或 0xC0000374 或干脆只提示“触发了一个断点”而无任何错误代码。
#include<cstdio>
#include<algorithm>
#include<random>
#include<ctime>
#pragma warning(disable:4996)
unsigned n, p;
struct list { unsigned* data = nullptr, len = 0; };
inline void ins(list &L, const unsigned &pos, const unsigned &num){
for (unsigned i = L.len; i > p; --i){ L.data[i] = L.data[i - 1]; }
L.data[p + 1] = num; ++L.len;
}
inline void del(list &L, const unsigned &pos){
for (unsigned i = pos; i < L.len; ++i){ L.data[i] = L.data[i + 1]; }
--L.len;
}
int main(){
for (;;){
std::uniform_int_distribution<unsigned> u(1, 32), v(0, 62), w(0, 99);
std::default_random_engine d; d.seed(clock());
puts("建立线性表 L");
list L; L.data = (unsigned*)malloc(256);
n = u(d); printf("本次输入数据共 %u 个:\n", n);
for (unsigned i = 0; i < n; ++i){ L.data[i] = w(d); printf("%u ", L.data[i]); ++L.len; }
printf("\n线性表 L 的长度 = %u\n", L.len);
n = u(d);
for (unsigned h = 0; h < n && L.len < 64; ++h) {
p = v(d); if (p >= L.len) { --h; continue; }
ins(L, p, v(d)); printf("在 L 的位置 %u 后插入数据 %u\n", p, L.data[p + 1]);
puts("列表 L 的所有项:");
for (unsigned i = 0; i < L.len; ++i){
printf("%u ", L.data[i]);
if (i == p)putchar('*');
}
printf("\n线性表 L 的长度 = %u\n", L.len);
}
n = u(d); putchar('\n');
for (unsigned h = 0; h < n && L.len > 0; ++h) {
p = v(d); if (p >= L.len) { --h; continue; }
del(L, p); printf("删除 L 的位置 %u 的数据\n", p);
puts("列表 L 的所有项:");
for (unsigned i = 0; i < L.len; ++i){
printf("%u ", L.data[i]);
if (i == p)putchar('*');
}
printf("\n线性表 L 的长度 = %u\n", L.len);
}
puts("\n建立线性表 M");
list M; M.data = (unsigned*)malloc(256);
n = u(d); printf("本次输入数据共 %u 个:\n", n);
for (unsigned i = 0; i < n; ++i){ M.data[i] = w(d); printf("%u ", M.data[i]); ++M.len; }
printf("\n线性表 M 的长度 = %u\n\n", M.len);
n = u(d);
for (unsigned h = 0; h < n && M.len < 64; ++h) {
p = v(d); if (p >= M.len) { --h; continue; }
ins(M, p, v(d)); printf("在 M 的位置 %u 后插入数据 %u\n", p, M.data[p + 1]);
puts("列表 M 的所有项:");
for (unsigned i = 0; i < M.len; ++i){
printf("%u ", M.data[i]);
if (i == p)putchar('*');
}
printf("\n线性表 M 的长度 = %u\n", M.len);
}
n = u(d); putchar('\n');
for (unsigned h = 0; h < n && M.len > 0; ++h) {
p = v(d); if (p >= M.len) { --h; continue; }
del(M, p); printf("删除 M 的位置 %u 的数据\n", p);
puts("列表 M 的所有项:");
for (unsigned i = 0; i < M.len; ++i){
printf("%u ", M.data[i]);
if (i == p)putchar('*');
}
printf("\n线性表 M 的长度 = %u\n", M.len);
}
puts("将表 L 和表 M 合并为表 N\n");
puts("列表 L 的所有项:");
for (unsigned i = 0; i < L.len; ++i) { printf("%u ", L.data[i]); }
printf("\n线性表 L 的长度 = %u\n", L.len);
puts("列表 M 的所有项:");
for (unsigned i = 0; i < M.len; ++i) { printf("%u ", M.data[i]); }
printf("\n线性表 M 的长度 = %u\n", M.len);
list N; N.len = L.len + M.len; N.data = (unsigned*)malloc(4 * N.len);
std::copy(&L.data[0], &L.data[L.len], &N.data[0]);
std::copy(&M.data[0], &M.data[M.len], &N.data[L.len]);
puts("\n列表 N 的所有项:");
for (unsigned i = 0; i < N.len; ++i) { printf("%u ", N.data[i]); }
printf("\n线性表 N 的长度 = %u\n", N.len);
free(L.data); free(M.data); free(N.data);
puts("\n要继续,输入任意字符;否则,输入EOF");
if (getchar() == EOF)return 0;
}
}

本文介绍了一种实现线性表的方法,包括插入、删除元素及两表归并的操作。通过构造随机数序列,演示了如何在C++中创建线性表,执行基本操作并最终将两个线性表合并到一个新表中。
866

被折叠的 条评论
为什么被折叠?



