文章目录
前言
编程实现线性表顺序存储下的基本操作:
1.初始化
2.插入元素
3.删除元素
4.获取第i个元素
5.判断元素是否存在
6.获取某个元素的下一个元素;
7.获取某个元素的前一个元素;
1.编程实现线性表顺序存储下的基本操作
代码如下(示例):
//Author:北硝 Date:2023.3.29
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#include<string.h>
//本程序主要功能说明:
// 顺序存储下,线性表基本操作实现
// 1.初始化、2.插入、3.删除、4.获取i元素、5.判断元素是否存在6.获取某个元素的下一个元素7.获取某个元素的前一个元素
#define LIST_INIT_SIZE 100
#define LISTINCREMENT 10
//程序返回结构 定义 1成功 0失败
#define Status int
#define OK 1
#define ERROR 0
#define OVERFLOW -2 //申请不到内存时 用-2表示
//自定义的数据元素,
typedef struct {
char name[10]; //假设暂时只用姓名和手机号
char phone[20]; //假设暂时只用姓名和手机号
} ElemType;
typedef struct {
ElemType* elem;
int length;
int listsize;//当前表的最大容量
} SqList;
//C 语言里面 参数使用引用&时,编译不过
//Status InitList_Sq(SqList &L) {
// L->elem = (ElemType*)malloc(LIST_INIT_SIZE
// * sizeof(ElemType));
// if (!L.Elem) {
// exit(OVERFLOW);
// }
// L.Length = 0;
// L.Listsize = LIST_INIT_SIZE;
// return OK;
//}
//基本操作1: 顺序存储下,线性表初始化
//把传引用改为 传*指针,
Status InitList_Sq(SqList * L) {
L->elem = (ElemType*)malloc(LIST_INIT_SIZE
* sizeof(ElemType));
if (!L->elem) {
return OVERFLOW;
}
L->length = 0;
L->listsize = LIST_INIT_SIZE;
printf("线性表L初始化成功!\r\n");
return OK;
}
//基本操作2:顺序存储下,线性表插入元素
Status ListInsert_Sq(SqList* L, int i, ElemType e) {
ElemType* q = NULL;
ElemType* p = NULL;
//参数合法性检查
if (i < 1 || i > L->length + 1) {
printf("传入的插入位置非法\r\n");
return ERROR;
}
//插入前判断一下已分配的空间是否已经满。
if (L->length >= L->listsize) {
ElemType* newbase = (ElemType*)realloc(L->elem,
(L->listsize + LISTINCREMENT) * sizeof(ElemType));
if (!newbase) {
exit(OVERFLOW);
}
L->elem = newbase;
L->listsize = L->listsize + LISTINCREMENT;
}
//怎么理解?
//L.elem[i-1]是第i个元素
//&(L.elem[i-1]) 是要插入的位置,
q = &(L->elem[i - 1]);
//取当前最后一个元素的位置
for (p = &(L->elem[L->length - 1]); p >= q; --p) {
*(p + 1) = *p;//插入位置及之后的元素依次右移动
}
*q = e;//目标位置插入e
L->length++;//表长度更改
return OK;
}
//基本操作3:顺序存储下,线性表删除元素
Status ListDelete_Sq(SqList* L, int i) {
ElemType* q = NULL;
ElemType* p = NULL;
if ((i < 1) || (i > L->length)) {
printf("传入的删除位置非法\r\n");
return ERROR;
}
//p取到被删除元素的位置
p = &(L->elem[i - 1]);
q = L->elem + L->length - 1;//表尾元素的位置
for (++p; p <= q; ++p) {
*(p - 1) = *p;
}
L->length--;
return OK;
}
//基本操作4:顺序存储下,线性表获取第i个元素
Status GetElem_Sq(SqList L, int i, ElemType *e) {
if ((i < 1) || (i > L.length)) {
printf("传入查询的位置非法\r\n");
return ERROR;
}
//改变e的内容
*e = L.elem[i - 1];//或者*(L.elem + i -1)
return OK;
}
int ElemIsEqual(ElemType e1, ElemType e2);
//基本操作5:顺序存储下,线性表 判断元素e是否存在
// 存在时,返回下标位置
// 不存在时,返回0
int LocateElem_Sq(SqList L, ElemType e) {
ElemType temp_e;//接收遍历时候的元素
//遍历一遍L,依次比较
for (int i = 1; i <= L.length; i++) {
temp_e = L.elem[i - 1];
if (ElemIsEqual(temp_e, e)) {
return i; //直接返回序号
}
}
//遍历完还没有找到就返回 0
return 0;
}
//基本操作6:顺序存储下,线性表 获取某个元素的下一个元素
Status NextElem(SqList L,int cur_e, ElemType *next_e) {
if ((cur_e < 0) || (cur_e > L.length-1)) {
printf("传入查询的位置非法\r\n");
return ERROR;
}
*next_e = L.elem[cur_e];
return OK;
}
//基本操作7:顺序存储下,线性表 获取某个元素的前一个元素
Status PriorElem(SqList L, int cur_e, ElemType* pre_e) {
if ((cur_e < 2) || (cur_e > L.length + 1)) {
printf("传入查询的位置非法\r\n");
return ERROR;
}
*pre_e = L.elem[cur_e-2];
return OK;
}
//
// 以下几个函数是自定义的, 用于打印数据元素和界面的,不属于线性表的基本操作
//功能:打印某个数据元素
void pintElem(ElemType e) {
printf("{%s, %s}\r\n", e.name,e.phone);
}
//功能:遍历打印一下当前的线性表:
void printList(SqList L) {
if (L.length == 0) {
return;//为空时可以不用展示
}
printf("当前线性表所有元素为:\r\n");
for (int i = 1; i <= L.length; i++) {
//打印每一个元素
pintElem(L.elem[i-1]);
}
printf("\r\n\n");//打印完 跟后面内容最好分隔开
}
//功能:打印主界面菜单
void printMenu(void) {
printf("\t\t*****顺序存储下,线性表的基本操作语句实现*****\r\n");
printf("\t\t*********** 1. 插入元素e ***********\r\n");
printf("\t\t*********** 2. 删除第i个元素 ***********\r\n");
printf("\t\t*********** 3. 获取第i个元素 ***********\r\n");
printf("\t\t*********** 4. 判断元素e是否存在 ***********\r\n");
printf("\t\t*********** 5. 获取某个元素的下一个元素 ***********\r\n");
printf("\t\t*********** 6. 获取某个元素的前一个元素 ***********\r\n");
}
//从控制台输入获取某个元素e
void getElemFormConsole(ElemType *e) {
printf("请输入姓名 手机号(回车表示结束):\r\n");
scanf_s("%s", e->name, 20);
scanf_s("%s", e->phone, 20);
}
//判断两个元素是否相等:
//相等返回1 不相等返回0
int ElemIsEqual(ElemType e1, ElemType e2) {
if (strcmp(e1.name, e2.name) == 0 &&
strcmp(e1.phone, e2.phone) == 0) {
return 1;
}
return 0;
}
//菜单的功能1:插入:
//就是从控制台接收要插入的位置i 和 元素e 并调用基本功能插入
void FunctionNo1(SqList *L) {
ElemType e;//用于接收要插入的元素e
int i;//用于接收要插入的位置
system("cls");//清屏
printf("请输入要插入的位置(回车表示结束):\r\n");
scanf_s("%d", &i, 6);
getElemFormConsole(&e);
//调用基本操作语句 插入
int result = ListInsert_Sq(L, i, e);
if (result != OK) {
printf("插入操作失败!");
system("pause");
}
}
//菜单的功能2:删除:
//就是从控制台接收要删除的位置i 并调用基本功能删除
void FunctionNo2(SqList* L) {
int i;//用于接收要删除的位置
system("cls");//清屏
printf("请输入要删除的位置(回车表示结束):\r\n");
scanf_s("%d", &i, 6);
//调用基本操作语句 删除
int result = ListDelete_Sq(L, i);
if (result != OK) {
printf("删除操作失败!");
system("pause");
}
}
//菜单的功能3:获取第i个元素
//就是从控制台接收要 查询的序号, 并调用基本功能获取第i元素
void FunctionNo3(SqList L) {
int i;//用于接收要查询的序号
ElemType e;//用于接收查询到的元素
system("cls");//清屏
printf("请输入要查询的位置(回车表示结束):\r\n");
scanf_s("%d", &i, 6);
//调用基本操作语句 获取第i元素
int result = GetElem_Sq(L, i, &e);
if (result != OK) {
printf("查询操作失败!");
system("pause");
return;
}
//查出来打印一下
printf("\r\n查询出来的第 %d 个元素为:", i);
pintElem(e);
system("pause");//暂停一下 让用户能看到查询的结果,再下一步
}
//菜单的功能4:判断元素e是否存在
//就是从控制台接收要 查询的元素,并调用基本功能判断是否存在
void FunctionNo4(SqList L) {
ElemType e;//用于接收要查询的元素e
system("cls");//清屏
//接收要查询的元素e
getElemFormConsole(&e);
//调用基本操作语句 LocateElem_Sq
int result = LocateElem_Sq(L, e);
if (!result) {
//不存在
printf("所找的元素e 不存在!");
}
else {
printf("所找的元素e 存在! 位置是第%d个", result);
}
system("pause");
}
//菜单的功能5:获取某个元素的下一个元素
//就是从控制台接收要 查询的序号, 并调用基本功能获取某个元素的下一个元素
void FunctionNo5(SqList L) {
int i;//用于接收要查询的序号
ElemType e;//用于接收查询到的元素
system("cls");//清屏
printf("请输入要查询的位置(回车表示结束):\r\n");
scanf_s("%d", &i, 6);
//调用基本操作语句 获取第i元素
int result = NextElem(L, i, &e);
if (result != OK) {
printf("查询操作失败!");
system("pause");
return;
}
//查出来打印一下
printf("\r\n查询出来的第 %d 个元素为:", i+1);
pintElem(e);
system("pause");//暂停一下 让用户能看到查询的结果,再下一步
}
//菜单的功能6:获取某个元素的前一个元素
//就是从控制台接收要 查询的序号, 并调用基本功能获取某个元素的前一个元素
void FunctionNo6(SqList L) {
int i;//用于接收要查询的序号
ElemType e;//用于接收查询到的元素
system("cls");//清屏
printf("请输入要查询的位置(回车表示结束):\r\n");
scanf_s("%d", &i, 6);
//调用基本操作语句 获取第i元素
int result = PriorElem(L, i, &e);
if (result != OK) {
printf("查询操作失败!");
system("pause");
return;
}
//查出来打印一下
printf("\r\n查询出来的第 %d 个元素为:", i- 1);
pintElem(e);
system("pause");//暂停一下 让用户能看到查询的结果,再下一步
}
//自定义几个功能代码
#define FUNCTION01 1
#define FUNCTION02 2
#define FUNCTION03 3
#define FUNCTION04 4
#define FUNCTION05 5
#define FUNCTION06 6
void main() {
SqList L; //定义一个线性表L;
int selectFun = 0;
//第一步:初始化线性表;
InitList_Sq(&L);//注意是传的L地址
//第二步:用户按任意键后继续 主要是让用户知道表已经初始化好了
system("pause");//用户按任意键继续下一步
while (1) {
system("cls");//清屏
printList(L);//先展示一下当前的表内容
printMenu();//展示一下 主菜单
printf("请输入你的选择:(回车表示结束)\r\n");
scanf_s("%d", &selectFun, 6);
switch (selectFun) {
case FUNCTION01:
//选择功能1时
FunctionNo1(&L);
break;
case FUNCTION02:
//选择功能2时
FunctionNo2(&L);
break;
case FUNCTION03:
//选择功能3时
FunctionNo3(L);
break;
case FUNCTION04:
//选择功能4时
FunctionNo4(L);
break;
case FUNCTION05:
//选择功能5时
FunctionNo5(L);
break;
case FUNCTION06:
//选择功能6时
FunctionNo6(L);
break;
default:;
}
}
}
总结
编程实现线性表顺序存储下的七个基本操作