import java.util.Arrays;
/**
*
* 1. 冒泡排序
* 2. 选择排序
* 3. 直接插入排序
* 4. 希尔排序
* 5. 快速排序
* 6. 归并排序
* 7. 堆排序
* 8. 基数排序
*
* @author CN
*
*/
public class SortUtils {
public static void main(String[] args) {
int[] arr= {49,38,65,97,76,13,27};
// bubleSort(arr);
// selectSort(arr);
// insertSort(arr);
// shellSort(arr);
// quickSort(arr, 0, arr.length-1);
// RadixSort(arr, 2);
// heapSort(arr);
// mergeSort(arr);
System.out.println(Arrays.toString(arr));
}
/**
* 1. 冒泡排序
* @param arr
*/
public static void bubleSort(int[] arr) {
for(int i=0; i<arr.length; i++)
for(int j=0; j<arr.length-i-1; j++)
if(arr[j] > arr[j+1])
swap(arr, j, j+1);
}
/**
* 2. 选择排序
* @param arr
*/
public static void selectSort(int[] arr) {
int pos = 0;
for(int i=0; i<arr.length; i++) {
pos = i;
for(int j=i+1; j<arr.length; j++)
if(arr[j] < arr[pos])
pos = j;
swap(arr, i, pos);
}
}
/**
* 3. 直接插入排序
* @param arr
*/
public static void insertSort(int[] arr) {
for(int i=1; i<arr.length; i++)
for(int j=i; j>0 && arr[j]<arr[j-1]; j--)
swap(arr, j, j-1);
}
/**
* 4. 希尔排序
* @param arr 原数组
*/
public static void shellSort(int[] arr) {
for(int dk=arr.length/2; dk>0; dk/=2) {
// 从第dk个元素,逐个对其所在组进行直接插入排序操作
for(int i=dk; i<arr.length; i++) {
for(int j=i; j-dk>=0 && arr[j]<arr[j-dk]; j -= dk)
swap(arr, j, j-dk);
}
}
}
/**
* 5. 快速排序
* @param arr 原数组
* @param low 开始位置
* @param high 结束位置
*/
public static void quickSort(int[] arr, int low, int high) {
int key = arr[low]; // 选择枢轴
int i = low;
int j = high;
while(i < j) {
while(i < j && key <= arr[j]) j--; // 从后往前
if(i < j) arr[i++] = arr[j]; // 小值前放
while(i < j && key >= arr[i]) i++; // 从前往后
if(i < j) arr[j--] = arr[i]; // 大值后放
}
arr[i] = key;
// 左侧排序
if(i-1 > low) quickSort(arr, low, i-1);
// 右侧排序
if(i+1 < high) quickSort(arr, i+1, arr.length-1);
}
/**
* 6. 归并排序
* @param arr 原数组
*/
public static void mergeSort(int[] arr) {
divide(arr, 0, arr.length-1);
}
/** 分 */
public static void divide(int[] arr, int left, int right) {
if(left < right) {
// 对半拆分
int mid = (left + right)/2;
divide(arr, left, mid);
divide(arr, mid+1, right);
// 两个分组进行合并
merge(arr, left, mid+1, right);
}
}
/** 治 */
public static void merge(int[] arr, int left, int mid, int right) {
int len = right-left+1;
int[] tmp = new int[len];
int i = 0;
int j = left;
int k = mid;
while(i < len) {
if(k > right) { // 如果右分组已全部被使用,将左分组全部移至至临时数组中
System.arraycopy(arr, j, tmp, i, mid-j);
break;
}
while(j<mid && arr[j]<arr[k]) // 如果左分组的第一个小,则移至临时数组
tmp[i++] = arr[j++];
if(j >= mid) { // 如果左分组已全部被使用,将右分组全部移至临时数组中
System.arraycopy(arr, j, tmp, i, right-k+1);
break;
}
while(k<=right && arr[k]<arr[j]) // 如果右分组的第一个小,则移至临时数组
tmp[i++] = arr[k++];
}
// 将临时数组复制至原数组中
System.arraycopy(tmp, 0, arr, left, len);
}
/**
* 7. 堆排序(大顶堆-升序)
* @param arr 原数组
*/
public static void heapSort(int[] arr) {
// 构造大顶堆
for(int i=arr.length/2-1; i>=0; i--) {
adjustHeap(arr, i, arr.length);
}
// 选出最大值置于尾部,并调整堆
for(int i=arr.length-1; i>=0; i--) {
swap(arr, 0, i); // 交换至尾部
adjustHeap(arr, 0, i); // 重新调整
}
}
/**
* 调整为堆大顶堆(在大顶堆的基础上)
* @param arr 原数组
* @param i 开始调整的位置
* @param length 长度
*/
public static void adjustHeap(int[] arr, int i, int length) {
// 从左子节点开始
for(int k=2*i+1; k<length; k=2*i+1) {
// 判断右子节点是否比左节点大
if(k+1 < length && arr[k]<arr[k+1])
k = k+1;
// 判断最大的子节点与父节点的大小
if(arr[k] > arr[i]) {
swap(arr, k, i);
i = k;
}
else // 比子节点都大,退出循环
break;
}
}
/** 交换函数 */
public static void swap(int arr[], int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
/**
* 8. 基数排序
* @param arr 原数组
* @param maxLen 数字的最长位数
*/
public static void RadixSort(int[] arr, int maxLen) {
int[][] tmp = new int[10][arr.length];
int[] nums = new int[10];
int d = 1; // 第i位数
int n = 1;
while(d <= maxLen) {
for(int i=0; i<arr.length; i++) {
// 获取某一位数
int lsd = arr[i] / n % (10*d);
tmp[lsd][nums[lsd]++] = arr[i];
}
// 放回原数组
int k = 0;
for(int i=0; i<10; i++) {
for(int j=0; j<nums[i]; j++)
arr[k++] = tmp[i][j];
nums[i] = 0;
}
d++;
n *= 10;
System.out.println(Arrays.toString(arr));
}
}
}
【8种排序算法】Java实现
猜你喜欢
转载自blog.csdn.net/goldlone/article/details/81304734
今日推荐
周排行