数据结构 算法解释,排序、查找
程序设计 = 数据结构 + 算法
算法:对数据操作的流程步骤
算法的设计
1. 正确性
语法正确
合法的输入能得到合理的结果
对非法的输入,给出满足要求的规格说明
对精心选择,甚至刁难的测试都能正常运行,结果正确
2. 可读性,便于交流,阅读,理解,高内聚 低耦合
3. 健壮性,输入非法数据,能进行相应的处理,而不是产生异常
4. 高效率 (时间复杂度)
5. 低存储(空间复杂度)
算法时间复杂度
执行这个算法所花时间的度量
将数据量增长和时间增长用函数表示出来,这个函数就叫做时间复杂度
一般用大O表示法:O(n) ------时间复杂度是关于数据n的一个函数
随着n的增肌,时间复杂度增长较慢的算法时间复杂度低
时间复杂度的计算规则
1. 用常数1取代运行时间中的所有加法常数
2. 在修改后的运行函数中,只保留最高阶项
3. 如果最高阶存在且系数不是1,则去除这个项相乘的常数
例:
命名 内核命名 get_max_num() 驼峰命名 getMaxNum() 均为动宾
排序和查找算法:
1. 冒泡排序 2.选择排序 3.插入排序 4. 快速排序 5. 二分查找
排序算法
1. 排序思想
2. 时间复杂度
3. 排序算法稳定性:在待排序列中,出现了两个相同数据,经过排序,
这两个相同数据的相对位置没有发送变化,该排序算法就是一个稳定的排序算法。
冒泡排序
相邻两两元素进行比较,将较大值向后移,一趟完成,将最大值存储在最后位置。
选择排序
将待排位置的数据和后面的数据依次进行比较,将较小的数据存入到待排位置;
经过一趟排序,待排位置存储最小值
插入排序
将待排的数据插入到一个已有序的序列中,确保每次插入后该序列任然有序。
希尔排序
将待排序列分成若干个子序列,分别对这若干个子序列进行插入排序。
int bin_find(int *a, int len, int data) { int begin = 0; int end = len-1; int cnt = 0; while (begin <= end) { cnt++; int mid = (begin + end) / 2; if (data == a[mid]) { printf("find %d\n", a[mid]); return 0; } else if (data > a[mid]) { begin = mid + 1; } else if (data < a[mid]) { end = mid - 1; } } printf("cnt = %d\n", cnt); printf("Not find\n"); return -1; } return 0; }快速排序
选取一个基准值,从两头向中间依次和基准值比较,将比基准值大的存在后面的序列,比基准值小的存在前面的序列;
经过一趟排序,将基准值存入合适的位置。并且以基准值为界,划分左右序列继续按照以上方式排序。
void quick_sort(int *a, int begin, int end) { if (begin >= end) { return ; } int i = begin; int j = end; int key = a[i]; while (i < j) { while (i < j && a[j] >= key) { j--; } a[i] = a[j]; while (i < j && a[i] <= key) { i++; } a[j] = a[i]; } a[i] = key; quick_sort(a, begin, i-1); quick_sort(a, i+1, end); }二分查找/折半查找
前提条件:必须是一个有序的序列
时间复杂度:O(logn)
int bin_find(int *a, int len, int data) { int begin = 0; int end = len-1; int cnt = 0; while (begin <= end) { cnt++; int mid = (begin + end) / 2; if (data == a[mid]) { printf("find %d\n", a[mid]); return 0; } else if (data > a[mid]) { begin = mid + 1; } else if (data < a[mid]) { end = mid - 1; } } printf("cnt = %d\n", cnt); printf("Not find\n"); return -1; } return 0; }