归并排序
void mergeSort(int a[],int start,int end) { int mid; if(start == end) return; else { mid = (end + start)/2; mergeSort(a,start,mid); mergeSort(a,mid+1,end); merge(a,start,mid,end); //make 2 ordered sequence in the same arrays order in general } }
微积分的思想
微分
-
先将一个长的无序的序列分成两个较短的无序的序列(再对这两个较短的序列排序)。
-
当上述分到极致时,两个较短的序列就是一个数字,那么开始了积分。
积分
-
将两个数字排序成为一个倒数第二短的有序序列。
-
两个倒数第二短的有序序列merge成一个倒数第三短的有序序列·······
积分完毕以后便是一个有序的序列。
如何将长的无序序列分成两个较短的无序序列?
取中间值mid,start到mid一组;mid+1到end一组。
如何将两个较短的有序序列merge成一个较长的有序序列?
设置第二个数组在两个较短的有序序列中逐序取值。
ps:感觉递归都有点微积分的味道
快速排序
步骤
-
直接选取第一个元素,通过将比它小的元素放置在它的左边,比它大的元素放在它的右边,这个元素最终会直接落在它应该在的位置
-
以上述元素为分界线,形成两个序列后,分别对两个重复操作
如何实现步骤1(理念)
-
从右边最后一个元素开始找到第一个比待排元素小的元素
-
将其与待排元素交换位置
-
从左边第二个(实际上可能也从第一个)开始找到第一个比待排元素大的元素
-
将其与待排元素交换位置
如何实现步骤1(物理)
数组a[ ]:可以用start & end 来解决,当两者相等时,待排元素已经找到了它的位置
hole = start;//wait to be ordered temp = a[hole]; i = start; j = end; while(i<j) { //find small in the right while( (j>i)&&(a[j]>=temp) ) j--; if(j==i) break; a[hole] = a[j]; hole = j; //find big in the left //...... }
选择排序
将一个序列中的数字由小到大排列好,这个序列便变成了一个有序(小->大)序列;
反而言之,将一个序列变成一个有序(小->大)序列,那么数字便是由小到大的。
选择排序就是将序列中的每个元素都放在它最终应该在的位置,即为有序序列的每个位置寻找合适的元素。
堆排序
什么是堆?
一种特殊的二叉树,大根堆是根节点比其左右子树上的结点都大的二叉树,反之反。
将无序序列变成有序序列的过程就是将一个顺序存储的完全二叉树变成一个堆的过程
如何使这个顺序存储的完全二叉树符合堆的定义
-
从后往前看,叶子结点都符合定义
-
故从第一个非叶子结点开始调整
拓展
优先队列
内排序总结
算法 | 解释 | 稳定性 | 时间复杂度 |
---|---|---|---|
冒泡排序 | |||
简单插入排序 | |||
折半插入排序 | |||
希尔排序 | |||
归并排序 | |||
快速排序 | |||
选择排序 | |||
堆排序 | |||
基数排序 |