【极简数据结构】快速了解并实现顺序表,速通玩家的最爱_数据结构速通

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

{
	psl->array[end + 1] = psl->array[end];
	end--;
}
//此时,array[0]被挪到后一位
psl->array[0] = x;
psl->size++;

}


**🔑解读:**


① 插入要考虑是否需要扩容,头插和尾插都需要扩容,我们可以将扩容操作封装为一个SeqListCheckCapacity函数,再在头插和尾插中复用。  
 ② 顺序表的数据是从头开始连续存储的。所以顺序表实现头插,需要将所有元素往后挪动1位。`int end = psl->size - 1;` 按psl->array[end]、psl->array[end - 1]…的顺序依次往后挪1位


#### ⚡优化顺序表 尾删


在尾插中复用扩容



📁SeqList.c
//顺序表 尾插
void SeqListPushBack(SL* psl, SLDateType x)
{
SeqListCheckCapacity(psl);//复用扩容函数
psl->array[psl->size] = x;
psl->size++;
}


优化后可读性提高!


#### 顺序表 头删



📁SeqList.c
//顺序表 头删
void SeqListPopFront(SL* psl)
{
assert(psl->size > 0);
int begin = 1;
while (begin < psl->size)
{
psl->array[begin - 1] = psl->array[begin];
begin++;
}
psl->size–;
}


**🔑解读:**  
 ① 删除需要考虑判空  
 ② `int begin = 1;` 按psl->array[1]、psl->array[2]…的顺序依次往前挪1位,最后`psl->size--;`


#### 顺序表 查找



📁SeqList.c
//顺序表 查找
int SeqListFind(SL* psl,SLDateType x)
{
//数组下标从0开始
int i = 0;
for (i = 0; i < psl->size; i++)
{
if (psl->array[i] == x)
{
return i;
}
}
//没找到
return -1;
}


**🔑解读:**  
 比较简单,for循环依次遍历顺序表 若 `psl->array[i] == x` ,则返回下标 `i`;没找到就返回 `-1`。  
 时间复杂度为`O(N)`。可以尝试写一个二分查找算法的接口函数实现,但前提要排序。


#### 顺序表 任意pos位置插入


前面学习了顺序表的头插和尾插,我们能不能在任意的pos位置插入呢?这得考虑考虑!


![在这里插入图片描述](https://img-blog.csdnimg.cn/0f863ce7e60f45cba63c1b2466026f6a.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5aSn54yp54yp77yB,size_20,color_FFFFFF,t_70,g_se,x_16)  
 因此我们要对pos进行条件限定。另外,插入就得考虑是否需要扩容。



📁SeqList.c
//顺序表 任意pos位置插入
int SeqListInsert(SL* psl, int pos, SLDateType x)
{
//插入的pos位置有区域约束

//1.温柔方法
/\* if (pos < 0 && pos > psl->size)

{
printf(“pos invalidd(pos非法!)\n”);
return;
}*/

//2.暴力方法
assert(pos >= 0 && pos <= psl->size);

//凡是插入,考虑是否需要扩容
SeqListCheckCapacity(psl);

//挪数据
int end = psl->size - 1;
while (end >= pos)
{
	psl->array[end + 1] = psl->array[end];
	end--;
}

//正式插入
psl->array[pos] = x;
psl->size++;

}


**🔑解读:**  
 思路类似头插,只是while循环的终止条件发生变化。


#### 🔱对头插函数和尾插函数的优化


SeqListInsert函数可以在任意pos位置插入数据,当然包括了头部和尾部。因此我们可以在头插和尾插函数中复用SeqListInsert函数。真是妙极了!


**头插函数复用SeqListInsert函数**



//顺序表 头插(复用SeqListInsert函数)
void SeqListPushFront(SL* psl, SLDataType x)
{
SeqListInsert(psl, 0, x);
}


**尾插函数复用SeqListInsert函数**



//顺序表 尾插(复用SeqListInsert函数
void SeqListPushBack(SL* psl, SLDataType x)
{
SeqListInsert(psl, psl->size, x);
}


#### 顺序表 任意pos位置删除


① 类似任意pos位置插入,我们也可以在pos位置删除。同样pos位置是有条件限定的,特别的是注意psl->size无有效数据,不可删除。


② 删除就得考虑判空



//顺序表 任意pos位置删除
void SeqListEarse(SL* psl, int pos)
{
//删除和插入一样:有区域约束,不可任意访问删除

//1.温柔方法
/\* if (pos < 0 && pos >= 0)

{
printf(“pos invalidd!\n”);
return;
}*/

//2.暴力处理
assert(pos >= 0 && pos < psl->size);

int begin = pos;
while (begin < psl->size)
{
	psl->array[begin] = psl->array[begin + 1];
	begin++;
}
psl->size--;

}


**🔑解读:**  
 思路类似头删。


#### 🔱对头删函数和尾删函数的优化


同样的道理,头删和尾删也可以复用SeqListEarse函数  
 **头删函数复用SeqListEarse函数**



//顺序表 头删(复用SeqListEarse函数)
void SeqListPopFront(SL* psl)
{
SeqListEarse(psl, 0);
}


**尾删函数复用SeqListEarse函数**



//顺序表 尾删(复用SeqListEarse函数)
void SeqListPopBack(SL* psl)
{
SeqListEarse(psl, psl->size - 1);
}


到此,想必速通万家们已经知道如何快速实现顺序表了!  
 我们把SeqListInsert函数和SeqListEarse函数写了,就相当于把头插尾插、头删尾删写了(复用即可)




---


## 四、完整代码


### 📁SeqList.h



#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

创建静态顺序表
//#define N 10
//typedef int SLDateType;
//
//typedef struct SeqList
//{
// SLDateType array[N];//定长数组
// SLDateType size;//有效个数
//}SL;

//创建动态顺序表
typedef int SLDateType;
typedef struct SeqList
{
SLDateType* array;//指向动态开辟的数组
SLDateType size;//有效个数
SLDateType capacity;//容量空间大小
}SL;

/*接口函数*/

//顺序表 初始化
void SeqListInit(SL* psl);

//顺序表 尾插
void SeqListPushBack(SL* psl, SLDateType x);

//顺序表 打印
void SeqListPrint(SL* psl);

//顺序表 销毁
void SeqListDestory(SL* psl);

//顺序表 尾删
void SeqListPopBack(SL* psl);

//顺序表 头插
void SeqListPushFront(SL* psl,SLDateType x);

//顺序表 判断扩容
void SeqListCheckCapacity(SL* psl);

//顺序表 头删
void SeqListPopFront(SL* psl);

//顺序表 查找
int SeqListFind(SL* psl,SLDateType x);

//顺序表 任意pos位置插入
int SeqListInsert(SL* psl, int pos, SLDateType x);

//顺序表 任意pos位置删除
void SeqListEarse(SL* psl, int pos);


### 📁SeqList.c



#include"SeqList.h"

//顺序表 初始化
void SeqListInit(SL* psl)
{
psl->array = NULL;
psl->size = psl->capacity = 0;
}

//顺序表 尾插
void SeqListPushBack(SL* psl, SLDateType x)
{
//插入
SeqListCheckCapacity(psl);
psl->array[psl->size] = x;
psl->size++;
}

//顺序表 打印
void SeqListPrint(SL* psl)
{
int i = 0;
for (i = 0; i < psl->size; i++)
{
printf(“%d “, psl->array[i]);
}
printf(”\n”);
}

//顺序表 销毁
void SeqListDestory(SL* psl)
{
free(psl->array);
psl->array = NULL;
psl->capacity = psl->size = 0;
}

//顺序表 尾删
void SeqListPopBack(SL* psl)
{
1.温柔手法
//if (psl->size > 0)
//{
// psl->size–;
//}

//没有考虑到"删过头"的情况,会非法访问
psl->array[psl->size - 1] = 0;
//psl->size--;

//2.暴力手法
//assert(psl->size > 0);
//psl->size--;

//复用SeqListEarse
SeqListEarse(psl, psl->size - 1);

}

//顺序表 头插
void SeqListPushFront(SL* psl, SLDateType x)
{
SeqListCheckCapacity(psl);
int end = psl->size - 1;
while (end >= 0)
{
psl->array[end + 1] = psl->array[end];
end–;
}

//此时,array[0]被挪到后一位
psl->array[0] = x;
psl->size++;

}

//顺序表 判断扩容
void SeqListCheckCapacity(SL* psl)
{
if (psl->size == psl->capacity)//判断空间是否足够
{
//扩容
SLDateType newcapacity = psl->capacity == 0 ? 4 : psl->capacity * 2;
SLDateType* tmp = (SLDateType*)realloc(psl->array, newcapacity * sizeof(SLDateType));;
if (tmp == NULL)
{
printf(“扩容失败!\n”);
exit(-1);
}

	//扩容后需要更新的
	psl->array = tmp;
	psl->capacity = newcapacity;
}

}

//顺序表 头删
void SeqListPopFront(SL* psl)
{
//assert(psl->size > 0);
//int begin = 1;
//while (beginsize)
//{
// psl->array[begin - 1] = psl->array[begin];
// begin++;
//}
//psl->size–;

//复用SeqListEarse
SeqListEarse(psl, 0);

}

//顺序表 查找
int SeqListFind(SL* psl,SLDateType x)
{
//数组下标从0开始
int i = 0;
for (i = 0; i < psl->size; i++)
{
if (psl->array[i] == x)
{
return i;
}
}

//没找到
return -1;

}

//顺序表 任意pos位置插入
int SeqListInsert(SL* psl, int pos, SLDateType x)
{
//插入有区域约束

//温柔处理:
/\* if (pos < 0 && pos > psl->size)

{
printf(“pos invalidd(pos非法!)\n”);
return;
}*/

//暴力解决
assert(pos >= 0 && pos <= psl->size);

//凡是插入,考虑是否需要扩容
SeqListCheckCapacity(psl);

//挪数据
int end = psl->size - 1;
while (end>=pos)
{
	psl->array[end + 1] = psl->array[end];
	end--;
}

//正式插入
psl->array[pos] = x;
psl->size++;

}

//顺序表 任意pos位置删除
void SeqListEarse(SL* psl, int pos)
{
//删除和插入一样:有区域约束,不可任意访问删除

//温柔处理
/\* if (pos < 0 && pos >= 0)

{
printf(“pos invalidd(pos非法!)\n”);
return;
}*/

//暴力处理
assert(pos >= 0 && pos < psl->size);

int begin = pos;
while (begin < psl->size)
{
	psl->array[begin] = psl->array[begin + 1];
	begin++;
}

psl->size--;

}


### 📁Test.c



#include"SeqList.h"

void TestSeqList1()
{
SL sl;
SeqListInit(&sl);
SeqListPushBack(&sl, 1);
SeqListPushBack(&sl, 2);
SeqListPushBack(&sl, 3);
SeqListPushBack(&sl, 4);
SeqListPushBack(&sl, 5);
SeqListPrint(&sl);

//SeqListPopBack(&sl);
//SeqListPopBack(&sl);
//SeqListPopBack(&sl);
//SeqListPopBack(&sl);
//SeqListPopBack(&sl);
//SeqListPopBack(&sl);
//SeqListPrint(&sl);

//SeqListPushBack(&sl, 10);
//SeqListPushBack(&sl, 20);
//SeqListPrint(&sl);

//SeqListPushFront(&sl, 1);
//SeqListPushFront(&sl, 2);
//SeqListPushFront(&sl, 3);
//SeqListPushFront(&sl, 4);

//SeqListPrint(&sl);

//SeqListDestory(&sl);

}

void TestSeqList2()
{
SL sl;
SeqListInit(&sl);

SeqListPushBack(&sl, 1);
SeqListPushBack(&sl, 2);
SeqListPushBack(&sl, 3);
SeqListPushBack(&sl, 4);

SeqListPrint(&sl);

SeqListPushFront(&sl, 1);
SeqListPushFront(&sl, 2);
SeqListPushFront(&sl, 3);
SeqListPushFront(&sl, 4);
SeqListPrint(&sl);

//SeqListDestory(&sl);

}

void TestSeqList3()
{
SL sl;
SeqListInit(&sl);
SeqListPushBack(&sl, 1);
SeqListPushBack(&sl, 2);
SeqListPushBack(&sl, 3);
SeqListPushBack(&sl, 4);

SeqListPrint(&sl);

//int ret = SeqListFind(&sl, 3);
//if (ret == -1)
// printf("找不到!\n");
//else
// printf("找到了,下标为%d", ret);

SeqListInsert(&sl, 5, 5);
SeqListPrint(&sl);
SeqListDestory(&sl);

}

void TestSeqList4()
{
SL sl;
SeqListInit(&sl);
SeqListPushBack(&sl, 1);
SeqListPushBack(&sl, 2);
SeqListPushBack(&sl, 3);
SeqListPushBack(&sl, 4);
SeqListPushFront(&sl, 1);
SeqListPushFront(&sl, 2);
SeqListPushFront(&sl, 3);
SeqListPushFront(&sl, 4);

SeqListPrint(&sl);
SeqListPopFront(&sl);
SeqListPopBack(&sl);
SeqListPrint(&sl);

SeqListDestory(&sl);

}

int main()
{
//TestSeqList1();
//TestSeqList2();
//TestSeqList3();
TestSeqList4();
}




---


![在这里插入图片描述](https://img-blog.csdnimg.cn/a4c6e7902b9744db8378ab1b032ec6c4.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5aSn54yp54yp77yB,size_20,color_FFFFFF,t_70,g_se,x_16)  
 **简单的三连是对作者的最大支持!**  
 ![请添加图片描述](https://img-blog.csdnimg.cn/531569304f5f4e72a628b7c5d469be2d.gif)


![img](https://img-blog.csdnimg.cn/img_convert/3e56a79a26568fdc3171815c83caa329.png)
![img](https://img-blog.csdnimg.cn/img_convert/3d10f1a02dddb38187b9ec84c4d3ca99.png)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618668825)**

();
	TestSeqList4();
}


在这里插入图片描述
简单的三连是对作者的最大支持!
请添加图片描述

[外链图片转存中…(img-VCmgeUU2-1715790901083)]
[外链图片转存中…(img-GuAypbRL-1715790901083)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

  • 15
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值