数据结构
1.定义
一组用来保存一种或者多种特定关系的数据的集合(组织和存储数据)
程序的设计:将现实中大量而复杂的问题以特定的数据类型和特定的存储结构存储在内存中,
并在此基础上实现某个特定的功能的操作;
程序 = 数据结构 + 算法
2.数据与数据之间的关系
数据的逻辑结构:数据元素与元素之间的关系
集合:关系平等
线性结构:元素之间一对一的关系(表(数组,链表),队列。栈。。。)
树型结构:元素之间一对多的关系(二叉树)
图形结构:元素之间多对多的关系(网状结构)
数据的物理结构:数据的逻辑结构在计算机内存中的存储形式
顺序存储:采用一段连续的内存空间保存元素
优点:空间连续,访问方便
缺点:插入删除需要移动大量的元素
需要预分配内存空间
容易造成存储空间碎片
链式存储:采用一组非连续的内存空间保存元素
缺点:访问元素效率低
优点:插入和删除数据方便
不需要预分配内存
索引存储:通过关键字构建索引表,通过索引表来来找到数据的存储位置
散列存储(哈希存储):将数据元素的存储位置与关键码之间建立确定对
应关系从而实现查找的存储方式
3. 储备知识
指针
结构体
动态内存分配
链式
单向链表
双向链表
栈
队列
二叉树:
哈希表
算法
单向链表
有头链表
无头链表
双向链表中存储的数据的数据类型
双向链表链表结点类型
数据域
指针域:保存上一个结点的地址
描述双向链表的标签类型
保存头结点地址
当前结点的个数
用来保存出栈数据的地址
树:由n个节点组成的有限集
有一个根节点;
其他节点只有一个前驱节点,但可以有多个后继节点。(一对多)
n = 0, 空树
叶子节点(终端结点):只有前驱结点没有后继结点
非叶子节点(分支节点):
度:子节点的个数称之为度
树的度:树中各节点度的最大值
深度:从根节点到最底层节点的层数
森林:n个互不相交的树的集合
二叉树:任意一个节点的子节点个数不能超过2个(树的度为2),且子节点的位置不可更改。
满二叉树:在不增加树的层数的前提下,无法再增加一个节点的二叉树
特性:满二叉树第K层有2^(k-1)个节点
K层满二叉树总共有2^k-1个节点
完全二叉树:只是删除了满二叉树最底层最右边的连续若干个节点,形成了完全二叉树
满二叉树 ==> 完全二叉树
完全二叉树 =/=> 满二叉树
二叉树的遍历:
前序遍历:根 左 右
中序遍历:左 根 右
后续遍历:左 右 根
层序遍历:逐层向下遍历
二叉树的遍历特性:
已知前序遍历序列和中序遍历序列,可以唯一确定一棵二叉树;
已知后序遍历序列和中序遍历序列,可以唯一确定一棵二叉树;
Hash
哈希表:
哈希算法:
在记录的存储位置和它的关键字之间建立一种去特定的对应关系,使得每个关键字key对应一个存储位置;
查找时,根据确定的对应关系,找到给定的key的映射。
记录的存储位置 = f(关键字)
我们把这种关系f称为哈希函数(散列函数);
采用这种散列技术将记录存储在一块连续的存储空间,这块连续存储开空间称为哈希表或散列表。
存储时,通过散列函数计算出记录的散列地址;
查找时,根据同样的散列函数计算记录的散列地址,并按此散列地址访问记录。
算法:
解决特定问题求解步骤
算法的设计,
1.正确性,
语法正确
合法的输入能得到合理的结果。
对非法的输入,给出满足要求的规格说明
对精心选择,甚至刁难的测试都能正常运行,结果正确
2. 可读性,便于交流,阅读,理解 高内聚 低耦合
3. 健壮性,输入非法数据,能进行相应的处理,而不是产生异常
4. 高效率(时间复杂度)
5. 低存储(空间复杂度)
算法时间复杂度
执行这个算法所花时间的度量
将数据量增长和时间增长用函数表示出来,这个函数就叫做时间复杂度。
一般用大O表示法:O(n)-----时间复杂度是关于数据n的一个函数
随着n的增加,时间复杂度增长较慢的算法时间复杂度低
时间复杂度的计算规则
1,用常数1 取代运行时间中的所有加法常数
2,在修改后的运行函数中,只保留最高阶项。
3,如果最高阶存在且系数不是1,则去除这个项相乘的常数。
Fun(int a,int b) O(1)
{
3 Int tmp = a; O(1) n O(1)
A = b;
B = tmp;
}
for(i=0;i<n;i++) O(n) n O(n)
{
3n Int tmp = a;
A = b;
B = tmp; O(n)
}
for (i = 1; i < n; i *= 2) O(logn) 1*2*2*2*2*2... < n
x {
2 ^x = n
o(logn)
}
for(i=0;i<n;i++) O(nlogn)
{
for (i = 0; i < n; i *= 2) o(logn)
{
}
}
for(i=0;i<n;i++) o(n^2)
{
for(j=i;j<n;j++) 0 1 2 ...n-1
{
Int tmp = a; 3n 3(n-1) 3(n-2) 3
n^2 A = b;
B = tmp; 3 (n + 1)n/2 ====>n^2
}
}
O(1)<O(logn)<O(n)<O(nlogn)<O(n^2)<O(n^3)<O(2^n)<O(n!)<O(n^n)
排序算法:
冒泡
选择
插入
链表存储的数据类型
链表的结点类型
数据域
指针域:指向下一个结点的指针
描述链表的标签类型
链表头结点地址
链表中当前结点数据的个数
函数
功能 : 向链表头部插入一个结点
参数 :
返回值 :
成功:返回链表标签指针
失败:NULL
向链表中插入的数据
链表遍历