网上很多Java排序算法有错误,以下是本人经过整理校验后的算法。
1、冒泡排序
public class BubbleSort {
public static void bubbleSort(int[] data) {
int temp = 0;
int len = data.length;
for (int i = 0; i < len - 1; i++) { //最多n-1趟,最后一个元素不用排
for (int j = len - 1; j > i; j--) {
if (data[j] < data[j - 1]) //交换两数位置
{
temp = data[j];
data[j] = data[j - 1];
data[j - 1] = temp;
}
}
}
}
public static void main(String[] args) {
int[] values = {100, 23, 11, 78, 98, 34, 15, 90, 88, 45, 74, 56};
bubbleSort(values);
System.out.println(Arrays.toString(values));
}
}
2、快速排序
public class QuickSort {
/**
* 查找出中轴(默认是最低位low)的在numbers数组排序后所在位置
*
* @param data 带查找数组
* @param low 开始位置
* @param high 结束位置
* @return 中轴所在位置
*/
public static int getMiddle(int[] data, int low, int high) {
int mid = data[low]; //数组的第一个作为中轴
while (low < high) {
while (low < high && data[high] > mid) {
high--;
}
data[low] = data[high];//比中轴小的记录移到低端
while (low < high && data[low] < mid) {
low++;
}
data[high] = data[low]; //比中轴大的记录移到高端
}
data[low] = mid; //中轴记录到尾
System.out.println("low:"+low + " hight:"+high);
return low; // 返回中轴的位置
}
/**
* @param data 带排序数组
* @param low 开始位置
* @param high 结束位置
*/
public static void sort(int[] data, int low, int high) {
if (low < high) {
int middle = getMiddle(data, low, high); //将numbers数组进行一分为二
sort(data, low, middle - 1); //对低字段表进行递归排序
sort(data, middle + 1, high); //对高字段表进行递归排序
}
}
/**
* 快速排序
*
* @param numbers 带排序数组
*/
public static void quickSort(int[] data) {
if (data.length > 0) //查看数组是否为空
{
sort(data, 0, data.length - 1);
}
}
public static void main(String[] args) {
int[] values = {100, 23, 11, 78, 98, 34, 15, 90, 88, 45, 74, 56};
quickSort(values);
System.out.println(Arrays.toString(values));
}
}
3、选择排序
public class SelectSort {
/**
* 选择排序算法
* 在未排序序列中找到最小元素,存放到排序序列的起始位置
* 再从剩余未排序元素中继续寻找最小元素,然后放到排序序列末尾。
* 以此类推,直到所有元素均排序完毕。
* @param numbers
*/
public static void selectSort(int[] numbers)
{
int len = numbers.length; //数组长度
int temp = 0 ; //中间变量
for(int i = 0 ; i < len ; i++)
{
int k = i; //待确定的位置
//选择出应该在第i个位置的数
for(int j = len -1 ; j > i ; j--)
{
if(numbers[j] < numbers[k]) //找出最小的位置
{
k = j;
}
}
//交换两个数
temp = numbers[i];
numbers[i] = numbers[k];
numbers[k] = temp;
}
}
public static void main(String[] args) {
int[] values = {100, 23, 11, 78, 98, 34, 15, 90, 88, 45, 74, 56};
selectSort(values);
System.out.println(Arrays.toString(values));
}
}
4、堆排序
public class HeapSort {
/**
* 构建大根堆
*/
public static void adjustHeap(int[] data, int i, int len) {
int temp, j;
temp = data[i];
for (j = 2 * i + 1; j < len - 1; j = j * 2 + 1) {// 沿关键字较大的孩子结点向下筛选
if (j < len - 1 && data[j] < data[j + 1])
j++; //取左右孩子最大值的下标
if (temp < data[j]) {
data[i] = data[j];
i = j;
} else //调整结束
break;
}
data[i] = temp;
}
public static void heapSort(int[] data) {
int i;
int len = data.length;
for (i = len / 2 - 1; i >= 0; i--) {// 构建一个大根堆
adjustHeap(data, i, len);
}
for (i = len - 1; i >= 0; i--) {// 将堆顶记录和当前未经排序子序列的最后一个记录交换
int temp = data[0];
data[0] = data[i];
data[i] = temp;
adjustHeap(data, 0, i);// 将a中前i个记录重新调整为大根堆
}
}
public static void main(String[] args) {
int[] values = {100, 23, 11, 78, 98, 34, 15, 90, 88, 45, 74, 56};
heapSort(values);
System.out.println(Arrays.toString(values));
}
}
5、插入排序
public class InsertSort {
/**
* 插入排序
*
* 从第一个元素开始,该元素可以认为已经被排序
* 取出下一个元素,在已经排序的元素序列中从后向前扫描
* 如果该元素(已排序)大于新元素,将该元素移到下一位置
* 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
* 将新元素插入到该位置中
* 重复步骤2
*
* @param data 待排序数组
*/
public static void insertSort(int[] data) {
int len = data.length;
int temp = 0;
int j = 0;
for (int i = 0; i < len; i++) {
temp = data[i];
//假如temp比前面的值小,则将前面的值后移
for (j = i-1; j >= 0 && temp < data[j]; j--) {
data[j+1] = data[j];
}
data[j+1] = temp;
}
}
public static void main(String[] args) {
int[] values = {100, 23, 11, 78, 98, 34, 15, 90, 88, 45, 74, 56};
insertSort(values);
System.out.println(Arrays.toString(values));
}
}
6、希尔排序
public class ShellSort {
public static void shellSort(int[] data) {
// i表示希尔排序中的第n/2+1个元素(或者n/4+1)
// j表示希尔排序中从0到n/2的元素(n/4)
// r表示希尔排序中n/2+1或者n/4+1的值
int i, j, temp;
// 划组排序
int length = data.length;
int gap = length / 2;
while (gap >= 1) {
//每个序列的步长应该是gap,多个序列和在一起执行了,因为算法都一样
for (i = gap; i < length; i++) {
temp = data[i]; //待插入元素
// 一轮排序
for (j = i - gap; j >= 0 && temp < data[j]; j -= gap) {
data[j + gap] = data[j]; //元素后移
}
data[j + gap] = temp; //插入
}
gap /= 2;
}
}
public static void main(String[] args) {
int[] values = {100, 23, 11, 78, 98, 34, 15, 90, 88, 45, 74, 56};
shellSort(values);
System.out.println(Arrays.toString(values));
}
}
7、归并排序
public static int[] sort(int[] data, int low, int high) {
int mid = (low + high) / 2;
if (low < high) {
// 左边
sort(data, low, mid);
// 右边
sort(data, mid + 1, high);
// 左右归并
merge(data, low, mid, high);
}
return data;
}
/**
* 将数组中low到high位置的数进行排序
* @param data 待排序数组
* @param low 待排的开始位置
* @param mid 待排中间位置
* @param high 待排结束位置
*/
public static void merge(int[] data, int low, int mid, int high) {
int[] temp = new int[high - low + 1];
int i = low;// 左指针
int j = mid + 1;// 右指针
int k = 0;
// 把较小的数先移到新数组中
while (i <= mid && j <= high) {
if (data[i] < data[j]) {
temp[k++] = data[i++];
} else {
temp[k++] = data[j++];
}
}
// 把左边剩余的数移入数组
while (i <= mid) {
temp[k++] = data[i++];
}
// 把右边边剩余的数移入数组
while (j <= high) {
temp[k++] = data[j++];
}
// 把新数组中的数覆盖data数组
for (int k2 = 0; k2 < temp.length; k2++) {
data[k2 + low] = temp[k2];
}
}
public static void mergeSort(int[] data){
sort(data,0,data.length - 1);
}
public static void main(String[] args) {
int[] values = {100, 23, 11, 78, 98, 34, 15, 90, 88, 45, 74, 56};
mergeSort(values);
System.out.println(Arrays.toString(values));
}
}