主程序
public class Test {
public static void main(String[] args) {
int[] arrs = {1, 9, 4, 50, 63, 82, 37} ;
System.out.println(Arrays.toString(arrs)) ;
//mergeSort(arrs, 0, arrs.length-1) ;
//quickSort(arrs, 0, arrs.length - 1) ;
heapSort(arrs) ;
System.out.println(Arrays.toString(arrs)) ;
}
}
交换数组中的两个元素
private static void swap(int[] array, int low, int high) {
int temp = array[low] ;
array[low] = array[high] ;
array[high] = temp ;
}
插入排序
public static void insertSort(int[] arr) {
int key ; //用于保存要插入的值
for(int i=1 ; i<=arr.length-1 ; i++) {
key = arr[i] ;
for(int j=i-1 ; j>=0 ; j--) {
if(key < arr[j]) {
arr[j+1]=arr[j] ; //记录后移
}
else {
arr[j+1] = key ; //找到插入的位置
break ;
}
}
}
}
选择排序(当前元素 VS 余下元素)
public static void selectSort(int[] arr) {
for(int i=0; i<=arr.length-2; i++) {
for(int j=i+1; j<=arr.length-1; j++) {
if(arr[i] > arr[j]) {
swap(arr, i, j) ;
}
}
}
}
冒泡排序(两两比较)
public static void bubbleSort(int[] arr) {
for(int i=arr.length-1; i>=1; i--) {
for(int j=0; j<=i-1; j++) {
if(arr[j] > arr[j+1]) {
swap(arr, j, j+1) ;
}
}
}
}
二路归并排序(递归版本)
public static void mergeSort(int[] arr, int low, int high) {
if(low < high) {
int mid = (low+high) / 2 ;
mergeSort(arr, low, mid) ;
mergeSort(arr, mid+1, high) ;
merge(arr, low, mid, high) ;
}
}
public static void merge(int[] arr, int left, int center, int right) {
int[] temp = new int[right-left+1] ; //归并排序的空间复杂度为O(n)
int k = 0 ;
int r1 = center+1 ; //右边起始下标
int start = left ; //保存拷贝的起始位置
while(left<=center && r1<=right) {
if(arr[left] < arr[r1]) { temp[k++] = arr[left++] ; }
else { temp[k++] = arr[r1++] ; }
}
//拷贝剩余元素
while(left <= center) { temp[k++] = arr[left++] ; }
while(r1 <= right) { temp[k++] = arr[r1++] ; }
//将临时数组中的元素拷贝至原数组
k = 0 ;
for(int i=start; i<=right ; i++) { arr[i] = temp[k++] ; }
}
二路归并排序(非递归版本)
public static void mergeSort(int[] arr) {
int length = arr.length ;
int low, mid, high ;
for(int step = 1 ; step <= length; step*=2) { //step为步长
low = 0 ;
while(low+step <= length) {
mid = low + step - 1 ;
high = mid + step ;
if(high >= length) { high = length - 1 ; } //元素个数小于step
merge(arr, low, mid, high);
low = high + 1 ; //下次归并的下界
}
}
}
public static void merge(int[] arr, int left, int center, int right) {
int[] temp = new int[right-left+1] ; //归并排序的空间复杂度为O(n)
int k = 0 ;
int r1 = center+1 ; //右边起始下标
int start = left ; //保存拷贝的起始位置
while(left<=center && r1<=right) {
if(arr[left] < arr[r1]) { temp[k++] = arr[left++] ; }
else { temp[k++] = arr[r1++] ; }
}
//拷贝剩余元素
while(left <= center) { temp[k++] = arr[left++] ; }
while(r1 <= right) { temp[k++] = arr[r1++] ; }
//将临时数组中的元素拷贝至原数组
k = 0 ;
for(int i=start; i<=right ; i++) { arr[i] = temp[k++] ; }
}
快速排序(递归版本)
public static void quickSort(int[] array, int low, int high) {
if(low < high) {
int i = partition(array, low, high) ;
quickSort(array, low, i-1);
quickSort(array, i+1, high);
}
}
private static int partition(int[] array, int low, int high) {
int pivot = array[low] ;
while(low < high) {
while(low < high && pivot <= array[high]) { high-- ; }
swap(array, low, high) ;
while(low < high && pivot >= array[low]) { low++ ; }
swap(array, low, high) ;
}
return low ;
}
快速排序(非递归版本)
public static void quickSort(int[] array) {
if(array==null || array.length==1) { return ; }
//保存划分后所形成空间的左右端点
Stack<Integer> stack = new Stack<Integer>() ;
stack.push(0) ;
stack.push(array.length - 1) ;
int low, high ;
while(! stack.isEmpty()) {
high = stack.pop() ;
low = stack.pop() ;
if(low >= high) { continue ; }
int i = partition(array, low, high) ;
stack.push(low) ; //保存左边的区间
stack.push(i-1) ;
stack.push(i+1) ; //保存右边的区间
stack.push(high) ;
}
}
private static int partition(int[] array, int low, int high) {
int pivot = array[low] ;
while(low < high) {
while(low < high && pivot <= array[high]) { high-- ; }
swap(array, low, high) ;
while(low < high && pivot >= array[low]) { low++ ; }
swap(array, low, high) ;
}
return low ;
}
堆排序
public static void heapSort(int[] heap) {
buildHeap(heap) ; //构建堆
for(int size=heap.length-1 ; size >= 1 ; ) {
swap(heap, 0, size); //交换首末元素
adjustHeap(heap, --size, 0); //对剩余元素进行调整
}
}
public static void buildHeap(int[] heap) {
int size = heap.length-1 ;
//自底向上调整堆
for(int begin = size/2 ; begin>=0 ; begin--){
adjustHeap(heap, size, begin) ;
}
}
public static void adjustHeap(int[] heap, int size, int start) {
int big = start ; //保存较大元素下标
int left = 2*start + 1 ; //左叶子节点
int right = 2*start + 2 ; //右叶子节点
while(left<=size || right<=size) {
if(left<=size && heap[left]>heap[big]) { big=left ; }
if(right<=size && heap[right]>heap[big]) { big=right ; }
if(start == big) { break ; } //调整完毕
else {
swap(heap, start, big) ; //较大元素上浮
start = big ;
left = 2*start + 1 ;
right = 2*start + 2 ;
}
}
}