一、任务概述
大家好!今天我将与大家分享关于顺序表的基本概念以及如何使用C语言实现顺序表的各种操作。顺序表是一种线性数据结构,它在计算机内存中以数组的形式保存数据元素,并通过数据元素物理存储的相邻关系来反映它们逻辑上的相邻关系。
首先,我们来看一下顺序表的基本定义和特点。顺序表是在计算机内存中以数组的形式保存的线性表,其特点是线性表中的数据元素在物理存储上是连续的,这样可以方便地进行随机存取操作。
接下来,我们将讨论如何使用C语言来实现顺序表的操作。这里我们提供了一个名为SqListDemo.c的程序示例,包含了创建空顺序表、获取顺序表元素、定位目标元素、插入元素、删除元素、更新元素和输出顺序表全部元素等基本操作。
在这个程序中,我们首先定义了一个顺序表类型的结构体,其中包含指向元素数组的指针、顺序表长度和存储容量等信息。然后,我们实现了各个操作函数,包括InitList()用于创建空顺序表,GetListElem()用于获取顺序表第i个元素,LocateListElem()用于定位目标元素,InsertListElem()用于在顺序表第i个位置插入元素,DeleteListElem()用于删除顺序表第i个元素,UpdateListElem()用于修改顺序表第i个元素,PrintList()用于输出顺序表全部元素。
最后,我们编写了一个主函数main(),通过一个while循环来实现顺序表操作演示。用户可以选择不同的功能号来进行相应的操作,如创建空顺序表、输出顺序表、查询元素、插入元素、删除元素、更新元素等。
希望通过这次分享,大家能够对顺序表有更深入的理解,并掌握如何使用C语言来实现顺序表的各种操作。感谢大家的关注与参与,期待在接下来的时间里能与大家分享更多有关数据结构的知识和经验。
二、顺序表概念与特点
顺序表是一种线性数据结构,它在计算机内存中以数组的形式保存数据元素,并通过数据元素物理存储的相邻关系来反映它们逻辑上的相邻关系。
(一)概念
顺序表是一种线性表(也称为一维数组)的实现方式。线性表是一个有限序列,其中的元素具有相同的数据类型,且元素之间是线性关系,即除了第一个和最后一个元素外,每个元素都有一个直接前驱和一个直接后继。顺序表中的元素是按照其在列表中的位置依次存储的,这种存储方式使得我们可以快速地访问任何位置的元素。
(二)特点
- 随机存取: 由于顺序表使用数组进行存储,所以可以方便地对任意位置的元素进行随机存取操作,时间复杂度为O(1)。
- 存储密度高: 顺序表只占用了一组连续的存储空间,不需要额外的空间来存储指针等附加信息,因此存储密度较高。
- 易于实现: 顺序表的实现相对简单,只需要一个指向数组的指针即可表示整个顺序表。
- 动态扩展困难: 如果需要增加顺序表的容量,可能会涉及到大量的数据移动,这是顺序表的一个缺点。为了解决这个问题,通常会预先分配比实际需求更大的存储空间,或者采用动态扩展技术,如动态数组。
- 插入和删除效率低: 在顺序表中插入或删除元素时,可能需要移动后续的元素来保持连续性,因此插入和删除操作的时间复杂度通常为O(n),其中n是顺序表的长度。
顺序表广泛应用于各种编程语言中,特别是在处理大量数据时,其高效的随机存取性能非常有用。
三、C语言实现顺序表
如何使用C语言来实现顺序表的操作。这里我们提供了一个名为SqListDemo.c的程序示例,包含了创建空顺序表、获取顺序表元素、定位目标元素、插入元素、删除元素、更新元素和输出顺序表全部元素等基本操作。
(一)编写程序,实现功能
/*
功能:创建顺序表并进行增删改查操作
作者:华卫
日期:2018年2月5日
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
// 定义符号常量
#define LIST_INIT_SIZE 50
#define LISTINCREMENT 10
#define OK 1
#define ERROR 0
#define OVERFLOW -2
// 定义元素类型
typedef int ElemType;
// 定义顺序表类型
typedef struct {
ElemType *elem; // 顺序表元素
int length; // 顺序表长度
int listsize; // 顺序表存储容量
} SqList;
// 构造空顺序表
int InitList(SqList *L)
{
// 获取顺序表基址
L->elem = (ElemType *) malloc(LIST_INIT_SIZE * sizeof(ElemType));
// 存储空间分配失败
if (!L->elem) return ERROR;
// 空表长度为0
L->length = 0;
// 分配给空表的存储容量
L->listsize = LIST_INIT_SIZE;
// 初始化成功
return OK;
}
// 获取顺序表第i个元素
ElemType GetListElem(SqList *L, int i)
{
// 检查i的合法性
if (i < 1 || i > L->length)
return ERROR;
else
return L->elem[i-1];
}
// 定位目标元素在顺序表中位置
int LocateListElem(SqList *L, ElemType e)
{
int i = 1;
// 定义指针p,指向第一个元素
ElemType *p = L->elem;
// 目标元素依次与顺序表元素比较
while (*p != e && i <= L->length)
{
i++;
p++;
}
if (i > L->length)
return 0;
else
return i;
}
// 在顺序表第i个位置插入元素
int InsertListElem(SqList *L, int i, ElemType e)
{
int k;
// 位置合法性判断
if (i < 1 || i > L->length + 1) return ERROR;
// 顺序表空间满,按增量重新分配
if (L->length >= L->listsize)
{
// 增加LISTINCREMENT个元素元素,获取顺序表新基址
L->elem = (ElemType *)realloc(L->elem, (L->listsize + LISTINCREMENT) * sizeof(ElemType));
if (!L->elem) return ERROR;
// 按增量修改存储空间大小
L->listsize += LISTINCREMENT;
}
// 元素后移1位
for (k = L->length - 1; k >= i - 1; k--)
L->elem[k + 1] = L->elem[k];
// 插入元素
L->elem[i-1] = e;
// 顺序表长度加1
L->length++;
// 插入成功
return OK;
}
// 删除顺序表第i个元素
int DeleteListElem(SqList *L, int i)
{
int k;
// 判断位置合法性
if (i < 1 || i >L->length) return ERROR;
// 元素前移1位
for (k = i; k <= L->length; k++)
L->elem[k-1] = L->elem[k];
// 顺序表长度减1
L->length--;
// 删除成功
return OK;
}
// 修改顺序表第i个元素
int UpdateListElem(SqList *L, int i, ElemType e)
{
// 判断位置合法性
if (i < 1 || i >L->length) return ERROR;
// 修改第i个元素值
L->elem[i-1] = e;
// 修改成功
return OK;
}
// 输出顺序表全部元素
void PrintList(SqList *L)
{
int i;
if (L->length == 0)
printf("\n顺序表为空!\n\n");
else
for (i = 1; i <= L->length; i++)
printf("%d ", L->elem[i-1]);
printf("\n");
}
int main()
{
int i, choice, position;
ElemType data, elem;
int isRunning = 1;
SqList *pl = (SqList *)malloc(sizeof(SqList));
while(isRunning)
{
printf("======顺序表操作演示=======\n");
printf("1. 创建一个空的顺序表\n");
printf("2. 输出顺序表的全部数据\n");
printf("3. 查询顺序表某个位置的数据\n");
printf("4. 查询数据在顺序表中的位置\n");
printf("5. 向顺序表指定位置插入数据\n");
printf("6. 删除顺序表指定位置的数据\n");
printf("7. 更新顺序表指定位置的数据\n");
printf("8. 退出顺序表操作演示程序\n");
printf("===========================\n");
printf("\n输入1-8,选择所需功能号:");
scanf("%d", &choice);
printf("\n您选择的功能号为:%d\n", choice);
switch(choice)
{
case 1:
if (InitList(pl))
printf("\n顺序表创建成功!\n\n");
else
printf("\n顺序表创建失败!\n\n");
system("pause");
break;
case 2:
PrintList(pl);
system("pause");
break;
case 3:
printf("i=");
scanf("%d", &i);
elem = GetListElem(pl, i);
if (elem)
printf("L[%d]=%d\n\n", i, elem);
else
printf("输入的位置不合法!");
system("pause");
break;
case 4:
printf("data=");
scanf("%d", &data);
position = LocateListElem(pl, data);
if (position)
printf("%d is at [%d] of the list.\n\n", data, position);
else
printf("%d is not in the list.\n\n", data);
system("pause");
break;
case 5:
printf("i,data=");
scanf("%d,%d", &i, &data);
if (InsertListElem(pl, i, data))
printf("\n数据插入成功!\n\n");
else
printf("\n数据插入失败!\n\n");
system("pause");
break;
case 6:
printf("i=");
scanf("%d", &i);
if (DeleteListElem(pl, i))
printf("\n数据删除成功!\n\n");
else
printf("\n数据删除失败!\n\n");
system("pause");
break;
case 7:
printf("i,data=");
scanf("%d,%d", &i, &data);
if (UpdateListElem(pl, i, data))
printf("\n数据更新成功!\n\n");
else
printf("\n数据更新失败!\n\n");
system("pause");
break;
case 8:
isRunning = 0;
break;
}
}
printf("\n谢谢使用本程序~");
return 0;
}
(二)运行程序,查看结果
======顺序表操作演示=======
1. 创建一个空的顺序表
2. 输出顺序表的全部数据
3. 查询顺序表某个位置的数据
4. 查询数据在顺序表中的位置
5. 向顺序表指定位置插入数据
6. 删除顺序表指定位置的数据
7. 更新顺序表指定位置的数据
8. 退出顺序表操作演示程序
===========================
输入1-8,选择所需功能号:1
您选择的功能号为:1
顺序表创建成功!
请按任意键继续. . .
======顺序表操作演示=======
1. 创建一个空的顺序表
2. 输出顺序表的全部数据
3. 查询顺序表某个位置的数据
4. 查询数据在顺序表中的位置
5. 向顺序表指定位置插入数据
6. 删除顺序表指定位置的数据
7. 更新顺序表指定位置的数据
8. 退出顺序表操作演示程序
===========================
输入1-8,选择所需功能号:5
您选择的功能号为:5
i,data=1,100
数据插入成功!
请按任意键继续. . .
======顺序表操作演示=======
1. 创建一个空的顺序表
2. 输出顺序表的全部数据
3. 查询顺序表某个位置的数据
4. 查询数据在顺序表中的位置
5. 向顺序表指定位置插入数据
6. 删除顺序表指定位置的数据
7. 更新顺序表指定位置的数据
8. 退出顺序表操作演示程序
===========================
输入1-8,选择所需功能号:5
您选择的功能号为:5
i,data=2,300
数据插入成功!
请按任意键继续. . .
======顺序表操作演示=======
1. 创建一个空的顺序表
2. 输出顺序表的全部数据
3. 查询顺序表某个位置的数据
4. 查询数据在顺序表中的位置
5. 向顺序表指定位置插入数据
6. 删除顺序表指定位置的数据
7. 更新顺序表指定位置的数据
8. 退出顺序表操作演示程序
===========================
输入1-8,选择所需功能号:5
您选择的功能号为:5
i,data=2,250
数据插入成功!
请按任意键继续. . .
======顺序表操作演示=======
1. 创建一个空的顺序表
2. 输出顺序表的全部数据
3. 查询顺序表某个位置的数据
4. 查询数据在顺序表中的位置
5. 向顺序表指定位置插入数据
6. 删除顺序表指定位置的数据
7. 更新顺序表指定位置的数据
8. 退出顺序表操作演示程序
===========================
输入1-8,选择所需功能号:5
您选择的功能号为:5
i,data=2,140
数据插入成功!
请按任意键继续. . .
======顺序表操作演示=======
1. 创建一个空的顺序表
2. 输出顺序表的全部数据
3. 查询顺序表某个位置的数据
4. 查询数据在顺序表中的位置
5. 向顺序表指定位置插入数据
6. 删除顺序表指定位置的数据
7. 更新顺序表指定位置的数据
8. 退出顺序表操作演示程序
===========================
输入1-8,选择所需功能号:2
您选择的功能号为:2
100 140 250 300
请按任意键继续. . .
======顺序表操作演示=======
1. 创建一个空的顺序表
2. 输出顺序表的全部数据
3. 查询顺序表某个位置的数据
4. 查询数据在顺序表中的位置
5. 向顺序表指定位置插入数据
6. 删除顺序表指定位置的数据
7. 更新顺序表指定位置的数据
8. 退出顺序表操作演示程序
===========================
输入1-8,选择所需功能号:3
您选择的功能号为:3
i=3
L[3]=250
请按任意键继续. . .
======顺序表操作演示=======
1. 创建一个空的顺序表
2. 输出顺序表的全部数据
3. 查询顺序表某个位置的数据
4. 查询数据在顺序表中的位置
5. 向顺序表指定位置插入数据
6. 删除顺序表指定位置的数据
7. 更新顺序表指定位置的数据
8. 退出顺序表操作演示程序
===========================
输入1-8,选择所需功能号:4
您选择的功能号为:4
data=250
250 is at [3] of the list.
请按任意键继续. . .
======顺序表操作演示=======
1. 创建一个空的顺序表
2. 输出顺序表的全部数据
3. 查询顺序表某个位置的数据
4. 查询数据在顺序表中的位置
5. 向顺序表指定位置插入数据
6. 删除顺序表指定位置的数据
7. 更新顺序表指定位置的数据
8. 退出顺序表操作演示程序
===========================
输入1-8,选择所需功能号:4
您选择的功能号为:4
data=1000
1000 is not in the list.
请按任意键继续. . .
======顺序表操作演示=======
1. 创建一个空的顺序表
2. 输出顺序表的全部数据
3. 查询顺序表某个位置的数据
4. 查询数据在顺序表中的位置
5. 向顺序表指定位置插入数据
6. 删除顺序表指定位置的数据
7. 更新顺序表指定位置的数据
8. 退出顺序表操作演示程序
===========================
输入1-8,选择所需功能号:6
您选择的功能号为:6
i=3
数据删除成功!
请按任意键继续. . .
======顺序表操作演示=======
1. 创建一个空的顺序表
2. 输出顺序表的全部数据
3. 查询顺序表某个位置的数据
4. 查询数据在顺序表中的位置
5. 向顺序表指定位置插入数据
6. 删除顺序表指定位置的数据
7. 更新顺序表指定位置的数据
8. 退出顺序表操作演示程序
===========================
输入1-8,选择所需功能号:2
您选择的功能号为:2
100 140 300
请按任意键继续. . .
======顺序表操作演示=======
1. 创建一个空的顺序表
2. 输出顺序表的全部数据
3. 查询顺序表某个位置的数据
4. 查询数据在顺序表中的位置
5. 向顺序表指定位置插入数据
6. 删除顺序表指定位置的数据
7. 更新顺序表指定位置的数据
8. 退出顺序表操作演示程序
===========================
输入1-8,选择所需功能号:7
您选择的功能号为:7
i,data=2,1000
数据更新成功!
请按任意键继续. . .
======顺序表操作演示=======
1. 创建一个空的顺序表
2. 输出顺序表的全部数据
3. 查询顺序表某个位置的数据
4. 查询数据在顺序表中的位置
5. 向顺序表指定位置插入数据
6. 删除顺序表指定位置的数据
7. 更新顺序表指定位置的数据
8. 退出顺序表操作演示程序
===========================
输入1-8,选择所需功能号:2
您选择的功能号为:2
100 1000 300
请按任意键继续. . .
======顺序表操作演示=======
1. 创建一个空的顺序表
2. 输出顺序表的全部数据
3. 查询顺序表某个位置的数据
4. 查询数据在顺序表中的位置
5. 向顺序表指定位置插入数据
6. 删除顺序表指定位置的数据
7. 更新顺序表指定位置的数据
8. 退出顺序表操作演示程序
===========================
输入1-8,选择所需功能号:8
您选择的功能号为:8
谢谢使用本程序~
四、实验总结
实验名称:顺序表的C语言实现
实验目的: 本次实验旨在让学生深入理解顺序表的概念和特点,并掌握使用C语言实现顺序表的基本操作,包括创建空顺序表、获取顺序表元素、定位目标元素、插入元素、删除元素、更新元素以及输出顺序表全部元素等。
实验内容与过程:
- 理解顺序表的概念和特点。
- 学习并理解C语言实现顺序表的代码。
- 运行程序,观察和分析程序运行结果。
- 根据需要修改程序,进行扩展实验。
实验收获: 通过这次实验,我深刻理解了顺序表作为线性数据结构的特点和优势。在实践中,我掌握了如何使用C语言来实现顺序表的各种基本操作,这不仅增强了我的编程技能,也加深了我对数据结构的理解。
实验中遇到的问题及解决方法: 在实验过程中,我遇到了一些问题,如对顺序表存储容量的理解不深、对C语言指针操作不够熟练等。为了解决这些问题,我查阅了相关资料,向老师和同学请教,并通过多次实践逐渐掌握了这些知识。
实验反思与改进意见: 虽然我已经成功完成了本次实验,但我认为还有许多可以改进的地方。例如,我可以进一步优化代码,使其更加简洁易懂;我还可以尝试使用其他编程语言来实现顺序表,以拓宽自己的视野。
总的来说,这次实验让我受益匪浅。我相信,随着不断的实践和学习,我将在数据结构和编程领域取得更大的进步。
五、拓展练习
运行程序后,我们可以看到一个简单的顺序表操作演示。通过输入不同的功能号,我们可以实现以下操作:
1. 创建一个空的顺序表
2. 输出顺序表的全部数据
3. 查询顺序表某个位置的数据
4. 查询数据在顺序表中的位置
5. 向顺序表指定位置插入数据
6. 删除顺序表指定位置的数据
7. 更新顺序表指定位置的数据
8. 退出顺序表操作演示程序
这个程序很好地展示了顺序表的基本操作,但是我们还可以对其进行一些拓展,以增加其功能和实用性。
例如,我们可以添加一个排序功能,让用户可以对顺序表进行升序或降序排列。这可以通过选择排序、冒泡排序、快速排序等算法来实现。
此外,我们还可以添加一个查找功能,允许用户根据给定条件(如大于、小于、等于某个值)在顺序表中查找元素。这可以通过二分查找、线性查找等算法来实现。
最后,我们还可以考虑添加一个统计功能,用于计算顺序表中的元素个数、最大值、最小值、平均值等信息。这将使我们的顺序表更加实用,并为用户提供更多有用的信息。
总之,通过对这个程序进行适当的拓展和改进,我们可以使其更加丰富和完善,更好地满足用户的需求。