原始链接:https://blog.csdn.net/yuan_qh/article/details/100139910
首先,这篇博客的来源是因为我在学习排序算法的时候,看到了一位大神写的十大经典排序算法,写的真的很不错,可是遗憾的是没有java版本实现,所以我按照每个排序来写了一个java版本实现,如有错误,欢迎指正。
所以说,学习这篇文章时,建议和十大经典排序算法一起看。
package cn.yqh.interview.sort;
/**
* @author 袁
* @create 2019/8/27-15:27
*/
public class BubbleSort {
public static int[] bubbleSort(int[] array) {
if (array == null || array.length == 0) {
return null;
}
for (int i = 0; i
for (int j = 0; j
if (array[j]
swap(array, j, j + 1);
}
}
}
return array;
}
private static void swap(int[] arr, int i, int i1) {
int tem = arr[i];
arr[i] = arr[i1];
arr[i1] = tem;
}
public static void main(String[] args) {
int[] arr = {5, 3, 7, 2, 9, 4, 1};
int[] sort = bubbleSort(arr);
for (int i : sort) {
System.out.print(i + " ");
}
}
}
package cn.yqh.interview.sort;
/**
* @author 袁
* @create 2019/8/27-15:27
*/
public class SelectionSort {
public static int[] selectionSort(int[] array) {
if (array == null || array.length == 0) {
return null;
}
for (int i = 0; i
//先假设每次循环时,最小(大)数的索引为i
int minIndex = i;
//每一个元素都和剩下的未排序的元素比较
for (int j = i + 1; j
if (array[minIndex] > array[j]) minIndex = j; //第一次写代码犯错:每比较一次,就交换一次,这样显然没有记录最小值的索引然后在最后交换一次的好
} //第二次写代码犯错:这里应该是array[minIndex] > array[j]比较,而不是array[i] > array[j]比较
//进过一轮循环,即可找出第一个最值的索引,然后把最值放到i的位置
swap(array, i, minIndex);
}
return array;
}
private static void swap(int[] arr, int i, int i1) {
int tem = arr[i];
arr[i] = arr[i1];
arr[i1] = tem;
}
public static void main(String[] args) {
int[] arr = {5, 3, 7, 2, 9, 4, 1};
int[] sort = selectionSort(arr);
for (int i : sort) {
System.out.print(i + " ");
}
}
}
package cn.yqh.interview.sort;
/**
* @author 袁
* @create 2019/8/27-15:27
*/
public class InsertionSort {
// 版本1,双for循环
public static int[] insertionSort(int[] array) {
int current, index;
if (array == null && array.length == 0) {
return null;
}
for (int i = 1; i
current = array[i]; //取出元素
index = i; //记下当前元素的索引位置
for (int j = i - 1; j >= 0; j--) {
if (current
array[j + 1] = array[j]; //将这个较大的结点后移
index = j; //通过index记下current将要放置的位置
}
}
if (index != i) array[index] = current; //如果array刚刚好是有顺序的,则到这里时,这个元素就不用移动了
}
return array;
}
// 版本2,for循环加while循环(大众版本)
public static int[] insertionSort2(int[] array) {
int current, index, j;
if (array == null || array.length == 0) {
return null;
}
for (int i = 1; i
current = array[i]; //取出元素,避免若前面的元素小于当前元素,前面元素后移导致当前元素被覆盖
index = i; //记下当前元素的索引位置
j = i-1; //记录当前元素的前一个元素的位置
while (j >= 0 && array[j] > current) {
array[j+1] = array[j]; //元素后移
index = j--; //先赋值再减减(j--就是继续往前寻找组中前面的元素)
}
if (index != i) array[index] = current; //如果array刚刚好是有顺序的,则到这里时,这个元素就不用移动了
//也可以不适用index,直接用最后的j+1,其实和index是一样的,这里加入index为了更好理解
}
return array;
}
public static void main(String[] args) {
int[] arr = {5, 3, 7, 2, 9, 4, 1};
int[] sort = insertionSort2(arr);
for (int i : sort) {
System.out.print(i + " ");
}
}
}
package cn.yqh.interview.sort;
/**
* @author 袁
* @create 2019/8/27-19:33
*/
public class ShellSort {
public static int[] shellSort(int[] array) {
int current, index, j;
if (array == null || array.length == 0) {
return null;
}
for (int gap = array.length / 2; gap > 0; gap = gap / 2) { //选取gap,采用推荐的默认/2取gap的方式
for (int i = gap; i
//接下来采用插入排序对每个组进行排序
current = array[i]; //取出当前元素,避免前组中前一个元素后移导致此元素被覆盖
j = i - gap; //取得这个组中的前一个元素的位置
while (j >= 0 && array[j] > current) {
array[j + gap] = array[j]; //元素后移,注意移动的个数为gap,第一次编程写错了array[j + 1] = array[j];
j -= gap; //j继续往前寻找组中前面的元素
}
array[j + gap] = current; //j+gpa即为array[i]该移动的位置
}
}
return array;
}
public static void main(String[] args) {
int[] arr = {5, 3, 7, 2, 9, 4, 1};
int[] sort = shellSort(arr);
for (int i : sort) {
System.out.print(i + " ");
}
}
}
package cn.yqh.interview.sort;
/**
* @author 袁
* @create 2019/8/27-19:33
*/
public class MergeSort {
public static int[] sort(int[] a, int low, int high) {
int mid = (low + high) / 2;
if (low
sort(a, low, mid);
sort(a, mid + 1, high);
merge(a, low, mid, high);
}
return a;
}
public static void merge(int[] a, int low, int mid, int high) {
if (a == null || a.length == 0) {
return;
}
int[] temp = new int[high - low + 1];
int k = 0; //记录temp数组的下标
int i = low, j = mid + 1; //定义两个指针,i指向前一半的第一个元素的位置,j指向mid+1的位置
while (i <= mid && j <= high) {
temp[k++] = a[i++];
} else {
temp[k++] = a[j++];
}
}
while (i <= mid) {
temp[k++] = a[i++];
}
while (j <= high) {
temp[k++] = a[j++];
}
for (int l = 0; l
a[low + l] = temp[l];
}
}
public static void main(String[] args) {
int[] arr = {5, 3, 7, 2, 9, 4, 1};
int[] sort = sort(arr, 0, 6);
for (int i : sort) {
System.out.print(i + " ");
}
}
}
package cn.yqh.interview.sort;
/**
* @author 袁
* @create 2019/8/28-15:47
* https://blog.csdn.net/Yexiaofen/article/details/78018204
*/
public class QuickSort {
public static void quickSort(int[] a, int low, int high) {
if (a == null || a.length == 0) {
return;
}
//1,找到递归算法的出口
if (low > high) {
return;
}
//2, 存
int i = low;
int j = high;
//3,key
int key = a[low];
//4,完成一趟排序
while (i
//4.1 ,从右往左找到第一个小于key的数
while (i
j--;
}
// 4.2 从左往右找到第一个大于key的数
while (i
i++;
}
//4.3 交换
if (i
int p = a[i];
a[i] = a[j];
a[j] = p;
}
}
// 4.4,调整key的位置
swap(a, i, low);
//5, 对key左边的数快排
quickSort(a, low, i - 1);
//6, 对key右边的数快排
quickSort(a, i + 1, high);
}
private static void swap(int[] arr, int i, int i1) {
int tem = arr[i];
arr[i] = arr[i1];
arr[i1] = tem;
}
public static void main(String[] args) {
int[] arr = {22, 3, 0, 85, 7, 6, 25, 24, 56, 22};
quickSort(arr, 0, arr.length - 1);
for (int i : arr) {
System.out.print(i + " ");
}
}
}
package cn.yqh.interview.sort;
/**
* @author 袁
* @create 2019/8/27-19:33
* https://www.jianshu.com/p/11655047ab58
*/
public class HeapSort {
/**
* 堆排序
*/
public static void heapSort(int[] arr) {
if (arr == null || arr.length == 0) {
return;
}
//对初始的数组构造大顶堆
//对最后一个非叶子结点开始到根节点为止进行排序,使数组构成大顶堆
for (int i = arr.length / 2 - 1; i >= 0; i--) {
//调用headADjust排序
headAdjust(arr, arr.length, i);
}
//排序完成,大顶堆已构成
//依次取出根元素与最后第一个元素,最后第二个元素,最后第三个元素...交换位置(根元素此时已经最大)
for (int i = arr.length - 1; i >= 1; i--) {
swap(arr, 0, i);
//交换之后,此时的根元素就一定是最大的元素了,所以进行堆调整,使根元素再次最大
headAdjust(arr, i, 0); //此时由于数组已经排出了一个最大元素放在最后,所以我们 只对剩下的length--进行排序,故长度为i
}
}
/**
* @param arr 需要排序的数组
* @param len 数组的长度
* @param i 需要排序的结点的索引
*
* 把要进行调整的结点i当做根节点,进行调整
*/
private static void headAdjust(int[] arr, int len, int i) {
if (arr == null || arr.length == 0) {
return;
}
//把要进行调整的结点i当做根节点,则children
int root = i, index = 2 * root + 1; //index指向root直接结点中的最大值
while (index
if (index + 1
if (arr[index]
}
//到这里就找到了root的孩子的最大值的索引
if (arr[index] > arr[root]) {
swap(arr, index, root);
}
//交换完之后继续把被交换的子节点变为父节点继续调整,因为交换操作可能会破坏堆
//这里应该注意到,当操作树的倒数第二层,也就是非叶子结点的倒数第一层时,运行到这里while就结束了
//但是如果是倒数第三次或者更高时,那么下面的倒数第二层已经是被排序过了的
root = index;
index = 2 * root + 1;
//这里可以改成这样,若交换了则继续更新下面的节点,没交换则不用更新
/*if (arr[index] > arr[root]) {
swap(arr, root, index);
root = index;
index = 2 * root + 1;
} else {
break;
}*/
}
}
private static void swap(int[] arr, int i, int i1) {
int tem = arr[i];
arr[i] = arr[i1];
arr[i1] = tem;
}
public static void main(String[] args) {
int[] arr = {5, 3, 7, 2, 9, 4, 1};
heapSort(arr);
for (int i : arr) {
System.out.print(i + " ");
}
}
}
package cn.yqh.interview.sort;
/**
* @author 袁
* @create 2019/8/27-19:33
* https://www.cnblogs.com/zer0Black/p/6169858.html
*/
public class CountingSort {
/**
* 堆排序
*/
public static void countingSort(int[] arr) {
if (arr == null || arr.length == 0) {
return;
}
int max = 0, min = 0;
//找出数组中最大最小值
for (int i = 0; i
max = Math.max(max, arr[i]);
min = Math.min(min, arr[i]);
}
int[] count = new int[max - min + 1];
//对数组中每个出现的元素计数
for (int i = 0; i
count[arr[i] - min]++;
}
//然后通过count数组得到数据的顺序
int index = 0;
for (int i = 0; i
while (count[i]-- > 0) { //这里count[i]先与0比较,后--
arr[index++] = i + min; //这里arr[index]=i+min之后,index再++
}
}
}
public static void main(String[] args) {
int[] arr = {5, 5, 3, 7, 2, 9, 4, 1};
countingSort(arr);
for (int i : arr) {
System.out.print(i + " ");
}
}
}
package cn.yqh.interview.sort;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* @author 袁
* @create 2019/8/27-19:33
* https://www.cnblogs.com/zer0Black/p/6169858.html
*/
public class BucketSort {
/**
* 桶排序
*/
public static List bucketSort(int[] arr) {
if (arr == null || arr.length == 0) {
return null;
}
int max = 0, min = 0;
//找出数组中最大最小值
for (int i = 0; i
max = Math.max(max, arr[i]);
min = Math.min(min, arr[i]);
}
// 先计算桶的数量
int bucketCount = (max - min) / arr.length + 1;
//创建桶数组
ArrayList
for (int i = 0; i
bucketArray.add(new ArrayList
}
//把数据放入桶中
for (int i = 0; i
bucketArray.get((arr[i] - min) / arr.length).add(arr[i]);
}
//对每个桶中的数据排序
for (int i = 0; i
Collections.sort(bucketArray.get(i));
}
return bucketArray;
}
public static void main(String[] args) {
int[] arr = {5, 5, 3, 7, 2, 9, 4, 1};
ArrayList list = (ArrayList) bucketSort(arr);
System.out.println(list.toString());
}
}
package cn.yqh.interview.sort;
/**
* @author 袁
* @create 2019/8/27-19:33
* https://www.cnblogs.com/developerY/p/3172379.html
*/
public class RadixSort {
/**
* 基数排序
*/
public static void RadixSort(int[] arr, int maxDigit) {
if (arr == null || arr.length == 0) {
return;
}
int mod = 1; //n取1,10,100...
int k = 0; //当把桶中的数据取出到arr时使用
int len = arr.length;
int[][] bucket = new int[10][len]; //桶,用来装每个数据
int[] count = new int[10]; //用来记每个桶中有几个数据
while (mod
//把当前的数据按照顺序存到桶中
for (int i : arr) {
int digit = (i / mod) % 10;
bucket[digit][count[digit]] = i;
count[digit]++;
}
//一次排序完,则把数据从桶中放回数组中,
for (int i = 0; i
if (count[i] != 0) { //如果这个桶有数据,则取出
for (int j = 0; j
arr[k++] = bucket[i][j];
}
}
//每遍历完一个桶,把计数器归零
count[i] = 0;
}
mod *= 10; //继续比较下一位
k = 0;
}
}
public static void main(String[] args) {
int[] arr = {5555, 5, 3, 7, 2, 999, 4, 1};
RadixSort(arr, 10000);
for (int i : arr) {
System.out.print(i + " ");
}
}
}
以上便是这是个算法的java实现版本,再次鸣谢大佬的分享:https://www.cnblogs.com/onepixel/articles/7674659.ht