您的位置:首页 > 编程语言 > Java开发

常见排序之Java实现

2016-07-09 00:00 323 查看
摘要: 内部排序:插入、选择、冒泡、归并、快速、堆

主程序

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 ;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  排序 java