一共有两份代码:
目录
- 说明:
-
- assert(ps)表示如果ps为空,会立即报错,使用这个函数一般要加头文件#include
-
- ps表示SL类型的结构体,相当于顺序表
-
- SeqList.h文件(头文件)存放函数的声明
- SeqList.c文件(源文件)存放函数的定义
- Seqtext.c存放主函数
- typedef int SLDateType; //数据类型
- typedef struct SeqList
- {
- SLDateType* a; //数据类型指针,指向动态开辟的数组
- int size; //顺序表长度
- int capacity; //顺序表容量
- }SL;
-
-
- void SLInsert(SL* ps) //顺序表的初始化
- {
- assert(ps);
-
- ps->a = NULL;
- ps->size = 0;
- ps->capacity = 0;
- }
-
- void SLDestroy(SL* ps) //顺序表的摧毁
- {
- assert(ps);
- if (ps->a) //如果ps->a不为空
- {
- free(ps->a);//释放掉pa->a空间
- ps->a = NULL;
- ps->size = ps->capacity = 0;
- }
- }
- int SLFind(SL* ps, SLDataType x)
- {
- assert(ps);
- for (int i = 0; i < ps->size; ++i)
- {
- if (ps->a[i] == x)
- {
- return i;
- }
- }
- return -1;
- }
如果找到了需要找的值,返回值的下标,否者返回-1;
-
- void SLCheckCapacity(SL*ps)
- {
- assert(ps);
- if (ps->size == ps->capacity)
- {
- int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
- SLDataType *tmp = (SLDataType*)realloc(ps->a, newCapacity * sizeof(SLDataType));//把新添加的用量添加到ps->a里面,这里注意tmp是地址空间
- if (tmp == NULL)
- {
- perror("realloc fail");
- exit(-1);
- }
- ps->a = tmp;
- ps->capacity = newCapacity;
- }
- }
刚开始初始化顺序表之后,也通过这个函数分配空间;在这里说一下realloc的作用:
- (SLDataType*)realloc(ps->a, newCapacity * sizeof(SLDataType))表示
- 给指向ps->a的指针分配一个大小为newCapacity * sizeof(SLDataType)大小
- 的空间,如果在原来指向ps->a的后面的空间被占用了,
- 则会异地开辟新的空间,
- 并且会拷贝原来的数据过来,而原来的空间会被释放掉。
- //在pos 位置插入x
- void SeqListInsert(SeqList* ps, int pos, SLDateType x)
- {
- assert(ps);
- assert(pos>= 0);
- assert(pos <= ps->size); //此处可以等于0,因为在插入之前ps->a[size]的值为0
-
- SeqListCheckCapacity(ps);
- int end = ps->size-1;
- while (end>=pos)
- {
- ps->a[end+1] = ps->a[end];
- end--;
- }
- ps->a[pos] = x;
- ps->size++;
- }
在插入数据之前需要考虑顺序表容量有没有满:SEqListCheckCapacity(ps);如果没有满,则将在pos位置往后的数据往后挪,挪完之后再插入数据x;
- //删除pos位置数据
- void SLErase(SL* ps, int pos)
- {
- assert(ps);
- assert(pos >= 0);
- assert(pos < ps->size);
- int begin = pos + 1;
- while (begin < ps->size)
- {
- ps->a[begin - 1] = ps->a[begin];
- begin++;
- }
- ps->size--;
- }
- void SLPushFront(SL* ps, SLDataType x) //头插
- {
- SLInsert(ps, 0, x);
- }
- void SLPopFront(SL* ps) //头删
- {
- SLErase(ps, 0);
- }
-
- void SLPopBack(SL* ps) //尾删除
- {
- SLErase(ps, ps->size-1);
- }
- void SLPushBack(SL* ps, SLDataType x) //尾插入
- {
- SLInsert(ps, ps->size, x);
- }
这个是.h文件(头文件),用来存放函数的声明和顺序表结构体的定义,引用头文件的时候记得加上#include"SeqList.h"
- //SeqList.h
- #pragma once
- #include
- #include
- #include
-
- //静态顺序表---不太实用
- //N太小了不够用,N大了可能浪费
- //#define N 1000
- //动态顺序表---按需扩空间
- typedef int SLDataType;
- typedef struct SeqList
- {
- SLDataType* a;
- int size; //记录存储多少个有效数据
- int capacity; //空间容量大小
- }SL;
-
- void SLInsert(SL* ps, int pos, SLDataType x);
- void SLErase(SL* ps, int pos);
-
- void SLPrint(SL* ps);
- void SLInit(SL* ps);
- void SLDestroy(SL* ps);
- void SLCheckCapacity(SL* ps); //检查容量
-
- //尾插尾删
- void SLPushBack(SL* ps, SLDataType x);
- void SLPopBack(SL* ps);
-
- //头插头删
- void SLPushFront(SL* ps, SLDataType x);
- void SLPopFront(SL* ps);
-
- void menu();
- int SLFind(SL* ps, SLDataType x, int begin);
以下是SeqLIst.c文件,存放函数的定义
- //SeqList.c
- #define _CRT_SECURE_NO_WARNINGS
- #pragma once
- #include"SeqList.h"
-
- void SLCheckCapacity(SL*ps)
- {
- assert(ps);
- if (ps->size == ps->capacity)
- {
- int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
- SLDataType *tmp = (SLDataType*)realloc(ps->a, newCapacity * sizeof(SLDataType));//把新添加的用量添加到ps->a里面,这里注意tmp是地址空间
- if (tmp == NULL)
- {
- perror("realloc fail");
- exit(-1);
- }
- ps->a = tmp;
- ps->capacity = newCapacity;
- }
- }
-
- void SLPrint(SL* ps) //打印
- {
- assert(ps);
- for (int i = 0; i < ps->size; ++i)
- {
- printf(" %d", ps->a[i]);
- }
- printf("\n");
- }
-
- void SLInit(SL* ps) //顺序表的初始化
- {
- assert(ps);
-
- ps->a = NULL;
- ps->size = 0;
- ps->capacity = 0;
- }
-
- void SLDestroy(SL* ps) //顺序表的摧毁
- {
- assert(ps);
- if (ps->a) //如果ps->a有值在里面
- {
- free(ps->a);//释放掉pa->a空间
- ps->a = NULL;
- ps->size = ps->capacity = 0;
- }
- }
-
- //在pos位置插入数据
- void SLInsert(SL *ps,int pos,SLDataType x)
- {
- assert(ps);
- assert(pos >= 0);
- assert(pos <= ps->size);
-
- SLCheckCapacity(ps);
- int end = ps->size - 1;
- while (end >= pos)
- {
- ps->a[end + 1] = ps->a[end];
- end--;
- }
- ps->a[pos] = x;
- ps->size++;
- }
-
- //删除pos位置数据
- void SLErase(SL* ps, int pos)
- {
- assert(ps);
- assert(pos >= 0);
- assert(pos < ps->size);
- int begin = pos + 1;
- while (begin < ps->size)
- {
- ps->a[begin - 1] = ps->a[begin];
- begin++;
- }
- ps->size--;
- }
-
- void SLPushBack(SL* ps, SLDataType x) //尾插入
- {
- SLInsert(ps, ps->size, x);
- }
-
- void SLPopBack(SL* ps) //尾删除
- {
- SLErase(ps, ps->size-1);
- }
- void SLPushFront(SL* ps, SLDataType x) //头插
- {
- SLInsert(ps, 0, x);
- }
-
- void SLPopFront(SL* ps) //头删
- {
- SLErase(ps, 0);
- }
-
- int SLFind(SL* ps, SLDataType x, int begin)
- {
- assert(ps);
- for (int i = begin; i < ps->size; ++i)
- {
- if (ps->a[i] == x)
- {
- return i;
- }
- }
- return -1;
- }
以下是用来存放主函数的文件,以及一些函数的调用
- //SLtest.c
- #define _CRT_SECURE_NO_WARNINGS
- #include"SeqList.h"
- void menu()
- {
- printf("***********************************************************\n");
- printf("1、尾插数据 2、尾删数据\n");
- printf("3、头插数据 4、头删数据\n");
- printf("5打印数据 -1退出\n");
- printf("***********************************************************\n");
- }
- int main()
- {
- SL ps;
- SLInit(&ps); //顺序表的初始化
- //SLInsert(&ps,0,1);
- //SLPrint(&ps);
- int n=0;
- int option=0;
- do
- {
- menu();
- printf("输入操作\n");
- scanf("%d", &option);
- switch (option)
- {
- case 1:
- printf("请输入你尾插的数据,以-1结束");
- scanf("%d",&n);
- while (n != -1)
- {
- SLPushBack(&ps,n);
- scanf("%d",&n);
- }
- break;
- case 2:
- SLPopBack(&ps);
- break;
- case 3:
- printf("请输入你头插入的数据,以-1结束\n");
- scanf("%d", &n);
- while (n != -1)
- {
- SLPushFront(&ps,n);
- scanf("%d", &n);
- }
- break;
- case 4:
- SLPopFront(&ps);
- break;
- case 5:
- SLPrint(&ps);
- break;
- default:
- break;
- }
- } while (option != -1);
- printf("????\n");
- SLDestroy(&ps);
- return 0;
- }
(将代码复制到.c文件就可以运行)
- #define _CRT_SECURE_NO_WARNINGS
- #pragma once
- #include
- #include
- #include
-
- typedef int SLDateType;
- typedef struct SeqList
- {
- SLDateType* a;
- int size;
- int capacity;
- }SeqList;
-
- // 对数据的管理:增删查改
- void SeqListInit(SeqList* ps);
- void SeqListDestroy(SeqList* ps);
-
- void SeqListPrint(SeqList* ps);
- void SeqListPushBack(SeqList* ps, SLDateType x);
- void SeqListPushFront(SeqList* ps, SLDateType x);
- void SeqListPopFront(SeqList* ps);
- void SeqListPopBack(SeqList* ps);
-
- // 顺序表查找
- int SeqListFind(SeqList* ps, SLDateType x);
- // 顺序表在pos位置插入x
- void SeqListInsert(SeqList* ps, int pos, SLDateType x);
- // 顺序表删除pos位置的值
-
- void SeqListInit(SeqList* ps)//初始化
- {
- ps->a = NULL;
- ps->size = 0;
- ps->capacity = 0;
- }
-
- void SeqListDestroy(SeqList* ps)
- {
- assert(ps);
- if (ps->a)
- {
- free(ps->a);
- ps->a = NULL; //指针制空,释放
- ps->size = ps->capacity = 0;
- }
- }
-
- void SeqPrint(SeqList* ps) //打印
- {
- int i;
- assert(ps);
- for (i = 0; i < ps->size; i++)
- {
- printf(" %d", ps->a[i]);
- }
- }
- void SeqListCheckCapacity(SeqList* ps) //给ps->a 分配空间或者添加空间
- {
- assert(ps);
- if (ps->size == ps->capacity) //当顺序表长度等于顺序表的容量的时候
- {
- int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
- SLDateType* temp = (SLDateType*)realloc(ps->a, newCapacity * sizeof(SLDateType));
- if (temp == NULL) //if里面用的是"=="
- {
- printf("realloc failed");
- exit(-1);
- }
- ps->a = temp;
- ps->capacity = newCapacity;
- }
-
- }
-
- //在pos位置删除数据
- void SeqListErase(SeqList* ps, int pos)
- {
- assert(ps);
- assert(pos >= 0);
- assert(pos < ps->size);
-
- int begin = pos + 1;
- while (begin < ps->size)
- {
- ps->a[begin--] = ps->a[begin]; //pos位置的数据被它后一位的数据覆盖
- begin++;
- }
- ps->size--;
- }
- //在pos 位置插入x
- void SeqListInsert(SeqList* ps, int pos, SLDateType x)
- {
- assert(ps);
- assert(pos>= 0);
- assert(pos <= ps->size); //此处可以等于0,因为在插入之前ps->a[size]的值为0
-
- SeqListCheckCapacity(ps);
- int end = ps->size-1;
- while (end>=pos)
- {
- ps->a[end+1] = ps->a[end];
- end--;
- }
- ps->a[pos] = x;
- ps->size++;
- }
- void SeqListPushBack(SeqList* ps,SLDateType x) //尾插
- {
- SeqListInsert(ps, ps->size, x); //相当于在位置ps->a[size]处插入值x
- }
- void SeqListPopBack(SeqList* ps) //尾删
- {
- SeqListErase(ps, ps->size - 1);//相当于在位置ps->a[size-1]处删除数据
- }
- void SeqListPushFront(SeqList* ps, SLDateType x) //头插
- {
- SeqListInsert(ps, 0, x);
- }
- void SeqListPopFront(SeqList* ps) //头删
- {
- SeqListErase(ps, 0);
- }
- int SeqListFind(SeqList* ps, SLDateType x) //查找元素
- {
- assert(ps);
- for (int i = 0; i < ps->size; ++i)
- {
- if (ps->a[i] == x)
- {
- return i; //返回下标
- }
- }
- return -1; //若返回-1则找不到
- }
-
- int main()
- {
- SeqList ps;
- int op;
- int x;
- int find;
- SeqListInit(&ps); //初始化
- do
- {
- printf("\n1、尾插 2、尾删 3、头插 4、头删 5、查找元素下标 6、打印 -1、退出\n");
- printf("输入你的操作:\n");
- scanf("%d", &op);
- switch (op)
- {
- case 1:
- printf("请输入你尾删的数据,以-1结束\n");
- scanf("%d", &x);
- while (x != -1)
- {
- SeqListPushBack(&ps, x);
- scanf("%d", &x);
- }
- break;
- case 2:
- SeqListPopBack(&ps); break;
- case 3:
- printf("请输入你头插的数据,以-1结束\n");
- scanf("%d", &x);
- while (x != -1)
- {
- SeqListPushFront(&ps, x);
- scanf("%d", &x);
- }
- break;
- case 4:
- SeqListPopFront(&ps); break;
- case 5:
- printf("请输入你要查找的元素x=");
- scanf("%d", &x);
- if ((find = SeqListFind(&ps, x)) == -1)
- {
- printf("没有该元素\n");
- }
- else
- printf("下标为%d", SeqListFind(&ps,x));
- break;
- case 6:
- SeqPrint(&ps); break;
- default:
- break;
- }
- } while (op != -1);
-
- SeqListDestroy(&ps);
- return 0;
- }