《数据结构》课程绪论
来源:互联网 发布:linux count 命令 编辑:程序博客网 时间:2024/05/20 01:46
《数据结构》课程绪论
使用教材:
《数据结构教程》第5版 李春葆 清华大学出版社
参考书:
《数据结构与算法分析 C语言描述》(第2版) Mark Allen Weiss 机械工业出版社
《算法导论》(第3版) Charles E. Leiserson 等 机械工业出版社
《算法》(第4版) Robert Sedgewick Kevin Wayne 人民邮电出版社
《STL源码剖析》 侯捷 华中科技大学出版社
使用语言:C/C++
1.数据结构基本概念
数据与数据结构
- 数据(data):描述客观事物的数和字符的集合。
- 数据元素(data element):数据的基本单位
- 数据项(data item):具有独立含义的数据最小单位,又叫字段或域。
- 数据结构(data structure):所有数据元素及其构成的关系
数据结构包括的三个方面
- 逻辑结构(logical structure)(数据的逻辑关系)
- 存储结构(storage structure)(物理结构,如何在存储器上表示)
- 运算(operation)(对数据实施的操作,增删改查排序等)
逻辑结构的表示方法
- 图表
- 二元组
B=(D,R) ,其中D 为数据集合,R 为数据的所有关系的集合。 - 每一个关系是序偶的集合,对于序偶
<x,y> (x,y∈D ),x 是y 的前驱(predecessor),y 是x 的后继(successor)。使用尖括号表示x 与y 是一个偏序关系,圆括号表示为等价关系。
逻辑结构的类型
- 集合
- 线性结构
- 树形结构
- 图型结构
存储结构
处理存储结构,既要保证存储所有的元素
1. 顺序存储结构:所有元素在存储器中都是连续存放的,逻辑相邻的元素也必然物理相邻。支持快速的查找,插入和删除较慢;
2. 链式存储结构:每个逻辑元素使用内存中的结点存储。所有结点的地址不一定是连续的。C/C++使用指针来链接每一个结点。Java等语言使用引用。支持快速的插入和删除,但是不能随机存取,需要额外浪费指针空间。
3. 索引存储结构:利用关键字,地址
的方式建立索引,可以利用关键字的有序性快速查找到关键字地址。查找效率高,但是索引表需要额外空间开销。
4. 哈希(散列)存储结构:直接建立值->存储地址
的映射,支持快速查找和插入,不存储数据之间的逻辑关系。
2.算法及其分析
算法的特点
- 有穷性
- 确定性
- 可行性
- 有输入输出
算法设计的目标
- 正确性
- 可使用性
- 可读性
- 健壮性
- 高效率、低存储
算法的时间分析
通常用“大O记号”表示其渐进复杂度。渐进复杂度取其最高阶,忽略系数和低阶项。
最好、最坏、平均时间复杂度
设输入规模
平均时间复杂度的定义
最好时间复杂度:
最坏时间复杂度:
递归算法分析
先求出递归式,然后对其化简,或使用递归树、主定理等方法。
算法复杂度分析举例
二分查找最坏情况
/*** 二分查找(升序数组中查找)* @param int[] A 待查找的数组* @param int length 数组的长度* @param int value 待查找的元素* @return int 该元素在数组中的下标(0开始,未找到则返回-1)*/int binary_search(int A[], int length, int value) { int begin = 0, end = length - 1, mid; while (begin <= end) { mid = (begin + end) / 2; if (A[mid] == value) return mid; else if (A[mid] > value) end = mid - 1; else begin = mid + 1; } return -1;}
二分查找的核心语句是while
循环。
最坏情况下,数组A
中没有值为value
的元素,不妨设
第二次比较后剩余
最后一次(第
因此最坏情况下的时间复杂度为
选择排序
/*** 选择排序(升序)* @param int[] A 待排序数组* @param int length 数组长度* @return int 函数返回值,0表示成功*/int selection_sort(int A[], int length){ int i, j; int min, tmp; for (i = 0; i < length - 1; i++) { min = i; for (j = i + 1; j < length; j++) if (A[min] > A[j]) min = j; tmp = A[i]; A[i] = A[min]; A[min] = tmp; } return 0;}
核心语句是一条if
判断语句,
对于外层for
循环,执行
内层for
循环,执行
因此其时间复杂度是
二路归并排序
/*** 二路归并排序* @param int[] A 待排序数组* @param int length 数组长度* @return int 函数返回值,0成功*/int merge_sort(int A[], int length) { int * aux = (int *)malloc(sizeof(int) * length); merge_sort_sub(A, 0, length - 1, aux); return 0;}/*** 二路归并排序子函数* @param int[] A 源数组* @param int begin 当前排序的子数组的起始下标* @param int end 当前排序的子数组的结束下标* @param int[] aux 临时数组*/int merge_sort_sub(int A[], int begin, int end, int aux[]) { int midpoint; int i, j, k; if (end <= begin) return; midpoint = (end + begin) / 2; merge_sort_sub(A, begin, midpoint, aux); merge_sort_sub(A, midpoint + 1, end, aux); for (k = begin; k <= end; k++) aux[k] = A[k]; i = begin; j = midpoint + 1; for (k = begin; k <= end; k++) { if (i <= midpoint && j <= end) { if (aux[i] > aux[j]) A[k] = aux[j++]; else A[k] = aux[i++]; } else if (i > midpoint) { A[k] = aux[j++]; } else if (j > end) { A[k] = aux[i++]; } } return 0;}
在递归过程中,设merge_sort_sub
一个长度为merge_sort_sub(A, begin, midpoint, aux)
贡献为merge_sort_sub(A, midpoint + 1, end, aux)
的贡献为
最后需要对
因此有递归式
假设
所以
…
容易知道起始条件
所以
所以
当为一般情况时,可根据主定理的情况2(
- 《数据结构》课程绪论
- 课程笔记 01:数据结构(清华) 绪论
- 数据结构绪论
- [数据结构]绪论
- 数据结构 绪论
- 数据结构绪论
- 数据结构---->绪论
- 数据结构 绪论
- 数据结构绪论
- 数据结构绪论
- 数据结构 绪论
- 《数据结构》 绪论
- 数据结构------绪论
- 数据结构 绪论
- 数据结构绪论
- 数据结构绪论
- 数据结构 绪论
- 数据结构绪论
- 1154:逆反的01串
- Github写公式
- Oracle----函数
- Set里元素怎么区分,==和equals的区别
- OJ 2706: 编写一个函数求最大的n 值。
- 《数据结构》课程绪论
- Asp.net+Vue2构建简单记账WebApp之五(vue.js构建记账页面)
- 加密解密算法java实现(5)—RSA 加解密的例子
- c++面向对象编程
- SetBkMode函数理解
- .List,Set,Map是否继承自Collection接口?
- 高仿微信主界面
- 算法笔记:动态规划背包问题(未完待续)
- 移动平台 Unity3D 应用性能优化