前沿
我们如何把现实中大量复杂的数据保存到主存储器(内存)中呢?为了解决这个问题,我们出了数据结构的学科,专门研究----个体的存储+个体关系的存储。所以当我们要解决问题时,首先要先解决的是如何把这些问题转换成数据,先保存到我们的主存中。
线性结构
什么是线性结构呢? 就是把所有的结点用一根直线穿起来
线性结构主要分为2种
连续存储【数组】
- 什么叫数组?
元素类型相同,大小相等(数组传参,只有传进去首地址和长度就行)
数组的优缺点
- 优点
存取速度快
- 缺点
事先必须知道数组的长度
插入删除元素很慢
空间通常是有限制的
需要大块连续的存储块
插入删除元素的效率很低
- 优点
- 什么叫数组?
离散存储【链表】
定义:
- n个节点离散分配
- 彼此通过指针相连
- 每个节点只有一个前驱节点,每个节点只有一个后续节点
- 首节点没有前驱节点,尾节点没有后续节点
数组和链表的排序
我们来看个数组和链表排序的伪代码
//数组排序
void sort_arr(struct Arr * pArr)
{
int i, j, t;
int len = length_list(pArr);
for (i=0; i<len-1; ++i)
{
for (j=i+1; j<len; ++j)
{
if (pArr->pBase[i] > pArr->pBase[j])
{
t = pArr->pBase[i];
pArr->pBase[i] = pArr->pBase[j];
pArr->pBase[j] = t;
}
}
}
}
//链表排序
void sort_list(struct Arr * pHead)
{
int i, j, t;
int len = length_list(pHead);
struct Arr * p, q;
for (i=0,p=pHead->pNext; i<len-1; ++i,p=p->pNext)
{
for (j=i+1,q=p->pNext; j<len; ++j,q=q->pNext)
{
if (p->data > q->data) //等价于 a[i] > a[j]
{
t = p->data;//等价于: t = a[i];
p->data = q->data; //等价于: a[i] = a[j];
q->data = t; //等价于: a[j] = t;
}
}
}
return;
}
在我们看来数组和链表的存储方式是不同的
数组可以有a[++i] 来指向下个元素
链表则是 p = p->next
来指向下个元素
但从广义上来说 算法说与数据的存储方式无关的,我们可以对链表进行一个封装也可以实现a[++i]指向下个元素的操作。不同的存储方式,达到操作方式是相同的。
动态分配内存
当我们要创建一个节点的时候,就需要动态来分配内存
int main(void)
{
int p;
int *m = (int*)malloc(100);
}
在代码中静态变量p是在栈中分配,有操作系统自动分配和释放,而 (int*)malloc(100)
执行之后将在堆中分配100字节的内存。这个操作系统并不会释放,必须要手动使用 free()
来释放内存。java 中变成垃圾内存则会自动释放,但是C和C++则不会,所以要手动释放,否则会引起内存泄露。
致谢
感谢你看完这篇文章,有什么不对的地方欢迎指出,谢谢🙏
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。