目录
线性表( linear list )是n个具有相同特性的数据元素的有限序列。 线性表是⼀种在实际中⼴泛使⽤的数据结构,常⻅的线性表:顺序表、链表、栈、队列、字符串...线性表在逻辑上是线性结构,也就说是连续的⼀条直线。但是在物理结构上并不⼀定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。案例:蔬菜分为绿叶类、⽠类、菌菇类。
- struct SeqList
- {
- int arr[100];//定长数组
- int size;//顺序表当前的数据个数
- };
概念:使用定长数组存放元素
缺陷:空间给少了不够⽤,给多了造成空间浪费
- struct SeqList
- {
- int *arr;
- int size;//有效的数据个数
- int capacity;//空间大小
- };
因为数组并不是定长的,可根据实际数据大小进行动态申请空间,随着数据的增加,也可进行动态增容。
分成三个文件实现:
SeqList.h
SeqList.c
test.c

首先在SeqList.h创建好顺序表的结构
- typedef int SLDataType;//顺序表存放的类型可能是int 也可能是char,
- 所有重新起个名字,方便以后更改
- //动态顺序表
- typedef struct SeqList
- {
- SLDataType* arr;
- int size;//有效数据个数
- int capacity;//空间大小
- }SL;
- void SLlnit(SL* ps)//顺序表初始化
- {
- ps->arr = NULL;
- ps->size = ps->capacity=0;
- }
在插入数据之前首先要判断空间是否为0,空间是否足够,
若不够,一次应增容多少?
通常来说增容是成倍的增长,一般是2倍或3倍
因此,创建一个函数SLCheckCapacity专门实现增容,每次插入数据之前需调用一次函数
- void SLCheckCapacity(SL* ps)
- {
- //插入数据之前先看空间够不够
- if (ps->capacity == ps->size)
- {
- //申请空间-->增容realloc
- int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
- //三目表达式 判断capacity是否为0 是:赋值为4 否:赋值为2 * ps->capacity
- //增容通常来说是成倍数的增加,一般是2或3倍
- SLDataType* tmp = (SLDataType*)realloc(ps->arr, newCapacity * sizeof(SLDataType));//要申请多大的空间
- if (tmp == NULL)
- {
- perror("realloc fail!");
- exit(1);//直接退出程序,不再继续执行
- }
- //空间申请成功
- ps->arr = tmp;
- ps->capacity = newCapacity;
- }
- }
在数据的尾部插入数据
- //尾插
- void SLPushBack(SL* ps, SLDataType x)
- {
- //防止ps可能为NULL
- assert(ps);//等价于assert(ps!=NULL);
-
- SLCheckCapacity(ps);
- ps->arr[ps->size++] = x;
- }
在数据的头部插入数据;
插入数据之前把原有数据全部向后移动一位
- //头插
- void SLPushFront(SL* ps, SLDataType x)
- {
- assert(ps);
- SLCheckCapacity(ps);
- //先让顺序表中已有的数据整体往后挪动一位
- for (int i = ps->size; i > 0; i--)//数组下标不会为-1
- {
- ps->arr[i] = ps->arr[i - 1];
- }
- ps->arr[0] = x;//头插
- ps->size++;
- }
创建一个变量pos存放指定位置,然后把pos之后的数据整体往后移动一位,在pos位置插入所需要的数据即可。
- //在指定位置之前插入数据
- void SLlnsert(SL* ps, int pos, SLDataType x)//pos:指定的位置 x:插入的数据
- {
- assert(ps);
- assert(pos >= 0 && pos <= ps->size);
- //插入数据:空间够不够
- SLCheckCapacity(ps);
- //让pos及之后的数据整体往后挪动一位
- for (int i = ps->size; i > pos; i--)//从后往前挪动
- {
- ps->arr[i] = ps->arr[i - 1];//arr[pos+1]=arr[pos] 最后下标为pos位置为空
- }
- ps->arr[pos] = x;//在pos位置插入数据
- ps->size++;
- }
- //查找
- int SLFind(SL* ps, SLDataType x)
- {
- assert(ps);
- for (int i = 0; i < ps->size; i++)
- {
- if (ps->arr[i] == x)
- {
- //找到了
- return i;
- }
- }
- //没有找到
- return -1;
- }
与插入数据原理一样,只需在所需的位置删除数据即可
SeqList.h
- #pragma once
- #include<stdio.h>
- #include<stdlib.h>
- #include<assert.h>
- //定义顺序表的结构
-
- //#define N 100
-
- 静态顺序表
- //struct SeqList
- //{
- // int arr[N];
- // int size;//有效数据个数
- //};
-
- typedef int SLDataType;//顺序表存放的类型可能是int 也可能是char,所有重新起个名字,方便以后更改
- //动态顺序表
- typedef struct SeqList
- {
- SLDataType* arr;
- int size;//有效数据个数
- int capacity;//空间大小
- }SL;
-
- //顺序表初始化
- void SLlnit(SL* ps);
- //顺序表的销毁
- void SLDestroy(SL* ps);
- //顺序表的打印
- void SLprint(SL s);
-
- //头部插入删除/尾部插入删除
- void SLPushBack(SL* ps, SLDataType x);
- void SLPushFront(SL* ps, SLDataType x);
-
- void SLPopBack(SL* ps);
- void SLPopFront(SL* ps);
-
- //指定位置之前插入/删除数据
- void SLlnsert(SL* ps,int pos,SLDataType x );
- void SLErase(SL* ps, int pos);
-
- //查找
- int SLFind(SL* ps, SLDataType x);
SeqList.c
- #include"SeqList.h"
- void SLlnit(SL* ps)//顺序表初始化
- {
- ps->arr = NULL;
- ps->size = ps->capacity=0;
- }
- //顺序表的销毁
- void SLDestroy(SL* ps)
- {
- if (ps->arr)//等价于 if(ps->!=NULL)
- {
- free(ps-> arr);//释放空间
- }
- ps->arr = NULL;
- ps->size = ps->capacity = 0;
- }
-
- void SLCheckCapacity(SL* ps)
- {
- //插入数据之前先看空间够不够
- if (ps->capacity == ps->size)
- {
- //申请空间-->增容realloc
- int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
- //三目表达式 判断capacity是否为0 是:赋值为4 否:赋值为2 * ps->capacity
- //增容通常来说是成倍数的增加,一般是2或3倍
- SLDataType* tmp = (SLDataType*)realloc(ps->arr, newCapacity * sizeof(SLDataType));//要申请多大的空间
- if (tmp == NULL)
- {
- perror("realloc fail!");
- exit(1);//直接退出程序,不再继续执行
- }
- //空间申请成功
- ps->arr = tmp;
- ps->capacity = newCapacity;
- }
- }
- //尾插
- void SLPushBack(SL* ps, SLDataType x)
- {
- //防止ps可能为NULL
- assert(ps);//等价于assert(ps!=NULL);
-
- SLCheckCapacity(ps);
- ps->arr[ps->size++] = x;
- }
-
- //头插
- void SLPushFront(SL* ps, SLDataType x)
- {
- assert(ps);
- SLCheckCapacity(ps);
- //先让顺序表中已有的数据整体往后挪动一位
- for (int i = ps->size; i > 0; i--)//数组下标不会为-1
- {
- ps->arr[i] = ps->arr[i - 1];
- }
- ps->arr[0] = x;//头插
- ps->size++;
- }
- //打印顺序表
- void SLprint(SL s)
- {
- for (int i = 0; i < s.size; i++)
- {
- printf("%d ", s.arr[i]);
- }
- printf("\n");
- }
-
- //尾部删除
- void SLPopBack(SL* ps)
- {
- assert(ps);
- assert(ps->size);
- //顺序表不为空
- //ps->arr[ps->size - 1] = -1;
- --ps->size;//删除
- }
-
- //头删
- void SLPopFront(SL* ps)
- {
- assert(ps);
- assert(ps->size);
-
- //数据整体往前挪动一位
- for (int i = 0; i < ps->size - 1; i++)
- {
- ps->arr[i] = ps->arr[i + 1];
- }
- ps->size--;//删除
- }
- //在指定位置之前插入数据
- void SLlnsert(SL* ps, int pos, SLDataType x)//pos:指定的位置 x:插入的数据
- {
- assert(ps);
- assert(pos >= 0 && pos <= ps->size);
- //插入数据:空间够不够
- SLCheckCapacity(ps);
- //让pos及之后的数据整体往后挪动一位
- for (int i = ps->size; i > pos; i--)//从后往前挪动
- {
- ps->arr[i] = ps->arr[i - 1];//arr[pos+1]=arr[pos] 最后下标为pos位置为空
- }
- ps->arr[pos] = x;//在pos位置插入数据
- ps->size++;
- }
- //删除指定位置的数据
- void SLErase(SL* ps, int pos)
- {
- assert(ps);
- assert(pos >= 0 && pos < ps->size);
- for (int i = pos; i < ps->size - 1; i++)
- {
- ps->arr[i] = ps->arr[i + 1];//pos位置后的数据全部往前挪动一位
- }
- ps->size--;
- }
-
- //查找
- int SLFind(SL* ps, SLDataType x)
- {
- assert(ps);
- for (int i = 0; i < ps->size; i++)
- {
- if (ps->arr[i] == x)
- {
- //找到了
- return i;
- }
- }
- //没有找到
- return -1;
- }
test.c
- #include<SeqList.h>
- void SLTest01()//测试
- {
- SL sl;
- //初始化
- SLlnit(&sl);
- //尾插
- SLPushBack(&sl, 1);
-
- //打印顺序表
- SLprint(sl);
- //头插
- SLPushFront(&sl,1);
- SLPushFront(&sl, 2);
- SLPushFront(&sl, 3);
- SLPushFront(&sl, 4);
-
- SLprint(sl);
-
- SLPopBack(&sl);
- SLprint(sl);
-
- //测试指定位置之前插入数据
- SLlnsert(&sl, 3, 90);
- SLprint(sl);
- //删除指定位置的数据
- SLErase(&sl, 4);
- SLprint(sl);
-
- int a=SLFind(&sl, 40);
- if (a >= 0)
- {
- printf("找到了,下标是:%d\n", a);
- }
- else
- {
- printf("没找到\n");
- }
- SLDestroy(&sl);
-
- }
- int main()
- {
- SLTest01();
- return 0;
- }
感谢观看,再见