⭐⭐⭐
新老博友们,感谢各位的阅读观看
期末考试&假期调整暂时的停更了两个多月
没有写博客为大家分享优质内容
还容各位博友多多的理解
美丽的八月重生之我归来
继续为大家分享内容
你我共同加油
一起努力
⭐⭐⭐
数据结构将以顺序表、链表、栈区、队列、二叉树、常见排序算法为主要内容展开学习
这里的数据结构是C语言实现的
道阻且长,行则将至
期待与你的交流学习
说在前面的话
数据结构是计算机存储、组织数据的方式,指的是相互之间存在的一种或多种特定关系的数据元素集合。数据本就是杂乱无章的,当我们对数据进行管理,形成一定的结构体系,数据才能有序存放便于我们存储和使用。数据结构将着力提升大家的算法能力,前期的C语言只是简单的为大家罗列了一些简答的知识点,现在我们将打开代码学习的魔幻大门,或许到这里我们才算得上代码学习刚入门。
前面我们已经学习了语言的基本内容:数组、指针、结构体、动态内存管等内容,这些都为今天我们学习数据结构做了铺垫,开启代码学习的新篇章——数据结构 ,在日常生活中我们要处理大量的数据,数据的统一管理,便于我们对数据增删查改,一些数据的内容过于庞大,高效便捷的管理需要我们对这些数据进行处理,那么如何处理好这些数据,就是我们接下来要学习的内容。
线性表
先来介绍线性表:
线性表在实际应用中非常广泛,比如数组、栈、队列等都可以看作是线性表的不同形式或在不同操作限制下的特殊结构,理解和掌握线性表对于深入学习数据结构至关重要。
物理结构:数据在内存中存储的一种形式
逻辑结构:人为想想出的一种数据结构形式,如线性关系、
线性表在逻辑结构上一定是线性的,在物理结构上不一定是线性的
今天介绍的顺序表是线性表的一种
顺序表(Sequence List)分类
顺序表:是⽤⼀段 物理地址连续的存储单元依次存储数据元素的线性结构,⼀般情况下采⽤数组存储。
顺序表的底层逻辑是数组,在数组的基础上增加了增删查改的功能完成对数组的封装。
可以这样理解顺序表:
顺序表=数组+增加数据+删除数据+修改数据+查找数据
前期学习的数组,我们知道数组可分为静态数组和动态数组,静态的数组的大小往往限制我们都数据进行一系列的操作,动态数组更受大家的青睐。
/*静态数组*/ int shuzu[10]={ } /*动态数组 动态数组内存开辟*/ int* shuzu /*确定好大小后再去申请*/
顺序表中对数组进行封装会使用结构体进行
静态顺序表
顺序表的空间已经确定,空间少了不够用空间多了浪费空间。
当空间过小会造成数据的丢失,空间远大于目前需求量需要资金的支持较大。
/*静态顺序表的定义*/ struct Seqlist { int arr[100]; //定长数组(在预估范围内操作) int size; //当前有效数据的个数 }; //静态顺序表 typedef int SLDataType //替换第四行的int #define N 10 typedef struct SeqList { SLDataType a[N]; //int被代替后 便于替换 int size; }SL;
动态顺序表
解决了静态数据表的痛点
/*动态顺序表的定义*/ struct Seqlist { int*shuzu; // int size; //有效数据的个数 实际空间大小 int capacity;//空间的大小 容器的能存量 }; //动态顺序表 typedf struct SeqList { SLDateType* a; int size; int capacity; }SL;
一键替换:这里使用typedef内容更换,方便代码量庞大时的替换数据的类型
动态数据表的实现
在实际的操作中通常我们需要三个文件来实现顺序表的功能:
一个.h头文件:头插文件用于存放顺序表的定义、接口声明、引用的头文件。等同于目录
两个.c源文件:顺序表各函数的实现
测试顺序表的各功能
我们创建了三个文件进行创建后进行初始化,并对初始化的第一步进行了测试(详见下图)
出现上述问题的原因在于对传值和传地址的理解
⭐传值:
实参保存的值拷贝一份给形参,实参和形参指向的是两块不同的地址,但保存的数据是一样的(形参是实参的值真实拷贝)
⭐传地址:
形参指向的就是实参的地址
初始化
头文件
#pragma once #include<stdio.h> #include<stdlib.h> typedef int SLDataTyre; //动态顺序表 typedef struct SeqList //等同于typedef struct SeqList SL; { SLDataTyre* arr; int size; //有效数据个数 int capacity;//空间大小 }SL; //初始化顺序表 void SLInit(SL* ps); //销毁顺序表 void SLDestory(SL*ps); //插入数据 void SLPushBack(SL* ps, SLDataTyre x); void SLPushFront(SL* ps, SL
源文件(实现功能文件)
#include"seqencelist.h" //初始化顺序表 void SLInit(SL* ps) { ps->arr = NULL; ps->size = 0; ps->capacity = 0; //初始的数组为空 有效数据和空间大小都为0 } //销毁顺序表 void SLDestory(SL* ps) { if (ps->arr)//(pa->arr!=NULL) { free(ps->arr);//释放空间 } ps->arr = NULL; ps->size = 0; ps->capacity = 0; } void SLPushBack(SL* ps, SLDataTyre x) { } void SLPushFront(SL* ps, SLDataTyre x) { }
源文件(测试文件)
#include"seqencelist.h" void SLText01() { SL s; SLInit(&s); } int main() { SLText01(); return 0; }
尾插
空间充足时
在顺序表的末尾加入数据,size++
空间不足时
新增容(增容一般是成倍数增加的),再在顺序表的末尾加入数据,size++
增容
增容操作本身就会对程序的性能进行一定的消耗,频繁的增容会导致程序的效率低下,采用成倍数的增加方式,一般情况下空间增量和数据的个数是正相关的
头插
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]; } //下标为0的位置 ps->arr[0] = x; ps->size++; }
⭐下一篇将带来顺序表的剩余内容和单链表