一、实验目的
1.掌握顺序表的定义。
2.熟悉C语言的上机环境,进一步掌握C语言的结构特点。
3.掌握顺序表的初始化、创建、输出、查找、插入、删除、拷贝等基础操作。
4.掌握无序顺序表的冒泡排序和快速排序算法。
二、实验要求
1.写出顺序表的操作的详细算法步骤;
2.使用C/C++实现顺序表,并编译运行。
三、实验过程
实验环境:visual studio 2017
实验步骤:
- 初始化顺序表L,定义函数名为Init_List;
- 创建顺序表L,向顺序表中输入L.length个元素,定义函数名为Creat_List;
- 输出顺序表L,将顺序表中的元素依次打印,定义函数名为Disp_List;
- 查找顺序表L值为e的第一个元素并输出下标,定义函数名为Search_List;
- 在顺序表L下标为index的位置插入一个元素e,定义函数名为Insert_List;
- 将顺序表L下标为index的元素删除,定义函数名为Delete_List;
- 将顺序表L拷贝至顺序表New_L,定义函数名为Copy_List;
- 通过冒泡排序将顺序表L的元素从小到大排列,定义函数名为Bubble_Sort;
- 通过快速排序将顺序表L的元素从小到大排列,定义函数名为Quick_Sort;
SqList.h
#define ELEMTYPE int //用#define定义一个标识符ELEMTYPE表示int
#define MAXSIZE 100 //用#define定义一个标识符ELEMTYPE表示常量100
#include<stdio.h> //调用头文件
#include<stdlib.h> //调用头文件
typedef struct //构建一个结构体存储顺序表信息
{
ELEMTYPE* data; //定义一个数组存放顺序表中的元素
int length; //定义一个整型变量存放顺序表的元素个数
}SqList; //结构别名为SqList
void Init_List(SqList* L); //声明初始化函数-Init_List
void Creat_List(SqList* L); //声明创建函数-Creat_List
void Disp_List(SqList L); //声明打印函数-Disp_List
int Search_List(SqList L, ELEMTYPE e); //声明查找函数-Search_List
void Insert_List(SqList* L, ELEMTYPE e, int index); //声明插入函数-Insert_List
void Delete_List(SqList* L, int index); //声明删除函数-Delete_List
SqList* Copy_List(SqList L, SqList* New_L); //声明拷贝函数-Copy_List
SqList* Bubble_Sort(SqList* L); //声明冒泡排序函数-Bubble_Sort
void Quick_Sort(ELEMTYPE* data, int begin, int end); //声明快速排序函数-Quick_Sort
函数的实现
#include"SqList.h" //调用头文件
void Init_List(SqList* L) //初始化顺序表L
{
L->data = (ELEMTYPE*)malloc(sizeof(ELEMTYPE)*MAXSIZE);
//用malloc给数组分配一块内存
L->length = 0; //初始化顺序表长度为0
}
void Creat_List(SqList* L) //创建顺序表
{
printf("Please input the length:"); //提示输入顺序表长度
scanf("%d",&L->length); //输入顺序表长度
printf("\n"); //换行
for (int i = 0; i < L->length; i++) //向顺序表输入L->length个元素
{
printf("Please input the data:"); //提示输入顺序表元素
scanf("%d",&L->data[i]); //输入顺序表元素
}
printf("\n"); //换行
}
void Disp_List(SqList L) //打印顺序表
{
printf("The SqList is:"); //提示输出顺序表
for (int n = 0; n < L.length; n++) 遍历顺序表
{
printf("%d ", L.data[n]); //打印顺序表元素
}
printf("\n"); //换行
}
int Search_List(SqList L, ELEMTYPE e) //查找第一个值为e的元素并返回该元素下标
{
for (int n = 0; n < L.length; n++) //遍历顺序表
{
if (L.data[n] == e) //判断该元素是否与待查找的元素相同
return n; //相同则返回该元素在数组中的索引
}
return -1; //顺序表中找不到待查找的元素
}
void Insert_List(SqList* L, ELEMTYPE e, int index) //在数组下标为index处插入一个元素e
{
if (index > L->length || index < 0 || L->length == MAXSIZE)
//判断插入位置是否合理以及顺序表长度是否达到最大值
{
printf("insert failed\n"); //提示非法插入
return; //退出函数
}
for (int n = L->length-1; n >= index; n--)
//从待插入位置开始遍历顺序表
{
L->data[n+1] = L->data[n];
//将待插入位置元素及以后的元素均向后移一个位置
}
L->data[index] = e; //将元素e插入数组下标为index的位置
L->length++; //插入一个元素后顺序表长度加1
}
void Delete_List(SqList* L, int index) //删除数组下标为index处元素
{
if (index >= L->length || index < 0 || L->length == 0)
//判断删除位置是否合理以及顺序表是否为空
{
printf("delete failed\n"); //提示非法删除
return; //退出函数 }
for (int n = index; n < L->length-1; n++)
//从待删除位置开始遍历顺序表
{
L->data[n] = L->data[n+1];
//将待删除位置元素及以后的元素均向后移一个位置
}
L->length--; //删除一个元素后顺序表长度减1
}
void Destory_List(SqList* L) //销毁顺序表
{
if (L->data) //判断顺序表不为空
free(L->data); //释放数组所占空间
}
SqList* Copy_List(SqList L, SqList* New_L) //将顺序表L拷贝至顺序表New_L
{
New_L->length = L.length; //使顺序表New_L的长度与顺序表L的长度相等
for (int n = 0; n < L.length; n++) //遍历待拷贝顺序表L
{
New_L->data[n] = L.data[n]; //使New_L与L对应的元素相等
}
return New_L; //返回拷贝后的顺序表New_L
}
SqList* Bubble_Sort(SqList* L) //使用冒泡排序将顺序表L从小到大排序
{
if (L->length < 2) //判断顺序表L中元素个数是否小于2
return L; //顺序表L中元素个数小于2则不需排序
for (int i = L->length - 1; i > 0; i--)
//第i+1趟需要比较的元素数量比第i趟少1个
{
for (int j = 0; j < i; j++) //遍历数组未排序部分
{
if (L->data[j] > L->data[j + 1])
//判断第j个元素是否大于第j+1个元素
{
int tmp = L->data[j];
L->data[j] = L->data[j + 1];
L->data[j + 1] = tmp;
//如果第j个元素大于第j+1个元素,将第j个元素与第j+1个元素调换位置
}
}
}
return L; //返回排序后的顺序表
}
void Quick_Sort(ELEMTYPE* data,int begin,int end) //使用快速排序将顺序表L从小到大排序
{
if (begin >=end) //递归结束条件
return; //结束递归
ELEMTYPE tmp = data[begin]; //设置数组的第一个数为基准数
int i = begin; //i指向数组的第一个元素
int j = end; //j指向数组的最后一个元素
while (i != j) //i与j不相遇
{
while (data[j] >= tmp && j > i) //索引为j的元素大于基准数并且j与i未相遇
j--; //j向左挪动找第一个小于基准数的元素
while (data[i] <= tmp && j > i) //索引为i的元素小于基准数并且j与i未相遇
i++; //i向右挪动找第一个大于基准数的元素
if (j > i) //i与j还没相遇
{
int ret = data[j];
data[j] = data[i];
data[i] = ret;
//索引为i、j的元素调换位置
}
}
data[begin] = data[i];
data[i] = tmp;
//i与j相遇,因为j先挪动,所以此时索引为i的元素小于基准数,将基准数与索引为i的元素调换位置
Quick_Sort(data, begin, i - 1); //对基准数左侧子数组快速排序
Quick_Sort(data, j + 1, end); //对基准数右侧子数组快速排序
}
以下为测试函数
1.测试初始化函数Init_List;创建函数Creat_List;输出函数Disp_List.
#include"SqList.h" //调用头文件
int main(void) //main()函数
{
SqList L; //定义一个顺序表L
Init_List(&L); //调用Init_List函数将顺序表L初始化
Creat_List(&L); //调用Creat_List函数创建顺序表
Disp_List(L); //调用Disp_List函数打印顺序表
return 0; //返回值
}
2.测试查找函数Search_List.
#include"SqList.h" //调用头文件
int main(void) //main()函数
{
SqList L; //定义一个顺序表L
Init_List(&L); //调用Init_List函数将顺序表L初始化
Creat_List(&L); //调用Creat_List函数创建顺序表
int e; //定义待查找元素e
printf("Please input an element to find:"); //提示输入待查找元素
scanf("%d", &e); //输入待查找元素
printf("The index of this element is:%d", Search_List(L, e));
//调用Search_List函数查找顺序表中第一个值为e的元素,并打印该元素在数组中的下标
return 0; //返回值
}
3.测试插入函数Insert_List.
#include"SqList.h" //调用头文件
int main(void) //main()函数
{
SqList L; //定义一个顺序表L
Init_List(&L); //调用Init_List函数将顺序表L初始化
Creat_List(&L); //调用Creat_List函数创建顺序表
ELEMTYPE e; //定义待插入元素
printf("The element to be inserted is:"); //提示输入需要插入的元素
scanf("%d", &e); //输入需要插入的元素
int index; //定义待插入位置
printf("The index of the element to be inserted is:");
//提示输入需要插入的位置
scanf("%d", &index); //输入需要插入的位置
Insert_List(&L, e, index); //调用Insert_List函数插入元素e
Disp_List(L); //调用Disp_List函数打印顺序表
printf("The length of this SqList is:%d ", L.length); //输出顺序表长度
return 0; //返回值
}
4.测试删除函数Delete_List.
#include"SqList.h" //调用头文件
int main(void) //main()函数
{
SqList L; //定义一个顺序表L
Init_List(&L); //调用Init_List函数将顺序表L初始化
Creat_List(&L); //调用Creat_List函数创建顺序表
int index; //定义待删除元素的位置
printf("The index of the element to be deleted is:");
//提示输入需要删除元素的位置
scanf("%d", &index); //输入需要删除元素的位置
Delete_List(&L, index); //调用Delete_List函数删除元素
Disp_List(L); //调用Disp_List函数打印顺序表
printf("The length of this SqList is:%d ", L.length);
//输出顺序表长度
return 0; //返回值
}
5.测试打印函数Copy_List.
#include"SqList.h" //调用头文件
int main(void) //main()函数
{
SqList L,New_L; //定义一个顺序表L
Init_List(&L); //调用Init_List函数将顺序表L初始化
Init_List(&New_L); //调用Init_List函数将顺序表L初始化
Creat_List(&L); //调用Creat_List函数创建顺序表L
Copy_List(L, &New_L); //调用Copy_List函数拷贝顺序表L
Disp_List(New_L); //调用Disp_List函数打印拷贝的顺序表New_L
return 0; //返回值
}
6.测试冒泡排序函数Bubble_Sort
#include"SqList.h" //调用头文件
int main(void) //main()函数
{
SqList L; //定义一个顺序表L
Init_List(&L); //调用Init_List函数将顺序表L初始化
Creat_List(&L); //调用Creat_List函数创建顺序表
Disp_List(*Bubble_Sort(&L));
//调用Bubble_Sort函数将顺序表L冒泡排序并打印
return 0; //返回值
}
7.测试快速排序函数Quick_Sort
int main(void) //main()函数
{
SqList L; //定义一个顺序表L
Init_List(&L); //调用Init_List函数将顺序表L初始化
Creat_List(&L); //调用Creat_List函数创建顺序表
Quick_Sort(L.data,0,L.length-1); //调用Quick_Sort函数将顺序表L快速排序
Disp_List(L); //调用Disp_List函数将顺序表L打印
return 0; //返回值
}
四、实验结果及分析
测试函数 | 测试用例 | 运行结果 | |
Init_List Creat_List Disp_List | 5 5,4,3,2,1 | Please input the length:5 Please input the data:5 Please input the data:4 Please input the data:3 Please input the data:2 Please input the data:1 The SqList is:5 4 3 2 1 | |
Search_List | 6 | Please input an element to find:6 The index of this element is:-1 | |
2 | Please input an element to find:6 The index of this element is:3 | ||
Insert_List | 6 -1 | The element to be inserted is:6 The index of the element to be inserted is:-1 insert failed The SqList is:5 4 3 2 1 The length of this SqList is:5 | |
6 5 | The element to be inserted is:6 The index of the element to be inserted is:5 The SqList is:5 4 3 2 1 6 The length of this SqList is:6 | ||
6 6 | The element to be inserted is:6 The index of the element to be inserted is:6 insert failed The SqList is:5 4 3 2 1 The length of this SqList is:5 | ||
Delete_List | -1 | The index of the element to be deleted is:-1 delete failed The SqList is:5 4 3 2 1 The length of this SqList is:5 | |
0 | The index of the element to be deleted is:0 The SqList is:4 3 2 1 The length of this SqList is:4 | ||
5 | The index of the element to be deleted is:5 delete failed The SqList is:5 4 3 2 1 The length of this SqList is:5 | ||
Copy_List | 原顺序表为5 4 3 2 1 | The SqList is:5 4 3 2 1 | |
原顺序表为空 | The SqList is: | ||
Bubble_Sort | 原顺序表为5 4 3 2 1 | The SqList is:1 2 3 4 5 | |
原顺序表为空 | The SqList is: | ||
Quick_Sort | 原顺序表为5 4 3 2 1 | The SqList is:1 2 3 4 5 | |
原顺序表为空 | The SqList is: |