这是一个简单的目录
前言
本文介绍了数据结构中顺序表的定义和一些基本操作,欢迎大家观看~如有问题请随时告诉博主!
正文
1. 顺序表的定义
# define MAXSIZE 1000
// 设置int类型也可以用datatype表示
typedef int datatype;
/*
顺序表的结构体定义
1. 一个整型数组
2. 变量size记录长度
*/
typedef struct
{
datatype a[MAXSIZE];
int size;
}sequence_list;
2. 顺序表的基本操作
- 将顺序表置空
注意:
其实在声明一个顺序表后,其中的a[]和size中存放的值都是auto的,不是真正意义上的空。只不过我们一系列的增删改查的操作都是围绕size来操作的,所以看上去好像数组只有size这一部分范围。但其实size范围外(不超过MAXSIZE)的数组也是存在的,只不过没有被我们赋值利用罢了。
/*
函数名称:init
传入参数: 指向sequence_list型变量的指针变量lst
函数功能:将顺序表置空
函数返回值:空
*/
void init(sequence_list *lst)
{
lst->size = 0;
}
TIPS:下面的每一个操作我都加入了判断顺序表是否为空或者满的操作,这也是代表着我们要注重培养考虑特殊情况的意识!
- 在顺序表尾部插入值
/*
函数名称:append
传入参数:指向sequence_list型变量的指针变量lst,datatype型参数x
函数功能:将值x插入到顺序表的末尾
函数返回值:空
*/
void append(sequence_list *lst, datatype x)
{
// 判断顺序表是否还有多余的位置供我们插入数据
if(lst->size == MAXSIZE)
{
printf("顺序表是满的!");
exit(1);
}
lst -> a[lst->size] = x;
// 不要忘记将size + 1 !!!
lst -> size = lst->size + 1;
}
- 判断顺序表是否为空
/*
函数名称:empty
传入参数:指向sequence_list型变量的指针变量lst
函数功能:判断顺序表是否为空
函数返回值:int型,1表示非空,0表示空
*/
int empty(sequence_list *lst)
{
// 三目运算符(?:),用于条件求值。
// 若条件为真,则返回冒号前的值;为假返回冒号后的值。
return(lst->size == 0 ? 0:1);
}
- 在顺序表中找值为x的结点位置
/*
函数名称:find
传入参数:指向sequence_list型变量的指针变量lst,datatype型变量x
函数功能:返回要寻找的值x的下标
函数返回值:int型,表示要寻找值的下标,没找到则返回-1
*/
int find(sequence_list *lst, datatype x)
{
int i;
// 判断顺序表是否为空
if(lst->size == 0)
{
printf("顺序表是空的!");
exit(1);
}
for(i = 0; i <= lst->size; i++) if(lst->a[i] == x) return i;
return -1;
}
- 取顺序表中结点i的值
/*
函数名称:get_x
传入参数:指向sequence_list型变量的指针变量lst,datatype型变量pos
函数功能:返回结点pos的值
函数返回值:int型,表示结点pos对应的值
*/
datatype get_x(sequence_list *lst, datatype pos)
{
// 判断顺序表是否为空
if(lst->size == 0)
{
printf("顺序表是空的!\n");
exit(1);
}
// 判断位置pos是否合法
if(pos < 0 || pos >= lst->size)
{
printf("该位置不存在!\n");
exit(1);
}
return lst->a[pos];
}
- 在顺序表的pos位置插入值x
顺序表的插入操作在平均情况下需要移动一半的元素。
其时间复杂度为O(n)。
/*
函数名称:insert
传入参数:指向sequence_list型变量的指针变量lst,datatype型变量x, datatype型变量pos
函数功能:将值x插入到顺序表的pos位置
函数返回值:空
*/
void insert(sequence_list *lst, datatype x, datatype pos)
{
int i;
// 判断顺序表是否可供插入
if(lst->size == MAXSIZE)
{
printf("顺序表是满的!");
exit(1);
}
// 判断pos是否合法
// 注意这里pos是可以等于size的,因为等于size的时候相当于在a[]紧跟着插入数据,原数据与插入的数据之前不会有无意义的结点
if(pos < 0 || pos > lst->size)
{
printf("插入位置不存在!");
exit(1);
}
for(i = lst->size - 1; i >= pos; i--) lst->a[i + 1] = lst->a[i];
lst->a[pos] = x;
lst->size = lst->size + 1;
}
- 删除顺序表pos位置的值
顺序表的删除操作在平均情况下需要移动(n-1)/2个元素。
其时间复杂度为O(n)。
/*
函数名称:dele
传入参数:指向sequence_list型变量的指针变量lst,datatype型变量pos
函数功能:将位置为pos的值删除
函数返回值:空
*/
void dele(sequence_list *lst, datatype pos)
{
int i;
// 判断顺序表是否为空
if(lst->size == 0)
{
printf("该顺序表是空的!\n");
exit(1);
}
// 判断pos是否合法
if(pos < 0 || pos >= lst->size)
{
printf("要删除的位置不存在!\n");
exit(1);
}
for(i = pos + 1; i < lst->size; i++) lst->a[i - 1] = lst->a[i];
lst->size = lst->size - 1;
}
- 打印顺序表
/*
函数名称:display
传入参数:指向sequence_list型变量的指针变量lst
函数功能:将顺序表中存储的值打印出来
函数返回值:空
*/
void display(sequence_list *lst)
{
int i;
// 判断顺序表是否为空
if(lst->size == 0) printf("顺序表是空的!\n");
else
for(i = 0; i <= lst->size - 1; i++) printf("%d\n", lst->a[i]);
}
3. 上述基本操作函数的调用实现
int main()
{
sequence_list lst, *p;
// 令p指向lst,然后将p作为传入函数的参数,避免形参多一次拷贝,提高效率
p = &lst;
// 调用init(),将顺序表初始化为空
init(p);
// 调用empty(),判断顺序表是否为空
if(empty(p)) printf("顺序表不是空的。\n");
else printf("顺序表是空的。\n");
printf("初始化为空后size = :%d\n", lst.size);
int i, ans1, ans2;
// 调用insert()插入数据
for(i = 0; i < 10; i++) insert(p, i, i);
// 调用find()来寻找给定数据的位置
ans1 = find(p, 5);
printf("值为5的结点的位置pos = %d\n", ans1);
// 调用append()插入数据
for(i = 10; i < 20; i++) append(p, i);
// 再次调用empty()判断顺序表是否为空
if(empty(p)) printf("顺序表不是空的。\n");
else printf("顺序表是空的。\n");
// 调用get_x()寻找指定位置对应的值
ans2 = get_x(p, 15);
printf("位置为15的结点的值 = %d\n", ans2);
printf("执行删除操作前的顺序表:\n");
// 调用display()查看未进行删除操作前的顺序表
display(p);
// 调用dele()删除指定位置的结点
dele(p, 10);
// 再次调用display()查看进行删除操作后的顺序表
printf("执行删除pos=10操作后的顺序表:\n");
display(p);
return 0;
}