昨天重温了一下插入排序与快速排序。
1,插入排序:将一个序列分为有序部分和无序部分,进行N-1次循环,每次将无序部分中的一个数插入到有序部分的相应位置。之后整个序列就是有序的。
算法复杂度O(N^2), 稳定排序。由于比较简单,不做具体分析,代码如下:
package sort;
public class InsertSort {
public static void insertSort(int []a) {
int j;
int n = a.length;
for(int i=1;i<n;i++)
{
int t = a[i];
for(j = i; j>0 && a[j-1]>a[j]; j--)
a[j] = a[j-1];
a[j] = t;
}
}
public static void main(String[] args) {
int []a = {2, 1, 3, 5, 8, 7};
insertSort(a);
for(int i=0;i<a.length;i++){
System.out.print(a[i] + " ");
if(i==a.length-1) System.out.println();
}
}
}
2,快速排序:选择一个基准数,经过一趟排序,使得基准数左边的数都比它小,右边的都比它大(针对升序排列)。然后再对左右两边的区间递归调用快排。基准数的选取,一般会选择区间的第一个元素,为了更加平均的效率,随机数是一个比较好的选择。
直接贴代码
public class QuickSort{
public static int partition(int []a, int l, int u){
int k = a[l];
while(l<u){
while( l<u && a[u]>=k) -- u;
a[l] = a[u];
while( l<u && a[l]<=k) ++ l;
a[u] = a[l];
}
a[l] = k;
return l;
}
public static void quickSort(int []a, int l, int u){
if(l>=u) return;
int p = partition(a, l, u);
quickSort(a, l, p-1);
quickSort(a, p+1, u);
}
public static void main(String []args){
int []a = {2, 3, 4, 6, 9, 2, 8};
quickSort(a, 0, a.length-1);
for(int i=0;i<a.length;i++){
System.out.print(a[i] + " ");
if(i==a.length-1) System.out.println();
}
}
}
3,堆排序:堆分为大根堆(a[i]>=a[2*i] && a[i]>=a[2*i+1] ) 和小根堆(a[i]<=a[2*i] && a[i]<=a[2*i+1] )。由此,堆的根节点即为最大值或者最小值,当不断拿走根节点并且使得剩下的部分重新调整为堆,即可实现排序。堆排序分为两个过程:1,建堆,即将一个乱序队列构建为堆;2,调整,即去掉根节点(最大值或者最小值)后调整剩下的部分使其继续为堆。 对于一个节点的树,已经是堆。对于二层树,如果最大值不是根,则最大值与根交换,这样就调整为堆。对于多层树,我们只需要从最后一个非叶节点调整就可以建堆。
排序过程,建堆,交换第一个节点与最后一个节点,这样最后一个数就已经在正确位置上,去掉已经在正确位置上的节点,调整。 依次下去就可排序。
注意, 如果需要升序排列,需要建立大根堆, 降序需要小根堆。
下面给出了递归和非递归的实现
public class HeapSort {
public static void makeHeap(int []a, int len) {
for(int i=len/2;i>=1;i--)
// ajustHeap(a, i, len);
ajustHeapNoRecursive(a, i, len);
}
public static void ajustHeap(int []a, int i, int len) {
if( i > len/2 ) return; // 叶节点,不做处理
int max = i;
int lChild = i * 2;
int rChild = i * 2 + 1;
if(lChild<=len && a[lChild]>a[max]) max = lChild;
if(rChild<=len && a[rChild]>a[max]) max = rChild;
if(max != i) { // 需要调整顺序
int tem = a[max];
a[max] = a[i];
a[i] = tem;
ajustHeap(a, max, len);
}
}
public static void ajustHeapNoRecursive(int []a, int i, int len) {
while(i<=len/2) {
int lChild = i * 2;
int rChild = i * 2 + 1;
int max = i;
if(lChild<=len && a[lChild]>a[max]) max = lChild;
if(rChild<=len && a[rChild]>a[max]) max = rChild;
if(max != i) { // 需要调整顺序
int tem = a[max];
a[max] = a[i];
a[i] = tem;
i = max;
}
else return;
}
}
public static void heapSort(int []a) {
int len = a.length - 1;
makeHeap(a, len);
for(int i=len;i>1;i--){
int tem = a[i];
a[i] = a[1];
a[1] = tem;
// ajustHeap(a, 1, i-1);
ajustHeapNoRecursive(a, 1, i-1);
}
}
public static void main(String[] args) {
int []a = {0, 4, 3, 5, 2, 6, 1, 9, 1};//第一个数字为无效数字,数组从1开始
heapSort(a);
for(int i=1;i<a.length;i++) System.out.print(a[i] + " ");
System.out.println();
}
}