一、顺序表
顺序表是一种线性数据结构,它采用一段连续的内存空间来存储元素。顺序表中的元素按照一定的顺序排列,可以通过下标访问和修改元素。
顺序表的定义通常包含以下几个要素:
- 内存空间:顺序表需要一段连续的内存空间来存储元素。
- 元素个数:顺序表中元素的数量,也即顺序表的长度。
- 元素类型:顺序表可以存储不同类型的元素,如整数、浮点数、字符等。
- 元素存储方式:顺序表中元素存储的方式可以是顺序存储或链式存储。顺序存储是指将元素依次存放在内存空间中的连续位置,而链式存储则是通过指针相连的方式来存储元素。
顺序表可以通过下标访问和修改元素,具有随机访问的特点,但插入和删除元素时需要移动大量元素,时间复杂度较高。
二、分类
1.静态顺序表
代码如下(示例):
struct Seqlist
{
int arr[100];//定长数组
int size;//记录顺序表当前有效的数据个数
};
2.动态顺序表
代码如下(示例):
struct Seqlist
{
int* arr;
int size;//记录顺序表当前有效的数据个数
int capacity;//记录顺序表当前的空间大小
};
三.代码实现
1.初始化
#include"SeqList.h"
void SLInit(SL* ps)
{
ps->arr = NULL;
ps->size = ps->capacity = 0;
}
2.销毁
void SLDestroy(SL* ps)
{
if (ps->arr) //等价于 if(ps->arr != NULL)
{
free(ps->arr);
}
ps->arr = NULL;
ps->size = ps->capacity = 0;
}
3.尾插
void SLPushBack(SL* ps, SLDataType x)
{
温柔的解决方式
//if (ps == NULL)
//{
// return;
//}
assert(ps); //等价与assert(ps != NULL)
//ps->arr[ps->size] = x;
//++ps->size;
SLCheckCapacity(ps);//扩容
ps->arr[ps->size++] = x;
}
4.扩容
void SLCheckCapacity(SL* ps)
{
//插入数据之前先看空间够不够
if (ps->capacity == ps->size)
{
//申请空间
//malloc calloc realloc int arr[100] --->增容realloc
//三目表达式
int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
SLDataType* tmp = (SLDataType*)realloc(ps->arr, newCapacity * sizeof(SLDataType));//要申请多大的空间
if (tmp == NULL)
{
perror("realloc fail!");
exit(1);//直接退出程序,不再继续执行
}
//空间申请成功
ps->arr = tmp;
ps->capacity = newCapacity;
}
}
5.头插
void SLPushFront(SL* ps, SLDataType x)
{
assert(ps);
SLCheckCapacity(ps);
//先让顺序表中已有的数据整体往后挪动一位
for (int i = ps->size; i > 0; i--)
{
ps->arr[i] = ps->arr[i - 1];//arr[1] = arr[0]
}
ps->arr[0] = x;
ps->size++;
}
6.写一个打印
void SLPrint(SL s)
{
for (int i = 0; i < s.size; i++)
{
printf("%d ", s.arr[i]);
}
printf("\n");
}
7.尾删
void SLPopBack(SL* ps)
{
assert(ps);
assert(ps->size);
//顺序表不为空
//ps->arr[ps->size - 1] = -1;
--ps->size;
}
8.头删
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]; //arr[size-2] = arr[size-1]
}
ps->size--;
}
9.指定位置插入数据
void SLInsert(SL* ps,int pos,SLDataType x)
{
assert(ps);
assert(pos>=0&&pos<=ps->size);
SLCheckCapacity(ps);
for(int i=ps->size;i>pos;i--)
{
ps->arr[i]=ps->arr[i-1];
}
ps->arr[pos]=x;
ps->size++;
}
10.指定位置删除数据
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];
}
ps->size--;
}
11.查找
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;//没有找到
}
亲爱的读者们,非常感谢你们抽出宝贵的时间来阅读我的第一篇博客。我对此感到非常激动和荣幸。希望通过这个平台,我能够与大家分享我的见解和经验,为大家带来一些启发和帮助。谢谢你们的支持与关注,让我们一起开启这段博客之旅吧!
下一次与大家分享顺序表的应用-----通讯录。