===数据结构===
数据结构:直白的讲,就是研究数据的存储方式。
数据存储只有一个目的,就是为了方便后期对数据的再利用。
对于存储之间具有复杂关系的数据,如果还是用变量或数组来存储,数据存储是没有问题的,但是无法体现数据之间的逻辑关系,后期无法使用。
数据结构是为了解决如何存储具有复杂关系的数据更有助于后期对数据的再利用。
===
数据结构包括:线性表,树结构,图结构。
线性表包括: 顺序表、链表、栈、队列
树结构包括:普通树、二叉树、线索二叉树等
图结构包括:图存储结构。
===线性表
线性表结构存储的数据往往是可以依次排列的,前面和后面都仅有一个数据,具备这种一对一关系的数据就可以使用线性表来存储。
线性表分为顺序表和 链表。
顺序表:常用的数组。 顺序表结构的底层实现借助的就是数组,对于初学者而言,可以把顺序表完全等价为数组,但实际不是这样。
链表:我们知道,使用顺序表(底层实现靠数组)时,需要提前申请一定大小的存储空间,这块存储空间的物理地址是连续的。链表则完全不同,使用链表存储数据时,是随用随申请,因此数据的存储位置是相互分离的,换句话说,数据的存储位置是随机的。
为了给各个数据块建立“依次排列”的关系,链表给各数据块增设一个指针,每个数据块的指针都指向下一个数据块(最后一个数据块的指针指向NULL),这样,看似毫无关系的数据块就建立了“依次排列”的关系,也就形成了链表。
===栈和队列===
栈和队列隶属于线性表,是特殊的线性表,因为他们对线性表中元素的进出做了明确的要求。
栈中的元素只能从线性表的一端进出,另一端封死。且要遵循“先入后出”的原则,即先进栈的元素后出栈。
队列:队列中的元素只能从线性表的一端进,从另一端出,且要遵循“先入后出”的特点,即先进队列的元素也要先出队列。
=====树存储结构===
树存储结构适合存储具有“一对多”关系的数据。
=====图存储结构===
图存储结构适合存储具有“多对多”关系的数据。
===算法的时间复杂度和空间复杂度===
算法,即解决问题的办法。同一个问题,使用不同的算法,虽然得到的结果相同,但是耗费的时间和资源是不同的。
算法的要求:
准确性:必须能够解决这个问题。
健壮性:在任何情况下不能奔溃。
效率性: 时间复杂度和空间复杂度。【算法运行时间和运行算法所需的内存空间大小。】
====时间复杂度的排序: O(1) < O(logN) < O(n) < O(n方) < O (2的N次方,指数阶)
=====线性表详解====
线性表:数据结构中最简单的一种存储结构,专门用来存储逻辑关系为:一对一的数据。
线性表,基于数据在实际物理空间中的存储状态,又可细分为顺序表和链表。
数据存储的成功与否,取决于是否能将数据完整地复原成它本来的样子。
将具有“一对一”关系的数据线性地存储到物理空间中,这种存储结构就称为线性存储结构。
使用线性表存储的结构,如同向数组中存储数据那样,要求数据类型必须一致。
===前驱和后继===
在数据结构中,一组数据中的每个个体被称为:数据元素。
某一元素的左侧相邻元素称为:直接前驱,位于此元素左侧的所有元素都统称为:前驱元素。
某一元素右侧相邻元素称为:直接后继,位于此元素右侧的所有元素都统称为:后继元素。
===顺序表的初始化===
使用顺序表存储数据之前,除了要申请足够大小的物理空间之外,为了方便后期使用表中的数据,顺序表还需要实时记录以下两项数据:
1. 顺序表申请的存储容量。
2. 顺序表的长度,也就是表中存储数据元素的个数。
==因此,我们需要自定义顺序表,C语言实现代码如下:
typedef struct Table {
int *head: // 声明了一个名为head 的长度不确定的数组,也叫:动态数组。
int length; // 记录当前顺序表的长度
int size; // 记录顺序表分配的存储容量
}table;
注意: head 是我们声明的一个未初始化的动态数组。
====建立一个顺序表===
1. 给head 动态数据申请足够大小的物理空间;
2. 给size 和length 赋初始值;
===示例代码===
#define Size 5 // 对size 进行宏定义,表示顺序表申请空间的大小
table initTable() {
table t;
t.head = (int*) malloc();
}