- 日期:20160626
- 作者:i.sshe
- https://github.com/isshe
【初探】排序算法
1. 基础问题
- 1.1 各个常见排序算法的思想及关键代码?
2. 基础问题解答
2.1 各个排序算法的思想及关键代码?
代码链接:https://github.com/isshe/Blog/tree/master/7_sort20160624
选择排序的思想:
- A. 从数据中选择一个最小/最大数据, 和第i个位置数据交换位置.
- B. 重复A操作,直到所有所有数据都被选择了一次.
- 关键代码:
for (i = 0; i < num; i++)
{
smallest = i;
for (j = i; j < num; j++)
{
if (temp_array[j] < temp_array[smallest])
{
//找最小 or 最大
smallest = j;
}
}
//交换
tempvalue = temp_array[smallest];
temp_array[smallest] = temp_array[i];
temp_array[i] = tempvalue;
}
插入排序的思想:
- A. 比较要插入数据value和目标数组array(已经排好序)的元素,从后往前比较,如果比value小/大(看升序降序), 把数组的数据往后移动一格.一直比较直到找到value的合适位置.
- B.把value插入到数组array中.
- C.重复AB即可插入多个数据.
- 关键代码:
for (i = 0; i < num; i++)
{
position = i;
for(j = i-1; j >= 0; j--)
{
if (data->array[i] < array[j])
{
position = j;
array[j+1] = array[j];
}
}
array[position] = data->array[i];
}
归并排序的思想: 分治思想
相关博文:归并排序-自顶向下/自底向上
- A.分解:把一份数据分为两份。像二分查找那样,mid=(front+rear)/2, 向下取整.(此时分为了[front, mid]和[mid+1, rear]两部分)
- B.解决:对两部分分别进行递归排序.
- C.合并:这里是递归合并,从最小的两部分开始一个一个取小的/大的(升序降序),放到目标数组中.
- 缺点:归并排序不是原地的, 需要拷贝整个数组.
- 模式:分治法.(将原问题分解为类似的子问题, 递归求解后再合并得到原问题的解)
代码:(归并排序个人个人觉得最精华的地方在于合并)
void merge(int *array, int front, int rear, int *dst_array) { int a = front; //第一个部分的头 int b = (front + rear) / 2; //第一部分的尾 int x = b + 1; //第二部分的头 int y = rear; //第二部分的尾 int i = front; while(a <= b || x <= y) { //这一句是最关键的!是精华! //合并是:a指向第一部分最小的数据,x指向第二部分最小的; //比较两个最小,看哪个更小,更小的放到目标数组。 //x>y是为了应付第二部分已经空的情况。(空了就不用比较了,直接把第一部分放目标数组) if (x > y || (a <= b && array[a] < array[x])) { dst_array[i++] = array[a++]; } else { dst_array[i++] = array[x++]; } } //把排序好的放回到原数组 for (i = front; i <= rear; i++) { array[i] = dst_array[i]; } }
快速排序:分治思想。
- 相关博文: 【初探】快速排序学习总结
- 相关博文: 快速排序及三向切分快速排序
- A. 在数据区域中选择一个基准点k;
- B. 大于k的放一边A,小于k的放另一边B.
- C. 再分别在A,B中以相同的策略划分。
(注:每一次都能排序好一个数据,就是基准点那个) 关键代码:
while(1) { while(array[j] >= key && i < j) //从后往前找比基准小的 { j--; } while(array[i] <= key && i < j) //从前往后找比基准大的 { i++; } if (i < j) //交换 { temp = array[i]; array[i] = array[j]; array[j] = temp; } else { break; } } //这次的交换能排序好一个数据,即基准。 temp = array[j]; array[j] = array[begin]; array[begin] = temp; //分两部分,继续递归 quick_sort(array, begin, j-1); quick_sort(array, j+1, end);
冒泡排序:
- A. 比较相邻数据;
- B. 交换数据;(上浮或下沉)
- C. 以此反复。每次都能排序好一个数据
代码:
void bubble_sort(int *array, int num) { int i = 0; int j = 0; int temp = 0; for(i = 0; i < num; i++) { for(j = num-1; j > i; j--) //这里是从下往上。 { if (array[j] < array[j-1]) { temp = array[j]; array[j] = array[j-1]; array[j-1] = temp; } } } }
堆排序:关键在于最大最小堆的调整,排序只是循环输出第一个数据。【和二叉树/优先队列相关一起写】
3. 参考资料
- 《算法基础-打开算法之门》
- 《啊哈!算法》
《算法(第四版)》
注:处于学习阶段,有理解错误的地方还望告知。感谢!