线性结构:
- 顺序结构:在逻辑上是连续的,在物理存储上也是连续的;
- 链式结构:在逻辑上是连续的,在物理存储上是不连续的;
什么是顺序表?
顺序表是指用一组地址连续的存储单元依次存储线性表的数据元素。
顺序表的基本构成
注意:顺序表在存储时,必须从起始位置开始存储并且连续存储(和数组的很大的区别)。
顺序表的c语言结构设计
#define DEFAULTSIZE 10
typedef int ElemType;
typedef struct SqList
{
ElemType *data; // 指向用于存储ElemType类型的堆区空间的指针
int length; // 长度: 以存储的属于元素的个数
int size; // 空间的大小,记录的是能够存储的元素个数
}SqList;
顺序表的各项操作及其实现方法
初始化
void InitSqList(SqList *sq_list, int init_size)
{
if(sq_list==nullptr)exit(0); //首先要对指针判空;
int init_size=init_size>0?init_size:DEFAULTSIZE; //如果init_size不大于0,则为默认值;
sq_list->data=(ElemType *)malloc(sizeof(ElemType)*init_size);//动态申请空间;
if(data==nullptr)exit(0); //对申请的空间判空;
sq_list->length=0; //初始化length;
sq_list->size=init_size; //初始化size;
}
销毁
void DestroySqList(SqList *sq_list)
{
if (sq_list == nullptr) exit(0); //首先要对指针判空;
free(sq_list->data); //释放用动态内存申请的空间;
sq_list->data = nullptr; //释放完成将指针置空,防止出现野指针;
sq_list->length = sq_list->size = 0; //空间大小及元素个数都置0;
}
插入
插入有三种操作:头插法,尾插法,按位置插。在此只给出按位置插入的实现方法。
bool InsertSqListPos(SqList *sq_list, ElemType value, int pos)
{
if (sq_list == nullptr) exit(0); //首先要对指针判空;
if(pos<0||pos>sq_list->length) //判断pos是否合法;
{
printf("error");
return false;
}
if(!AppendSpace(sq_list))//判满,如果空间满了将进行扩容操作; sq_list->length == sq_list->size则满
{
printf("error");
return false;
}
for(int i=sq_list->length-1;i<pos;i--)
{
sq_list->data[i+1]=sq_list->data;
}
sq_list->data[pos]=value;
sq_list->length++;
return true;
}
扩容操作
static bool AppendSpace(sq_list) //扩容操作,加静态关键字是为了改变可见性;
{
int new_size=init_size*2 //将新空间扩充为原来的2倍;
ElemType new_space= (ElemType *)malloc(sizeof(ElemType)*new_size);//也可以用relloc扩容
if(new_space==nullptr)exit(0);
for(int i=0;i<sq_list->size;i++) //将原来空间的数据赋值进新的空间;
{
new_space[i]=sq_list->data[i];
}
free(sq_list->data); //释放原来的空间;
sq_list->data=new_space; //将指针指向新开辟的空间;
sq_list->size=new_size; //空间也为新开辟的长度;
}
删除
删除操作也对应三种:头删法,尾删法,按位置删,按值删。在此给出按位置删除和按值删除的实现方法。
按位置删除
bool DeleteSqListPos(SqList *sq_list, int pos)
{
if (sq_list == nullptr) exit(0); //首先要对指针判空;
if (pos < 0 || pos >= sq_list->length) //判断pos是否合法;
{
printf("Delete Fail: Pos is error\n");
return false;
}
if (Empty(sq_list)) //判断表是否为空;
{
printf("Delete Fail: SqList is Empty\n");
return false;
}
for (int i = pos; i < sq_list->length - 1; ++i) //若不为空,向前覆盖数据;
{
sq_list->data[i] = sq_list->data[i + 1];
}
sq_list->length--; //空间中存储的元素个数--
return true;
}
按指定值删除
删除顺序表中所有的value值: 时间复杂度为O(n), 空间复杂度为O(1)
- 定义两个变量,都指向起始位置,如果j下标对应的值和指定值相等j++,若不相等,则将下标为j的值赋给下标为i的值,i++,j++;
bool DeleteSqListValue(SqList *sq_list, ElemType value)
{
if (sq_list == nullptr) exit(0);
int i = 0, j = 0;
for (; j < sq_list->length; ++j)
{
if (sq_list->data[j] != value)
{
sq_list->data[i] = sq_list->data[j];
i++;
}
}
sq_list->length = i;
return true;
}
查找
int FindSqList(SqList *sq_list, ElemType value, Compare fun)
{
if (sq_list == nullptr) exit(0);
for (int i = 0; i < sq_list->length; ++i)
{
if (value==sq_list->data[i])
{
return i;
}
}
return -1;
}