线性结构分为连续存储和离散存储,连续存储有数组,离散存储有链表
在具体分析这些数据结构之前,应该了解Typedef
typedef
可以让数据机构的定义更加方便,
typedef int BigAsh;//用BigAsh代替int这个数字类型,可以直接用
// struct Student
// {
// int sid;
// char name[100];
// char sex;
// };//定义的时候要写全部的struct Student,太麻烦了
typedef struct Student
{
int sid;
char name[100];
char sex;
}ST; //这样写就更加方便,可以直接用ST来代替这个数据结构 struct Student
数组
- 优点:存取速度很快
- 缺点:插入删除元素很慢,效率低,空间通常有限,需要大块的内存块
元素类型相同,大小相等
struct Arr
{
int * pBase; //数组第一个元素的地址
int len; //数组能容纳的最大元素的个数
int cnt; //当前数组有效元素的个数
// int increment; //自动增长因子 内存的扩充是一个不太好办的事情 allocate()
};
//排序
void sort_list(PNODE pHead)
{
int t;
for(int i =0,i<len-1;++i){
for ( j = i+1; j < len; ++j){
if(a[i]>a[j]){
t = a[i];
a[i] = a[j];
a[j] = t;
}
}
}
}
泛型 :是一种利用某种技术达到的效果, 不同的存数方式,执行的操作是一样的,(例如C++函数重载)
这里的数组和链表排序时,抽象出来的逻辑既可以理解未泛型,本质的操作其实一样
链表
- 优点:空间没有限制,插入删除很快
- 缺点 :存取速度慢
多个节点离散分配,批次通过指针相连,每个节点有唯一的前驱和后继节点,链表头和尾部除外
需要区分 头节点,尾节点,首节点,头指针,尾指针,(头指针指向头节点,并不指向首节点)
头节点的存在目的是便于对链表进行操作
对于操作链表,至少需要一个参数(头指针)
链表有很多分类:单链表,双链表,循环链表,非循环链表
typedef struct Node
{
int data; //数据域
struct Node * pNext; //指针域
}NODE,*PNODE; // 顺序无所谓,NODE等价于struct Node,*NODE等价于struct Node *
在节点不用的时候,需要释放内存,否则会泄露内存,(比如链表删除)
r = p->pNext; //p所指结构体的pNext成员
p->pNext = p->pNext->pNext;
free (r); //free删除的是r指向结点所占的内存,并不是删除r本身所占内存
//r本身属于栈内存,r所指为堆内存(个人理解)
最终的代码存放在Github仓库 Linked List和Array部分
帮助很大
嘿嘿,感谢肯定,可以多多交流😊