/*
顺序的操作集中一些常用的操作
说明:顺序表的操作可以根据需要灵活的编写,操作接口比较多,这里只写了一些常用的基本接口
1、始化顺序表
Status InitList_Sq(SqList &L, int size, int increment);
2、销毁顺序表
Status DestroyList_Sq(SqList &L);
3、判断顺序表是否为空
Status ListEmpty_Sq(SqList L);
4、清空顺序表
Status ClearList_Sq(SqList &L);
5、求顺序表的长度
int ListLength_Sq(SqList L);
6、读取顺序表中指定的第 i 个元素
Status GetElem_Sq(SqList L, int i, ElemType &e);
7、顺序表中查找指定元素 e,说明:成功时返回该元素在表中第一次出现的位置,否则返回 -1
int Search_Sq(SqList L, ElemType e);
8、顺序表的第 i 个元素赋值为 e
PutElem_Sq(SqList &L, int i, ElemType e);
9、在表尾添加一个元素
Status Append_Sq(SqList &L, ElemType e);
10、在指定第 i 个元素之前插入元素
Status ListInsert_Sq(SqList &L, int i, ElemType e);
11、删除表尾元素
Status DeleteLast_Sq(SqList &L,int i, ElemType &e);
12、删除指定的第 i 个元素
Status ListDelete_Sq(SqList &L,int i, ElemType &e);
13、遍历顺序表 L,说明:依次对每个元素调用函数 visit()
Status ListTraverse_Sq(SqList L, Status(*visit)(ElemType e));
*/
#include<stdio.h>
#include<stdlib.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -1
#define PERROR -2
typedef int Status;
// 数据元素的类型,使用时需根据问题的需求定义。
typedef int ElemType;
//顺序表结构类型定义
typedef struct {
ElemType *elem; // 存储空间的基址
int length; // 表长
int size; // 存储容量
int increment; // 扩容增量
} SqList;
// 1、初始化顺序表 L
Status InitList_Sq(SqList &L, int size, int inc){
L.elem = (ElemType *)malloc(size * sizeof(ElemType));
if (L.elem == NULL) return OVERFLOW;
L.length = 0;
L.size = size;
L.increment = inc;
return OK;
}
// 2、销毁顺序表 L
Status DestroyList_Sq(SqList &L) {
if((L.elem != NULL)&&(L.size == 0))return PERROR; // 参数合法性检验,防止实参未初始化时就使用的野指针
if(L.elem == NULL)return PERROR; // 参数合法性检查,顺序表已销毁则返回,不再执行销毁操作
free(L.elem); // 释放顺序表所占空间
L.elem = NULL; // 避免指针悬挂
L.length = 0;
L.size = 0;
L.increment = 0;
return OK;
}
// 3、判断顺序表 L 是否为空表
Status ListEmpty_Sq(SqList L) {
if((L.elem != NULL)&&(L.size == 0))return PERROR; // 参数合法性检验,防止实参未初始化时就使用的野指针
if(L.elem == NULL)return PERROR; // 参数合法性检查,顺序表已销毁则返回
if(L.length == 0) {
return TRUE;
}else{
return FALSE;
}
}
// 4、清空顺序表 L
Status ClearList_Sq(SqList &L) {
if((L.elem != NULL)&&(L.size == 0))return PERROR; // 参数合法性检验,防止实参未初始化时就使用的野指针
if(L.elem == NULL)return PERROR; // 参数合法性检查,顺序表已销毁则返回
L.length = 0;
return OK;
}
// 5、求顺序表的长度
int ListLength_Sq(SqList L) {
if((L.elem != NULL)&&(L.size == 0))return PERROR; // 参数合法性检验,防止实参未初始化时就使用的野指针
if(L.elem == NULL)return PERROR; // 参数合法性检查,顺序表已销毁则返回
return L.length;
}
// 6、读取顺序表中指定的第 i 个元素
Status GetElem_Sq(SqList L, int i, ElemType &e) {
if((L.elem != NULL)&&(L.size == 0))return PERROR; // 参数合法性检验,防止实参未初始化时就使用的野指针
if(L.elem == NULL)return PERROR; // 参数合法性检查,顺序表已销毁则返回
if(i<1 || i>L.length) return PERROR; // 参数合法性检查,非法则返回
e = L.elem[i-1];
return OK;
}
// 7、在顺序表 L 顺序查找元素e
// 成功时返回该元素在表中第一次出现的位置,否则返回 -1
int Search_Sq(SqList L, ElemType e) {
if((L.elem != NULL)&&(L.size == 0))return PERROR; // 参数合法性检验,防止实参未初始化时就使用的野指针
if(L.elem == NULL)return PERROR; // 参数合法性检查,顺序表已销毁则返回
int i = 0;
while (i < L.length && L.elem[i] != e){
i++;
}
if (i < L.length){
return i;
}else{
return -1;
}
}
// 8、把顺序表的第 i 个元素赋值为 e
Status PutElem_Sq(SqList &L, int i, ElemType e) {
if((L.elem != NULL)&&(L.size == 0))return PERROR; // 参数合法性检验,防止实参未初始化时就使用的野指针
if(L.elem == NULL)return PERROR; // 参数合法性检查,顺序表已销毁则返回
if(i<1 || i>L.length) return PERROR; // 参数合法性检查,非法则返回
L.elem[i-1] = e;
return OK;
}
// 9、在顺序表 L 的表尾添加元素 e
Status Append_Sq(SqList &L, ElemType e) {
ElemType *newbase;
if((L.elem != NULL)&&(L.size == 0))return PERROR; // 参数合法性检验,防止实参未初始化时就使用的野指针
if(L.elem == NULL)return PERROR; // 参数合法性检查,顺序表已销毁则返回
if (L.length >= L.size){ // 满了需要扩容
newbase = (ElemType*)realloc(L.elem, (L.size + L.increment)*sizeof(ElemType));
if(newbase==NULL) return OVERFLOW;
L.elem = newbase;
L.size += L.increment;
}
L.elem[L.length] = e;
L.length++;
return OK;
}
// 10、在顺序表 L 的指定第 i 个元素之前插入元素
Status ListInsert_Sq(SqList &L, int i, ElemType e){
ElemType *newbase;
int l,r;
if((L.elem != NULL)&&(L.size == 0))return PERROR; // 参数合法性检验,防止实参未初始化时就使用的野指针
if(L.elem == NULL)return PERROR; // 参数合法性检查,顺序表已销毁则返回
if(i < 1 || i > L.length) return PERROR; // 数合法性检查,非法则返回
if (L.length >= L.size){ // 满了需要扩容
newbase = (ElemType*)realloc(L.elem, (L.size + L.increment)*sizeof(ElemType));
if(newbase==NULL) return OVERFLOW;
L.elem = newbase;
L.size += L.increment;
}
l = i-1; // l为插入位置
for(r = L.length-1; r >= l; r--){
L.elem[r+1] = L.elem[r]; //插入位置及之后的元素后移
}
L.elem[l] = e; //插入e
L.length++; //表长加 1
return OK;
}
// 11、删除表尾元素
Status DeleteLast_Sq(SqList &L, ElemType &e) {
if((L.elem != NULL)&&(L.size == 0))return PERROR; // 参数合法性检验,防止实参未初始化时就使用的野指针
if(L.elem == NULL)return PERROR; // 参数合法性检查,顺序表已销毁则返回
if(L.length == 0) return ERROR; // 空表,无法删除
e = L.elem[L.length - 1];
L.length--;
return OK;
}
// 12、在顺序表 L 中删除指定的第 i 个元素,并用 e 将其返回
Status ListDelete_Sq(SqList &L, int i, ElemType &e)
{
int r; // 后面的元素移位迭代用变量
if((L.elem != NULL)&&(L.size == 0))return PERROR; // 参数合法性检验,防止实参未初始化时就使用的野指针
if(L.elem == NULL)return PERROR; // 参数合法性检查,顺序表已销毁则返回
if(i < 1 || i > L.length) return ERROR; // 参数合法性检查,非法则返回
e = L.elem[i-1]; // 将第 i 个元素交给 e
for(r = i;r < L.length;r--){
L.elem[r-1] = L.elem[r]; // 将删除位置之后的元素依次前移
}
L.length--; //表长减一
return OK;
}
// 13、遍历顺序表 L ,依次对每个元素调用函数 visit()
Status ListTraverse_Sq(SqList L, Status(*visit)(ElemType e)) {
if((L.elem != NULL)&&(L.size == 0))return PERROR; // 参数合法性检验,防止实参未初始化时就使用的野指针
if(L.elem == NULL)return PERROR; // 参数合法性检查,顺序表已销毁则返回
if (L.length == 0) return ERROR; // 空表不再遍历访问
for (int i = 0; i < L.length; i++) {
visit(L.elem[i]);
}
return OK;
}
// 测试用函数:打印顺序表的全部元素
Status PrintList(ElemType e) {
printf("%d\t",e);
return OK;
}
int main(){
int i, e, state;
SqList L;
printf("1.初始化顺序表\n");
printf("2.销毁顺序表\n");
printf("3.判断顺序表是否为空\n");
printf("4.清空顺序表\n");
printf("5.求顺序表的长度\n");
printf("6.读取顺序表中指定的第 i 个元素\n");
printf("7.在顺序表中查找指定元素\n");
printf("8.将顺序表的第 i 个元素赋值为 e\n");
printf("9.在顺序表中的表尾添加一个元素\n");
printf("10.在指定第 i 个元素之前插入元素\n");
printf("11.删除表尾元素\n");
printf("12.删除指定的第 i 个元素\n");
printf("13.打印顺序表中的全部元素\n");
do{
printf("请输入你要进行的操作:\n");
scanf("%d",&i);
switch(i){
case 1 :
state = InitList_Sq(L, 10, 5);
if(state == OK){
printf("顺序表初始化成功。\n");
}else{
printf("顺序表初始化失败!\n");
}
break;
case 2 :
state = DestroyList_Sq(L);
if(state == PERROR){
printf("请确认参数合法化或者先执行顺序表的初始化操作!\n");
}else{
printf("顺序表销毁成功。\n");
}
break;
case 3 :
state = ListEmpty_Sq(L);
if(state == PERROR){
printf("请确认参数合法化或者先执行顺序表的初始化操作!\n");
}else if(state == TRUE){
printf("队列为空!\n");
}else if(state == FALSE){
printf("队列不为空!\n");
}
break;
case 4 :
state = ClearList_Sq(L);
if(state == PERROR){
printf("请确认参数合法化或者先执行顺序表的初始化操作!\n");
}else{
printf("已为您清空队列。\n");
}
break;
case 5 :
state = ListLength_Sq(L);
if(state == PERROR){
printf("请确认参数合法化或者先执行顺序表的初始化操作!\n");
}else{
printf("当前顺序表中共有 %d 个元素!\n",state);
}
break;
case 6 :
printf("请输入将需要读取的是第几个元素:\n");
scanf("%d",&i);
state = GetElem_Sq(L, i, e);
if(state == PERROR){
printf("请确认参数合法化或者先执行顺序表的初始化操作!\n");
}else{
printf("顺序表中第 %d 个元素是: %d \n",i,e);
}
break;
case 7 :
printf("请输入将想要查找的元素:\n");
scanf("%d",&e);
state = Search_Sq(L, e);
if(state == PERROR){
printf("请确认参数合法化或者先执行顺序表的初始化操作!\n");
}else if(state == -1){
printf("顺序表没有这个元素!\n");
}else{
printf("查找成功:您要找的元素是顺序表的第 %d 个元素。\n",state);
}
break;
case 8 :
printf("请输入更换的元素的位置:\n");
scanf("%d",&i);
printf("请输入您想将元素更换为:\n");
scanf("%d",&e);
state = PutElem_Sq(L, i, e);
if(state == PERROR){
printf("请确认参数合法化或者先执行顺序表的初始化操作!\n");
}else{
printf("元素更换成功。\n");
}
break;
case 9 :
printf("请输入您想在表尾追加的元素为:\n");
scanf("%d",&e);
state = Append_Sq(L, e);
if(state == PERROR){
printf("请确认参数合法化或者先执行顺序表的初始化操作!\n");
}else if(state == OK){
printf("元素 %d 追加成功。\n",e);
}else{
printf("元素 %d 追加失败!\n",e);
}
break;
case 10 :
printf("请输入您想在第几个元素前插入元素:\n");
scanf("%d",&i);
printf("请输入您想插入的元素为:\n");
scanf("%d",&e);
state = ListInsert_Sq(L, i, e);
if(state == PERROR){
printf("请确认参数合法化或者先执行顺序表的初始化操作!\n");
}else if(state == OK){
printf("元素 %d 追加成功。\n",e);
}else{
printf("元素 %d 追加失败!\n",e);
}
break;
case 11 :
state = DeleteLast_Sq(L, e);
if(state == PERROR){
printf("请确认参数合法化或者先执行顺序表的初始化操作!\n");
}else if(state == OK){
printf("顺序表表尾元素已成功删除。\n");
}else{
printf("顺序表内没有元素,不能执行删除表尾元素操作!\n");
}
break;
case 12 :
printf("请输入您删除的是顺序表中的第几个元素:\n");
scanf("%d",&i);
state = ListDelete_Sq(L, i, e);
if(state == PERROR){
printf("请确认参数合法化或者先执行顺序表的初始化操作!\n");
}else if(state == OK){
printf("指定的元素已成功删除。\n");
}else{
printf("顺序表内没有元素,不能执行删除表尾元素操作!\n");
}
break;
case 13 :
state = ListTraverse_Sq(L, PrintList);
if(state == PERROR){
printf("请确认参数合法化或者先执行顺序表的初始化操作!\n");
}else if(state == ERROR){
printf("当前的顺序表为空表。\n");
}else{
printf("\n");
}
break;
}
}while(i>=1&&i<=13);
return 0;
}