/**
* 实现最基本的排序算法
*/
import java.util.*;
public class Solution {
public static void main(String args[]) {
int a[] = new int[]{8, 9, 2, 3, 1, 4, 6, 7, 5, 0};
Solution s = new Solution();
System.out.print("排序之前:");
s.show(a);
s.stackSort(a);
// s.shellSort(a);
/**s.bubbleSort(a);
s.insertSort(a);
s.shellSort(a);
s.simpleSelectSort(a);
s.quickSort(a);
s.mergeSort(a);
s.stackSort(a);
*/
}
//打印数组
public void show(int a[]) {
for (Integer i : a)
System.out.print(i + " ");
System.out.println();
}
//交换数值的函数
public void swap(int a[], int i, int j) {
int t = a[i];
a[i] = a[j];
a[j] = t;
}
//冒泡排序:从后往前,每次获得一个最小值
public void bubbleSort(int a[]) {
int n = a.length;
boolean flag = false;
for (int i = 0; i < n; i++)
for (int j = n - 1; j > i; j--) {
if (a[j] < a[j - 1]) {
swap(a, j - 1, j);
flag = true;
}
if (flag == false)
break;
}
System.out.print("冒泡法结果:");
show(a);
}
//简单选择排序:每次选择一个最小值,和当前第i的位置交换
public void simpleSelectSort(int a[]) {
int n = a.length;
for (int i = 0; i < n; i++) {
int min = i;
for (int j = i + 1; j < n; j++) {
if (a[j] < a[min])
min = j;
}
swap(a, i, min);
}
System.out.print("\n简单选择排序结果为: ");
show(a);
}
//快速排序
public void quickSort(int a[]) {
quickSort(a, 0, a.length - 1);
System.out.print("快速排序:");
show(a);
}
public void quickSort(int a[], int low, int high) {
if (low >= high)
return;
int pos = partition(a, low, high);
quickSort(a, low, pos - 1);
quickSort(a, pos + 1, high);
}
public int partition(int a[], int low, int high) {
if (low >= high)
return high;
int pivot = a[low];
while (low < high) {
while (low < high && a[high] >= pivot) high--;
a[low] = a[high];
while (low < high && a[low] <= pivot) low++;
a[high] = a[low];
}
a[high] = pivot;
return high;
}
//直接插入排序.
public void insertSort(int a[]) {
int n = a.length;
//将0...i-1当做有序的,把i..n-1插入到前面有序的序列中
int j = 0;
for (int i = 1; i < n; i++) {
int t = a[i];
for (j = i - 1; j >= 0 && a[j] > t; j--) {
a[j + 1] = a[j];
}
a[j + 1] = t;
}
System.out.print("\n插入排序: ");
show(a);
}
//希尔排序,和直接插入排序类似,只是步长改变
public void shellSort(int a[]) {
int n = a.length;
int h = n / 3 + 1;
//把a[i]插入到a[i-h],a[i-2*h]....中,结合直接插入排序看就是了
int j = 0;
while (h >= 1) {
for (int i = h; i < n; i++) {
int t = a[i];
for (j = i - h; j >= 0 && a[j] > t; j -= h) {
a[j + h] = a[j];
}
a[j + h] = t;
}
h = h / 3;
}
System.out.print("\n希尔排序: ");
show(a);
}
// 归并排序,O(n)空间复杂度,这里把结果保存到原数组,原地归并
int aux[];
public void mergeSort(int a[]) {
aux = new int[a.length];
mergeSort(a, 0, a.length - 1);
System.out.print("\n归并排序: ");
show(a);
}
public void mergeSort(int a[], int low, int high) {
if (low >= high)
return;
int mid = low + (high - low) / 2;
mergeSort(a, low, mid);
mergeSort(a, mid + 1, high);
merge(a, low, mid, high);
}
public void merge(int a[], int low, int mid, int high) {
int i = low, k = low, j = mid + 1;
for(k=low;k<=high;k++) aux[k]=a[k]; //复制到辅助数组
k=low;
for(k=low;k<=high;k++)
if(i>mid) a[k]=aux[j++];
else if(j>high) a[k]=aux[i++];
else if(aux[i]>=a[j]) a[k]=aux[j++];
else
a[k]=aux[i++];
}
//堆排序,O(n),要建造一个堆,这里a[0] 不保存数字好了,所以建造了一个新数组
public void stackSort(int a[]){
int n=a.length;
int b[]=new int[n+1];
for(int i=1;i<=n;i++)
b[i]=a[i];
//先建堆,使用下沉函数,小根堆
for(int i=n/2;i>0;i--){
sink(b,n,i);
}
//堆排序
int len=n;
int index=0;
while(len>1){
a[index++]=b[1]; //结果保存到数组中
swap(b,len--,1);
sink(a,len,1);
}
System.out.print("\n堆排序: ");
show(a);
}
//下沉和上浮,方便建堆
public void swim(int b[],int n,int k){
while(k>1&&a[k/2]<a[k])
swap(b,k,k/2);
k=k/2;
}
public void sink(int b[],int n,int k){
while(2*k<=n){ //只要有孩子存在
int j=2*k;
if(j<n&&b[j]<b[j+1])
j++;
if(b[k]>b[j]) break;
swap(b,j,k);
k=j;
}
}
}