首页 > 其他分享 >【线性表】之顺序表(C语言)

【线性表】之顺序表(C语言)

时间:2022-11-17 21:32:49浏览次数:41  
标签:ps 顺序 线性表 int SeqList C语言 void arry size


【线性表】之顺序表

  • ​​线性表​​
  • ​​顺序表​​
  • ​​结构定义​​
  • ​​初始化​​
  • ​​销毁​​
  • ​​打印​​
  • ​​扩展空间​​
  • ​​尾插​​
  • ​​头插​​
  • ​​尾删​​
  • ​​头删​​
  • ​​在指定位置插入数据​​
  • ​​删除指定位置数据​​
  • ​​查找​​
  • ​​修改​​

线性表

线性表(linear list)是n个具有相同特性元素的有限序列 。线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串…

线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。

顺序表

它是最简单的数据结构,也是最常用的数据结构——他的作用就是将数据存起来。

概念:顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。

顺序表一般可分为:

1.静态顺序表:使用定长数据存储。

2.动态顺序表:使用动态开辟的数组存储。

下面的代码实现的是动态顺序表

结构定义

typedef int SeqListDataType;
typedef struct SeqList
{
SeqListDataType* arry;//指向动态开辟的数组
int size;//数组中有效数据的个数(在数组中说就是最后一个数据的下一个位置,因为数组下标是从0开始的)
int capacity;//容量空间的大小
}SeqList;

【线性表】之顺序表(C语言)_数组

初始化

void SeqListInit(SeqList* ps)
{
ps->arry = NULL;//可以一上来就给空间,也可以不给空间
ps->size = 0;
ps->capacity = 0;
}

销毁

严格来说空间用完之后就要销毁,如果malloc开辟的空间不销毁就会存在内存泄漏。

void SeqListDestory(SeqList* ps)
{
free(ps->arry);
ps->arry = NULL;
ps->capacity = ps->size = 0;
}

打印

void SeqListPrint(SeqList* ps)
{
for (int i = 0; i < ps->size; i++)
{
printf("%d ", ps->arry[i]);
}
}

扩展空间

void SeqListCheckCapacity(SeqList* ps)
{
//如果数组满了——有效的数据个数等于空间容量的总大小
if (ps->size == ps->capacity)
{
//要注意如果满了,就进行扩容,在原来基础上*2,但是开始的空间是0,
//0*2还是0,所以开始插入的时候要加一个判断
//如果开始的空间是0,那么就给他赋值4,之后就不是0了,就给他*2
int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
//realloc扩充原来开辟好的空间
//如果原来的空间在原来的地方是空,那就他是直接申请一个新的空间就跟malloc是一样的。
SeqListDataType* tmp = (SeqListDataType*)realloc(ps->arry, newCapacity * sizeof(SeqListDataType));
//如果扩容失败,给予提示
if (tmp == NULL)
{
printf("realloc is fail!");
exit(-1);//退出
}
else
{
//把扩充好的数组传给arry
ps->arry = tmp;
ps->capacity = newCapacity;//空间容量大小
}
}
}

尾插

void SeqListPushBack(SeqList* ps,SeqListDataType x)
{
SeqListCheckCapacity(ps);
//顺序表中的数据要依次存储
ps->arry[ps->size] = x;
ps->size++;
}

头插

void SeqListPushFront(SeqList* ps, SeqListDataType x)
{
//同尾插-空间不够了需要增容
SeqListCheckCapacity(ps);
//从后开始挪
//注意初识条件-结束条件-迭代过程
//先找到最后一个位置
int end = ps->size - 1;
while (end >= 0)
{
ps->arry[end + 1] = ps->arry[end];
end--;
}
ps->arry[0] = x;
ps->size++;
}

尾删

void SeqListPopBack(SeqList* ps)
{
assert(ps->size > 0);//等于0直接报错,比较粗暴。
//下面这行代码没用,因为了顺序表中具体的数据个数是由size决定的
//把这个位置置 成0,万一这个位置本来就是0呢,或者这个位置的数据类型不是int,是double呢,置成0也不合适,没有意义。
//ps->arry[ps->size - 1] = 0;
ps->size--;
//可以复用删除,头删、头插、尾插、同理
//SeqListErase(ps,ps->size);
}

头删

void SeqListPopFront(SeqList* ps)
{
//检查一下还有没有元素,没有就别删了
assert(ps->size > 0);
int start = 1;
//就是用后面的元素将前面的元素给覆盖了,每次消失的都是第一个,其他的依次向前推
while (start < ps->size)
{
ps->arry[start - 1] = ps->arry[start];
start++;
}
ps->size--;
}

在指定位置插入数据

void SeqListInsert(SeqList* ps, int pos, SeqListDataType x)
{
assert(pos < ps->size);//大于就报错
//思路:先创建空间,利用循环找到pos这个位置,将元素放入数组,size+1
//创建空间
SeqListCheckCapacity(ps);
//找到最后一个元素
int end = ps->size - 1;
while (end >= pos)
{
//依次往后推移一位,
ps->arry[end + 1] = ps->arry[end];
end--;
}
ps->arry[pos] = x;
ps->capacity++;
}

删除指定位置数据

void SeqListErase(SeqList* ps, int pos)
{
assert(pos < ps->size);
//被删除元素后面的位置
int start = pos + 1;
while (start < ps->size)
{
ps->arry[start - 1] = ps->arry[start];
start++;
}
ps->size--;
}

查找

int SeqListFind(SeqList* ps, SeqListDataType x)
{
//找到返回下标,找不到返回-1
for (int i = 0; i < ps->size; i++)
{
if (ps->arry[i] == x)
{
return i;
}
}
return -1;
}

修改

void SeqListModity(SeqList* ps, int pos, SeqListDataType x)
{
assert(pos < ps->size);
ps->arry[pos] = x;
}


标签:ps,顺序,线性表,int,SeqList,C语言,void,arry,size
From: https://blog.51cto.com/u_15333750/5866181

相关文章

  • LeetCode刷题(4)【移除元素&合并两个有序数组】(C语言)(含图解)
    移除元素典型双指针玩法。27.移除元素-力扣(LeetCode)(leetcode-cn.com)我们都会想到这样的解法:从前面依次往后推,是val就将该数据后面的元素依次覆盖上来,但是这样的时间复......
  • LeetCode刷题(5)【链表】【环形链表II】(C语言)
    环形链表I​​LeetCode刷题(3)【链表】【环形链表】&扩展_半生瓜のblog-CSDN博客​​环形链表II142.环形链表II-力扣(LeetCode)(leetcode-cn.com)这个题写起来不难,但是证......
  • 【线性表】之栈(C语言)
    栈​​回顾​​​​栈​​​​结构定义​​​​初始化​​​​销毁​​​​入栈​​​​出栈​​​​返回栈顶元素​​​​返回栈中元素个数​​​​判断栈是否为空​​​​......
  • 【线性表】之队列(C语言)
    队列​​队列的概念​​​​结构定义​​​​初始化​​​​销毁​​​​队尾入​​​​队头出​​​​队头出​​​​队头数据​​​​队尾数据​​​​是否为空​​​​返......
  • LeetCode刷题(7)【栈&队列】用队列实现栈(C语言)
    用队列实现栈225.用队列实现栈-力扣(LeetCode)(leetcode-cn.com)目的:用队列实现栈,从先进先出——>先进后出,1234这四个数据依次从队列1的队尾进入,要让4先出,一个队列是无法......
  • LeetCode刷题(2)【链表】【合链表&链表的中间结点】(C语言)
    我的小站——半生瓜のblog快慢指针问题:思路:定义一个快指针和一个慢指针,快指针走到结束的时候,慢指针刚好走到一半。链表的中间结点。876.链表的中间结点-力扣(LeetCode)(le......
  • LeetCode刷题(3)【链表】【环形链表】&扩展(C语言)
    我的小站——半生瓜のblog环形链表141.环形链表-力扣(LeetCode)(leetcode-cn.com)什么是链表带环:链表的最后一个元素不指向空而指向前面的某个结点。思路:快慢指针,慢指针走......
  • C语言二级错题积累(4)
    在栈中,栈项指针的动态变化决定栈中元素的个数。详细设计的人物是为软件结构体中的每一个模块确定实现算法和局部数据结构,用某种选定的表达工具表示算法和数据结构的细节。扇......
  • C语言二级错题积累(5)
    常用的连续存储管理技术有固定分区存储管理和可变分区存储管理。程序流程图中带有箭头的线段表示的是控制流。若二叉树没有叶子结点,则为空二叉树。带链栈的栈底指针是随栈的......
  • C语言实现贪吃蛇小程序
    参考视频https://www.bilibili.com/video/BV1LN41197zV?from=search&seid=15462998985727977257代码有点缺陷:1.食物有可能会生成在吃不到的地方2.吃掉食物的音效添加失败//......