顺序表的操作
欢迎评论区指正及讨论
头文件
#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 20 //定义最大存储内存为20
结构体的定义
typedef int ElemType;//数据元素的类型
typedef struct
{
ElemType a[MAXSIZE]; //定义顺序表元素数组
int length; //定义顺序表长度
}sqList; //顺序存储结构的结构体类型
sqList a, b, c; //变量a,b,c为sqList类型的三个变量
函数声明
void creat_list(sqList *L);
void out_list(sqList L);
void insert_sq(sqList* L, int i, ElemType e);
ElemType delete_sq(sqList* L, int i);
int locat_sq(sqList L, ElemType e);
主函数
int main()
{
int i, k, loc;
ElemType e, x;
char ch;
do //做顺序表的操作的循环
{
printf("\n 1.建立线性表");
printf("\n 2.插入元素");
printf("\n 3.删除元素");
printf("\n 4.查找元素");
printf("\n 0.结束程序运行");
printf("\n =============");
printf("\n 请输入要执行的操作\n");
scanf_s("%d", &k);
switch (k)//选择进行的顺序表操作
{
case 1:{creat_list(&a);//创建一个顺序表
out_list(a);}//输出顺序表
break;
case 2:{printf("\n请输入插入位置: ");
scanf_s("%d", &i);
printf("\n请输入插入的元素的值: ");
scanf_s("%d", &e);
insert_sq(&a, i, e);//&a 表示在函数中对链表进行改动会直接影响到原链表
out_list(a);}
break;
case 3:
{printf("\n请输入要删除元素的位置:");
scanf_s("%d", &i);
x = delete_sq(&a, i);//x返回删除元素的位置
if (x != -1)
printf("\n删除的元素为:%d\n", x);
out_list(a);}
break;
case 4: {printf("\n请输入要查找的元素值:");
scanf_s("%d", &e);
loc = locat_sq(a, e);//loc返回查找元素值的地址
if (loc == -1)
printf("\n未找到指定元素!");
else
printf("\n 已找到,元素的位置是:%d", loc);}
break;
}
}while (k != 0);//当用户输入0即退出顺序表操作的循环
printf("\n 按回车键,返回...\n");
ch = getchar();
}
建立线性表
void creat_list(sqList *L)
{
int i;
printf("请输入线性表的长度:");
scanf_s("%d", &L->length);
for (i = 0;i < L->length;i++)//从第1个数开始进行数据输入
{
printf("数据 %d=", i);
scanf_s("%d", &(L->a[i]));
//顺序表结构体中对数据元素的定义是数组形式的a【】,引用时也这么引用
}
}
输出线性表
void out_list(sqList L) //因为不要对L进行相互影响的操作,故参数直接用L
{
int i;
for (i = 0;i <= L.length - 1;i++) //从第一个元素开始输出所有数据
//i<l.length==l<=l.length-1
printf("%10d", L.a[i]);
}
在线性表的第i个位置插入元素e
void insert_sq(sqList* L, int i, ElemType e)
{
int j;
if (L->length == MAXSIZE) //还未插入元素时内存已满,则不能执行插入元素的操作
printf("线性表已满");
else if (L->length == 0)
printf("线性表为空表!");
else
{
L->length += 1;//顺序表的长度加一,因为表中所有元素都要后移一位
if (i<1 || i>L->length + 1) //考虑全面:插入位置不在表内的情况
printf("输入位置错误!\n");
else
{
/*先将第i个位置及以后的数据元素从最后一个开始依次往后移
如果从第i个元素后移会导致之后的元素值被覆盖,最后使得表内数据的值错误*/
for (j = L->length - 1;j >= i - 1;j--)
{
L->a[j + 1] = L->a[j];
}
L->a[i - 1] = e;//赋第i个位置的数据为e
}
}
}
删除第i个元素并返回其值
ElemType delete_sq(sqList* L, int i) //因为要返回值,故而函数的修饰符为elemtype
{
ElemType x ;
int j;
if (L->length == 0) //考虑全面:空表或第i个元素不在表内
printf("空表!\n");
else if (i<1 || i>L->length)
{
printf("输入位置错误\n");
x = -1;
}
else
{
x = L->a[i - 1]; //将第i个元素的值赋给x
for (j = i;j <= L->length - 1;j++) //j=i是因为第i个元素下标为i-1
L->a[j - 1] = L->a[j]; //将所有元素依次前移
L->length--;
}
return x;
}
查找值为e的元素并返回它的位置
int locat_sq(sqList L, ElemType e)
{
int i = 0;
//当i在顺序表内且第i-1个元素的值不为e时执行循环
while (i <= L.length - 1 && L.a[i] != e)
i++;
i = i + 1; //第i个元素下标为i-1
return i;
}
输出结果
*L 和 L 和 *L 和 *&L
第一种参数**“L”**是传结构体变量,但是函数操作之后,不能将新的数据带回(或者说是更新)
第二种参数**“L”* 是传结构体指针,调用函数之后,能将新的数据带回主调函数 ;因为它传递的是地址,在被调函数里对L的操作就是对主调函数里L的操作。
*&L是引用类型的指针,代表的是原指针,我们在函数中对指针的操作,都是直接对原指针的操作,无论是指针的内容,还是指针指向的地址,都会发生改变。
*L在函数中会改变不了所指向的地址
参数为*L时,数据的使用形式为:L->length
参数为 L时,数据的使用形式为:L.length