#include <iostream>
#include <windows.h>
#include <stdlib.h>
#define LIST_INIT_SIZE 100//SqList存储空间的初始分量
#define LISTINCREMENT 10//SqList存储空间的分配增量
//1:定义顺序表结构体数据类型
typedef struct {
int *elem;//存储空间首地址
int length;//当前长度
int sqListSize;//当前分配的存储容量(sizeof(int)为单位)
}SqList;
//2:定义顺序表的初始化函数
bool initSqList(SqList &L){
L.elem = (int *)calloc(LIST_INIT_SIZE,sizeof(int));
if(L.elem == NULL){
printf("存储分配失败\n");
exit(1);//程序终止
}
L.length = 0;
L.sqListSize = LIST_INIT_SIZE;
return true;
}
//3:定义顺序表的初始数据输入函数
bool initInputSqList(SqList &L){
int count = 0;//count为初始填入的数据个数
printf("input of count:");
scanf("%d",&count);
if(count>=L.sqListSize){
printf("存储空间不足\n");
exit(1);
}
for(int i=0;i<count;i++){
printf("input of %d elem:",i+1);
scanf("%d",L.elem+i);
L.length++;
}
return true;
}
//4:定义顺序表的遍历函数
bool traverseSqList(SqList L){
if(L.length == 0){
printf("顺序表为空表\n");
return false;
}
printf("==========================\n");
for(int i=0;i<L.length;i++){
printf("SqList 第%d个数据元素:%d\n",i+1,L.elem[i]);
}
printf("==========================\n");
return true;
}
//5:定义顺序表查询的数据元素的比较规则函数
bool compare(int elem,int e){//elem为顺序表中的数据元素,e为待查询的数据元素
if(elem == e){
return true;
}else{
return false;
}
}
//6:定义顺序表的查询数据元素函数
int inquireSqList(SqList L,int e,bool (*compare)(int elem,int e)){
if(L.length == 0){
return 0;//函数返回值为0表示没有找到
}
for(int i=0;i<L.length;i++){
if((*compare)(L.elem[i],e)){//表达式返回值为true表示找到待查询的数据元素e
return i+1;//C语言数组的下标是从0开始,而顺序表从1开始
}
}
return 0;//for循环比较完整个顺序表都没找到e,则表示表中无数据元素e
}
//7:定义顺序表的插入数据元素函数
bool insertSqList(SqList &L,int i,int e){
if(i<1 || i>L.length+1){
printf("插入数据元素的位置i不合理\n");
return false;
}
if(L.length >= L.sqListSize){
int *newBase = (int *)realloc(L.elem,(LIST_INIT_SIZE*LISTINCREMENT)*(sizeof(int)));//增加顺序表的存储容量,realloc函数在增容时会保留原指针指向的数据
if(newBase == NULL){
printf("增加存储容量失败\n");
exit(1);
}
L.elem = newBase;//新基址
}
int *q = L.elem+i-1;//指针q指向插入数据元素的位置
for(int *p=L.elem+L.length-1;p>=q;p--){//指针p指向顺序表最后一个数据元素的位置
*(p+1) = *p;
}
*q = e;
L.length++;
return true;
}
//8:定义顺序表的删除数据元素函数
bool deleteSqList(SqList &L,int i,int &e){//e用于接收删除的数据元素
if(i<1 || i>L.length){
printf("删除数据元素的位置i不合理\n");
return false;
}
int *p = L.elem+i-1;
e = *p;
int *q = L.elem+L.length-1;
for(++p;p<=q;p++){
*(p-1) = *p;
}
L.length--;
return true;
}
//9:定义顺序表的操作功能菜单
void menuSqList(void){
char *funName[] = {
"1_顺序表的初始数据输入操作","2_顺序表的遍历操作","3_顺序表的查询数据元素操作",
"4_顺序表的插入数据元素操作","5_顺序表的删除数据元素操作"
};
printf("========================================\n");
for(int i=0;i<sizeof(funName)/sizeof(char *);i++){
printf("\t%s\n",funName[i]);
}
printf("========================================\n");
}
//10:定义顺序表的操作功能函数
void operate(SqList &L){
int funNo = 0;//操作功能编号
int e = 0;//e用于inquire 或接收删除的数据元素
int i = 0;//i用于插入删除数据元素
int index = 0;//index用于接收查询数据的位置
bool flag = true;
while(flag){
menuSqList( );
printf("input of funNo:");
scanf("%d",&funNo);
switch(funNo){
case 1:
initInputSqList(L); break;
case 2:
traverseSqList(L); break;
case 3:
printf("input of inquire e:");
scanf("%d",&e);
index = inquireSqList(L,e,compare);
if(index == 0){
printf("not found e\n");
}else{
printf("e 在顺序表的第%d个位置\n",index);
}
break;
case 4:
printf("input of insert i:");
scanf("%d",&i);
printf("input of insert e:");
scanf("%d",&e);
if(insertSqList(L,i,e) == true){
printf("插入数据元素成功\n");
}else{
printf("插入数据元素失败\n");
};
break;
case 5:
printf("input of delete i:");
scanf("%d",&i);
if(deleteSqList(L,i,e) == true){
printf("数据元素%d删除成功\n",e);
}else{
printf("数据元素删除失败\n");
}
break;
default:
printf("输入的funNO错误\n"); break;
}
printf("是否执行其他操作? 1_是,0_否:");
std::cin>>flag;
system("cls");//清屏
}
}
int main(void){
SqList L;//定义一个顺序表
initSqList(L);//初始化顺序表
operate(L);//顺序表操作
system("pause");
return 0;
}
[对C语言的realloc函数的用法不清楚的可以查看这篇博客](https://blog.csdn.net/weixin_42373330/article/details/88321911)
[注意:以上的每个函数的位置顺序不可以打乱,因为我没有在函数内部加上引用函数的声明]
[如有不足,可以畅所欲言,谢谢点评]