有序顺序表中删除所有值重复的元素,使表中所有元素均不同
好的,我将提供更详细的解释和注释。
第一步,定义有序顺序表的数据结构。
#include <stdio.h> // 包含标准输入输出库
#define MaxSize 20 // 定义顺序表的最大长度
typedef int ElemType; // 定义顺序表存储的元素类型为int
typedef struct { // 定义顺序表的结构体
ElemType data[MaxSize]; // 用于存储顺序表元素的数组
int length; // 顺序表当前的长度
} SqList;
解释: 顺序表是一种线性数据结构,我们使用一个固定大小的数组来存储顺序表中的元素。length
字段用来记录顺序表中当前元素的数量。
第二步,编写删除有序顺序表中所有值重复的元素的算法。
算法思想1:
由于顺序表是有序的,重复元素必定是连续的。可以用一个指针k
记录非重复元素的个数,将非重复元素移动到k
下标所在位置。
bool Del_Sql_Rep1(SqList &L) { // 通过引用传递顺序表,以便在函数内部修改顺序表
if (L.length == 0) { // 如果顺序表为空,则返回false
return false;
}
int k = 0; // k用于记录非重复元素的下标
ElemType rep = L.data[0]; // 初始化rep为第一个元素,以便开始比较
for (int i = 1; i < L.length; i++) { // 从第二个元素开始遍历
while (rep == L.data[i] && i < L.length) { // 跳过所有重复元素
i++; // 移动到下一个元素,直到遇到不重复的元素
}
if (i < L.length) { // 如果没有到达顺序表的末尾
rep = L.data[i]; // 更新rep为当前非重复元素
L.data[++k] = L.data[i]; // 将非重复元素移动到k下标所在位置
}
}
L.length = k + 1; // 更新顺序表长度,k是最后一个非重复元素的下标
return true;
}
解释: 此算法通过一个循环遍历顺序表,使用变量k
来跟踪非重复元素的位置,将非重复元素移动到数组的前面,最后更新顺序表的长度。
算法思想2:
初始时,将第一个元素作为非重复元素。后续元素与其比较,如相同,则继续往后遍历;如不相同,则插入该非重复元素的后面。
bool Del_Sql_Rep2(SqList &L) { // 通过引用传递顺序表,以便在函数内部修改顺序表
if (L.length == 0) { // 如果顺序表为空,则返回false
return false;
}
int i = 0, j = 1; // i用于记录非重复元素的下标,j用于遍历顺序表
while (j < L.length) { // 外层循环控制j,内层循环控制i
if (L.data[i] != L.data[j]) { // 非重复时i自增,并将j的元素复制到i+1位置
L.data[++i] = L.data[j];
}
j++; // j自增,继续遍历
}
L.length = i + 1; // 更新顺序表长度,i是最后一个非重复元素的下标
return true;
}
解释: 此算法使用两个指针i
和j
,i
用于跟踪非重复元素的位置,j
用于遍历顺序表。如果L.data[j]
与L.data[i]
不同,则将L.data[j]
复制到L.data[i+1]
,然后i
和j
都自增;如果相同,则只将j
自增。
第三步,编写打印函数。
void PrintSql(SqList L) { // 打印顺序表函数
for (int i = 0; i < L.length; i++) { // 遍历顺序表
printf("L.data[%d] = %d\n", i, L.data[i]); // 打印每个元素及其索引
}
}
解释: 这个函数遍历顺序表,访问每个元素,并打印其数据。
第四步,编写main
函数。
int main() {
SqList L; // 创建顺序表L
L.length = 0; // 初始化长度为0
printf("Input the length of the sequence:\n");
scanf("%d", &L.length); // 读取用户输入的顺序表长度
printf("Input the elements of the sequence (end with a negative number):\n");
int input; // 用于存储用户输入的元素
for (int i = 0; i < L.length; i++) { // 循环读取用户输入的元素
scanf("%d", &input);
if (input < 0) { // 遇到负数结束输入
break;
}
L.data[i] = input; // 将输入的元素存储到顺序表中
}
bool ret = Del_Sql_Rep1(L); // 可以选择调用任一删除重复元素的函数
// bool ret = Del_Sql_Rep2(L); // 可以选择调用另一个删除重复元素的函数
if (ret) {
PrintSql(L); // 打印处理后的顺序表
} else {
printf("Failed to delete duplicates.\n"); // 如果删除失败,打印失败信息
}
return 0;
}
解释: main
函数是程序的入口点。它首先初始化顺序表,然后读取用户输入的顺序表元素。接着,它调用删除重复元素的函数,并打印处理后的顺序表。
完整代码:
#include <stdio.h>
#define MaxSize 20 // 定义顺序表的最大长度
typedef int ElemType; // 定义顺序表存储的元素类型为int
typedef struct { // 定义顺序表的结构体
ElemType data[MaxSize]; // 用于存储顺序表元素的数组
int length; // 顺序表当前的长度
} SqList;
// 删除有序顺序表中所有值重复的元素(算法一)
bool Del_Sql_Rep1(SqList &L) { // 通过引用传递顺序表,以便在函数内部修改顺序表
if (L.length == 0) { // 如果顺序表为空,则返回false
return false;
}
int k = 0; // k用于记录非重复元素的下标
ElemType rep = L.data[0]; // 初始化rep为第一个元素,以便开始比较
for (int i = 1; i < L.length; i++) { // 从第二个元素开始遍历
while (rep == L.data[i] && i < L.length) { // 跳过所有重复元素
i++; // 移动到下一个元素,直到遇到不重复的元素
}
if (i < L.length) { // 如果没有到达顺序表的末尾
rep = L.data[i]; // 更新rep为当前非重复元素
L.data[++k] = L.data[i]; // 将非重复元素移动到k下标所在位置
}
}
L.length = k + 1; // 更新顺序表长度,k是最后一个非重复元素的下标
return true;
}
// 删除有序顺序表中所有值重复的元素(算法二)
bool Del_Sql_Rep2(SqList &L) { // 通过引用传递顺序表,以便在函数内部修改顺序表
if (L.length == 0) { // 如果顺序表为空,则返回false
return false;
}
int i = 0, j = 1; // i用于记录非重复元素的下标,j用于遍历顺序表
while (j < L.length) { // 外层循环控制j,内层循环控制i
if (L.data[i] != L.data[j]) { // 非重复时i自增,并将j的元素复制到i+1位置
L.data[++i] = L.data[j];
}
j++; // j自增,继续遍历
}
L.length = i + 1; // 更新顺序表长度,i是最后一个非重复元素的下标
return true;
}
// 打印顺序表函数
void PrintSql(SqList L) { // 打印顺序表函数
for (int i = 0; i < L.length; i++) { // 遍历顺序表
printf("L.data[%d] = %d\n", i, L.data[i]); // 打印每个元素及其索引
}
}
// 主函数
int main() {
SqList L; // 创建顺序表L