数据结构之顺序表(c语言版)
线性表是最简单的数据结构,而顺序表又是最简单的线性表,其基本思想是用一段地址连续的储存单元依次存储线性表的数据元素;
数组就是线性表,不过通常作为内置的数据结构,顺序表用数组为底层容器,优点在于可以动态增加删除元素,还可以自定义查找,可以说顺序表就是增强的数组。
顺序表1.0版本
这是1.0版本的顺序表,受到一位朋友的代码启发写出来的。当时确实是实现了顺序表的基本功能,不过代码冗余,不健壮。
#include<stdio.h>
#include<stdlib.h>
# define MAXSIZE 20//顺序表最大长度
typedef struct
{
/* data */
int data[MAXSIZE];
int len;
}SortList;
//初始化表
SortList *init(SortList *list){
list->len=0;
return list;
}
//创建一个表,传入顺序表指针,数组,数组大小
SortList *create_SortList(SortList *l,int a[],int size){
//初始长度为0
SortList *list=init(l);
//不能大于顺序表长度
if(size>MAXSIZE){
printf("数组长度大于顺序表最大长度,非法,程序中断");
exit(0);
}
//数组数据加入表中
for(int i=0;i<size;i++){
list->data[i]=a[i];
}
//长度等于数组元素的长度
list->len=size;
return list;
}
//判空
int is_Empty(SortList *list){
if(list->len!=0){
return 0;
}
return 1;
}
//长度
int length(SortList *list){
return list->len;
}
//判满
int is_Up(SortList *list){
if(list->len==MAXSIZE){
return 1;
}
return 0;
}
//遍历
void display(SortList *list){
for(int i=0;i<list->len;i++){
printf("The list[%d] is %d\n",i,list->data[i]);
}
printf("....................");
}
//按位查找
int queryI(SortList *list,int i){
if(i<1||i>list->len){
printf("关键词错误,无法查询,程序异常");
exit(0);
}
if(is_Empty(list)){
printf("顺序表空,不能查询,程序异常");
exit(0);
}
return list->data[i];
}
//按值查找
int queryE(SortList *list,int e){
for(int i=0;i<list->len;i++){
if(e==list->data[i]){
return 1;//存在
}
}
return 0;//不存在
}
//插入
int insert(SortList *list,int i,int e){//位置和值
if(i<1||i>MAXSIZE){
printf("插入位置错误,程序异常");
exit(0);
}
if(is_Up(list)){
printf("顺序表已满,不能插入,程序异常");
exit(0);
}
for(int l=list->len;l>i;l--){
list->data[l]=list->data[l-1];
}
list->data[i]=e;
list->len++;
return 1;
}
//删除
int delete(SortList *list,int i){//通过键删除元素,返回元素
if(i<1||i>list->len){
printf("关键词错误,无法删除,程序异常");
exit(0);
}
if(is_Empty(list)){
printf("顺序表空,不能删除,程序异常");
exit(0);
}
int e=list->data[i];
for(;i<list->len-1;i++){
list->data[i]=list->data[i+1];
}
list->len--;
return e;
}
//更新
int update(SortList *list,int i,int e){//把下标为i的元素替换为e
if(i<1||i>list->len){
printf("关键词错误,无法替换,程序异常");
exit(0);
}
if(is_Empty(list)){
printf("顺序表空,不能替换,程序异常");
exit(0);
}
list->data[i]=e;
return 1;
}
在主函数中测试一下:
int main(){
SortList *list;
int a[]={3,1,4,2,56,88,32,27,29,177,139};
int size=sizeof(a)/sizeof(int);
//将list初始化并加入元素
create_SortList(list,a,size);
//遍历元素
display(list);
insert(list,3,109);
display(list);
delete(list,9);
display(list);
printf("查询元素 %d",queryE(list,8));
}
得到结果:
The list[0] is 3
The list[1] is 1
The list[2] is 4
The list[3] is 2
The list[4] is 56
The list[5] is 88
The list[6] is 32
The list[7] is 27
The list[8] is 29
The list[9] is 177
The list[10] is 139
....................
The list[0] is 3
The list[1] is 1
The list[2] is 4
The list[3] is 109
The list[4] is 2
The list[5] is 56
The list[6] is 88
The list[7] is 32
The list[8] is 27
The list[9] is 29
The list[10] is 177
The list[11] is 139
....................
The list[0] is 3
The list[1] is 1
The list[2] is 4
The list[3] is 109
The list[4] is 2
The list[5] is 56
The list[6] is 88
The list[7] is 32
The list[8] is 27
The list[9] is 177
The list[10] is 139
....................
查询元素 0
顺序表2.0版本
2.0版本是后来对1.0版本的增强,相比于1.0版本,2.0的增强有以下部分:
1、把顺序指针作为全局静态变量
此时各个函数能直接访问到指针,不需要单独的参数接收指针。
2、把各个函数中对传入参数的判断单独作为一个函数
传入的索引参数,是需要判断是否非法的,把这部分直接封装成一个函数,其他函数需要判断的部分可以有这个函数替代,尤其是查询函数,下一点有说明。
3、各个函数中需要找元素位置的部分直接用查询函数替代
1.0中传入的索引,每次都要遍历查找位置,又是一部分冗余的代码,这部分直接可以调用查询函数来代替,极大地减少了代码量,查询函数中的判断函数也不用再写一遍了。。
时间久了,这部分代码丢了。。。。。不过在下一篇单链表中的2.0版本的代码还在,已经修改了,可以参考一下