C语言顺序表

顺序表的底层逻辑是数组,顺序表是线性表的一种,

线性表具有: 物理结构不一定连续 

                       逻辑结构一定连续  

顺序表的特征:物理和逻辑结构都是连续的 

一个动态顺序的的写法 

 这两种结构体类型重命名类型一样

初始化和回收释放

free 完后记得置为NULL 

顺序表的扩容

为什么是 8 * ,我们应拆开分析,8 = 2 * 4,4代表了原本空间的大小,乘 2就是这个空间翻倍了。

顺序的增删查改

尾插

        尾插(从末尾插入数据)

两种情况:

        1、尾部的空足够直接插入就行

        2、尾部空间不够,那么就需要用realloc去扩容

上面为判断指针是否为空,内存大小够不够,加开辟空间及判断空间是否成功开辟

void Check_size(LQS* che)//判断空间大小
{
	assert(che);
	LQStype* ret = NULL;
	if (che->capacity == che->size)
	{
		ret = (LQStype*)realloc(che->arr, 8 * (che->capacity));
		if (ret == NULL)
		{
			perror("realloc");
			exit(EOF);
		}
		che->capacity = che->capacity * 2;
		che->arr = ret;
	}
}
void LQS_pushback(LQS* D,LQStype a)//尾插
{
	Check_size(D);
	(D->arr)[D->size++] = a;
	
}

头插

头插也要考虑,空间是否足够的情况,所以调用了,Check_pushfront 函数

        在执行头插钱我们需要把每一位向后挪动一位,再插入(*(E->arr)= e),随后size++表示被占用的空间大小

void LQS_pushfront(LQS* E,LQStype e)
{
	Check_size(E);
	int Size = E->size;
	while (Size>0)
	{
		(E->arr)[Size] = (E->arr)[Size-1];
		//(E->arr)[Size] = (E->arr)[--Size]
		//如果是这条语句,Size先减 1 等于 0
		//arr[0] = arr[0] 
		//等于没动如果这样执行到头插语句时,就会把 5 给覆盖掉

		Size--;
	}
	*(E->arr) = e;
	(E->size)++;
}

尾删

尾删我们只需要判断数组不为空,和size不为0,为0有什么好删的
 

void LQS_Bdet(LQS* F)//尾删
{
	assert(F->arr);
	assert(F->size);
	(F->size)--;
}

 头删

        头删我们只需要将每一位有效数据向前挪动一位,然后size--

考虑到size等于1的情况如果只用下面的循环为1的时候删不了,所以单独拿出来考虑。

void LQS_Fdet(LQS* G)//头删
{	//头删我们只需要将每一位向前挪动一位就行
	assert(G->arr);
	assert(G->size);
	int i = 0;
	if (G->size == 1)
	{
		G->size--;
	}
	else
	{
		for (i = 1; i < G->size; i++)
		{
			(G->arr)[i-1] = (G->arr)[i];
		}
		G->size--;
	}
	

}

指定位置插入

        尾插 5 5 5 5

        当头插8的时候就需要开辟空间了,结果是 8 5 5 5 5

        然后尾删一个5 ,头删一个 8,剩下 5 5 5 5

        再第二个数据前插入 4 得,5 4 5 5,代码运行正确

void LQS_alter(LQS* I, int pos, LQStype a)//指定位置前插入
{
	//我这里的pos表示第几个数据,不表示下标
	assert(I);
	if (pos < 0 || pos > I->size)
	{
		printf("该位置不存在\n");
		return;
	}
	//既然是插入那么就得考虑空间问题
	Check_size(I);
	int i = I->size;
	for (i; i >= pos; i--)
	{
		I->arr[i] = I->arr[i - 1];

	}
	I->arr[i] = a;
	I->size++;
	
}

指定位置删除

void LQS_Zdet(LQS* J, int pos)//指定位置删除
{
	assert(J);
	if (pos < 0 || pos > J->size)
	{
		printf("该位置不存在\n");
		return;
	}
	//只需要将指定位置后的每一位向前挪动然后size--

	int i = pos;
	for (i; i < J->size; i++)
	{
		J->arr[i-1] = J->arr[i];
	}
	J->size--;

}

查找

太简单啦,遍历就完啦


void LQS_find(LQS* H,LQStype h)//查找
{
	assert(H);
	assert(H->size);
	int i = 0;
	for (i; i < H->size; i++)
	{
		if (H->arr[i] == h)
		{
			printf("找到了!!!下标为:%d\n", i);
		}
	}
	if (i == H->size)
	{
		printf("找不到!!!\n");
	}

}

销毁

void SListDesTroy(SLN ** pphead)
{
	assert(pphead && *pphead);
	SLN* cpphead = *pphead;
	while (*pphead)
	{
		cpphead = *pphead;
		*pphead = (*pphead)->Next;
		free(cpphead);
		cpphead = NULL;
	}
}

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值