java实现各种排序_Java实现各种常用的排序算法

冒泡排序

/**

* 冒泡排序(大的值从前往后冒泡)

* 优点:稳定排序;适用于数组存储的数据和链表存储的数据;

*/

public static int[] bubbleSort(int[] a) {

for (int end = a.length - 1; end > 0; end--) {

boolean flag = false; //增加一个判断是否发生过交换的标记

for (int j = 0; j < end; j++) {

if (a[j] > a[j + 1]) {

swap(a, j, j + 1);

flag = true;

}

}

if (!flag) { //如果扫描一遍发现没有发生交换则说明序列已经有序,退出循环

break;

}

}

return a;

}

/**

* 冒泡排序(小的值从后往前下沉)

* 优点:稳定排序;适用于数组存储的数据和链表存储的数据;

*/

public static int[] bubbleSort2(int[] a) {

for (int start = 0; start < a.length - 1; start++) {

boolean flag = false; //增加一个判断是否发生过交换的标记

for (int j = a.length - 1; j > start; j--) {

if (a[j] < a[j - 1]) {

swap(a, j, j - 1);

flag = true;

}

}

if (!flag) { //如果扫描一遍发现没有发生交换则说明序列已经有序,退出循环

break;

}

}

return a;

}

插入排序

/**

* 插入排序

*/

public static int[] insertSort(int[] a) {

for (int i = 1; i < a.length; i++) {

int temp = a[i];

int j = i;

while (j > 0 && temp < a[j - 1]) {

a[j] = a[j - 1];

j--;

}

a[j] = temp;

}

return a;

}

二分排序

/**

* 二分排序

* 也称折半插入排序,查找次数为O(n log n),移动次数为O(n^2)

* Time complexity: O(n^2)

* 稳定性:稳定排序

*/

public static int[] binarySort(int[] a) {

int i, j;

int low, high, mid;

int temp;

for (i = 1; i < a.length; i++) {

temp = a[i];

low = 0;

high = i - 1;

while (low <= high) {

mid = (low + high) / 2;

if (a[mid] > temp) {

high = mid - 1;

} else {

low = mid + 1;

}

}

for (j = i - 1; j > high; j--) {

a[j + 1] = a[j];

}

a[high + 1] = temp;

}

return a;

}

选择排序

/**

* 选择排序

*/

public static int[] selectionSort(int[] a) {

for (int i = 0; i < a.length; i++) {

for (int j = i + 1; j < a.length; j++) {

if (a[i] > a[j]) {

swap(a, i, j);

}

}

System.out.println(Arrays.toString(a));

}

return a;

}

希尔排序

/**

* 希尔排序

*/

public static int[] shellSort(int[] a) {

int gap = a.length / 2;

while (gap >= 1) {

for (int i = gap; i < a.length; i++) {

int j;

int temp = a[i];

for (j = i - gap; j >= 0 && temp < a[j]; j = j - gap) {

a[j + gap] = a[j];

}

a[j + gap] = temp;

}

gap /= 2;

}

return a;

}

堆排序

/**

* 堆排序

*/

public static int[] heapSort(int[] a) {

buildMaxHeap(a, a.length - 1);

swap(a, 0, a.length - 1);

for (int i = 1; i < a.length - 1; i++) {

adjustMaxHeap(a, 0, a.length - 1 - i);

swap(a, 0, a.length - 1 - i);

}

return a;

}

public static void buildMaxHeap(int[] data, int lastIndex) {

for (int i = (lastIndex - 1) / 2; i >= 0; i--) {

adjustMaxHeap(data, i, lastIndex);

}

}

public static void adjustMaxHeap(int[] data, int parent, int lastIndex) {

/*

* 通常堆是通过一维数组来实现的。在数组起始位置为 0 的情形中:

* 父节点 i 的左子节点在位置 (2*i+1);

* 父节点 i 的右子节点在位置 (2*i+2);

* 子节点 i 的父节点在位置 floor((i-1)/2);

*/

while (2 * parent + 1 <= lastIndex) {

int maxChildIndex = 2 * parent + 1;

// 如果当前左孩子不是末尾元素

if (maxChildIndex < lastIndex) {

// 如果左孩子小于右孩子,取右孩子下标

if (data[maxChildIndex] < data[maxChildIndex + 1]) {

maxChildIndex++;

}

}

// 比较当前父节点和最大孩子节点

if (data[parent] < data[maxChildIndex]) {

swap(data, parent, maxChildIndex);

parent = maxChildIndex;

} else {

break;

}

}

}

public static void swap(int[] data, int i, int j) {

int temp = data[i];

data[i] = data[j];

data[j] = temp;

}

快速排序

/**

* 快速排序

*/

public static int[] quickSort(int[] a) {

if (a.length > 0) {

quickSortRecursion(a, 0, a.length - 1);

}

return a;

}

public static void quickSortRecursion(int[] data, int low, int high) {

if (low < high) {

int middle = partition(data, low, high);

quickSortRecursion(data, low, middle - 1);

quickSortRecursion(data, middle + 1, high);

}

}

public static int partition(int[] data, int low, int high) {

int temp = data[low]; // 数组的第一个作为中轴

while (low < high) {

while (low < high && data[high] >= temp) {

high--;

}

data[low] = data[high]; // 比中轴小的记录移到低端

while (low < high && data[low] <= temp) {

low++;

}

data[high] = data[low]; // 比中轴大的记录移到高端

}

data[low] = temp;

return low; // 返回中轴的位置

}

/**

* 快速排序的第二种写法

*/

public static int[] quickSort2(int[] a) {

qSort(a, 0, a.length - 1);

return a;

}

public static void qSort(int[] sequence, int low, int high) {

int pivot = sequence[low]; // 取首元素的为基准

int left = low, right = high;

if (low >= high) {

return;

}

swap(sequence, low, high); //将基准与最后一个元素交换

while (true) {

//将序列中比基准小的移到基准左边,比基准大的移到基准右边

while (low < high && sequence[low] <= pivot) {

low++;

}

while (low < high && sequence[high] >= pivot) {

high--;

}

if (low < high) {

swap(sequence, low, high);

} else {

break;

}

}

swap(sequence, low, right); //将最后的基准换到正确的位置

//分别对两个子集进行快排

qSort(sequence, left, low - 1);

qSort(sequence, low + 1, right);

}

归并排序

/**

* 归并排序

*/

public static int[] mergingSort(int[] a) {

if (a.length > 0) {

mergingSortRecursion(a, 0, a.length - 1);

}

return a;

}

public static void mergingSortRecursion(int[] data, int left, int right) {

if (left < right) {

int middle = (left + right) / 2;

mergingSortRecursion(data, left, middle);

mergingSortRecursion(data, middle + 1, right);

merge(data, left, middle, right);

}

}

public static void merge(int[] data, int left, int middle, int right) {

int[] tempArray = new int[data.length];

int i = left; // 左边序列的游标

int j = middle + 1; // 右边序列的游标

int k = left; // 临时序列的游标

// 从两个数组中取出最小的放入中间数组

while (i <= middle && j <= right) {

if (data[i] <= data[j]) {

tempArray[k++] = data[i++];

} else {

tempArray[k++] = data[j++];

}

}

// 剩余部分依次放入中间数组

while (j <= right) {

tempArray[k++] = data[j++];

}

while (i <= middle) {

tempArray[k++] = data[i++];

}

// 将中间数组中的内容复制回原数组

while (left <= right) {

data[left] = tempArray[left++];

}

}

基数排序

/**

* 基数排序

*/

public static int[] radixSort(int[] a) {

int max = 0;

for (int i = 0; i < a.length; i++) {

max = a[i] > max ? a[i] : max;

}

int time = 0;

while (max > 0) {

time++;

max /= 10;

}

List> queue = new ArrayList<>();

for (int i = 0; i < 10; i++) {

queue.add(new ArrayList<>());

}

for (int i = 0; i < time; i++) {

// 按某位对原数组进行一趟排序

for (int j = 0; j < a.length; j++) {

int d = a[j] % (int) Math.pow(10, i + 1) / (int) Math.pow(10, i);

ArrayList list = queue.get(d);

list.add(a[j]);

queue.set(d, list);

}

// 把queue进行过一趟排序的数据拷贝回原数组

int count = 0;

for (int k = 0; k < 10; k++) {

while (queue.get(k).size() > 0) {

a[count] = queue.get(k).get(0);

queue.get(k).remove(0);

count++;

}

}

}

return a;

}

计数排序

/**

* 计数排序法1 取出序号用了少量的比较和循环

*/

public static int[] countingSort1(int[] a) {

int max = 0;

for (int i = 0; i < a.length; i++) {

max = a[i] > max ? a[i] : max;

}

int[] count = new int[max + 1];

for (int i = 0; i < a.length; i++) {

count[a[i]]++;

}

int sum = 0;

for (int i = 0; i < count.length; i++) {

if (count[i] > 0) {

for (int j = 0; j < count[i]; j++) {

a[sum + j] = i;

}

}

sum += count[i];

}

return a;

}

/**

* 计数排序法2 完全没有使用比较和循环

*/

public static int[] countingSort2(int[] a) {

int max = 0;

for (int i = 0; i < a.length; i++) {

max = a[i] > max ? a[i] : max;

}

int[] count = new int[max + 1];

for (int i = 0; i < a.length; i++) {

count[a[i]]++;

}

for (int i = 1; i < count.length; i++) {

count[i] += count[i - 1];

}

int[] b = new int[a.length];

for (int i = 0; i < a.length; i++) {

b[count[a[i]] - 1] = a[i];

count[a[i]]--;

}

return b;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值