博客
关于我
9. 排序算法 - java实现
阅读量:390 次
发布时间:2019-03-05

本文共 5944 字,大约阅读时间需要 19 分钟。

基本概念说明

术语说明

  • 稳定:在排序过程中,相同的值保持相对位置不变。
  • 不稳定:在排序过程中,相同的值可能改变相对位置。
  • 内排序:所有数据都存放在内存中进行排序。
  • 外排序:部分数据存放在内存,部分存放在外存中进行排序。

各种排序算法的复杂度

以下是几种常见排序算法的平均情况、最好情况和最差情况的时间复杂度,以及辅助空间和稳定性:

排序算法 平均情况复杂度 最好情况复杂度 最差情况复杂度 辅助空间 稳定性
冒泡排序 O(n²) O(n) O(n²) O(1) 稳定
快速排序 O(n log n) O(n log n) O(n²) O(log n) 不稳定
简单选择排序 O(n²) O(n²) O(n²) O(1) 稳定
堆排序 O(n log n) O(n log n) O(n log n) O(1) 不稳定
归并排序 O(n log n) O(n log n) O(n log n) O(n) 稳定
希尔排序 O(n log n) O(n²) O(n²) O(1) 稳定
直接插入排序 O(n²) O(n²) O(n²) O(1) 稳定

逐步解释

1.1 术语说明

稳定排序算法在排序过程中保持相同值的相对位置不变,而不稳定排序算法可能会改变相同值的位置。

1.2 各种排序算法的复杂度

排序算法的时间复杂度主要由平均情况决定,但在最坏情况下可能会显著降低效率。


冒泡排序

基本描述

冒泡排序是一种简单的比较排序算法,通过多次对比和交换,逐步将较大的元素“冒”到已排序区域的最后。

改进方法

传统的冒泡排序每次都从第一个元素开始对比,导致时间复杂度较高。改进后的冒泡排序可以通过记录最后一次交换的位置,提前终止排序过程。

优化代码

public class BubbleSort {
public static void main(String[] args) {
int[] array = {3, 1, 4, 2, 5};
bubbleSort(array);
System.out.println(Arrays.toString(array));
}
private static void bubbleSort(int[] array) {
boolean swapped = true;
for (int i = 0; i < array.length; i++) {
if (!swapped) break;
swapped = false;
for (int j = 0; j < array.length - i - 1; j++) {
if (array[j] > array[j + 1]) {
swap(array, j, j + 1);
swapped = true;
}
}
}
}
private static void swap(int[] array, int i, int j) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}

快速排序

基本描述

快速排序是一种高效的分治排序算法,通过选择一个基准值并将数组划分为左右两部分,递归排序左右子数组。

优化方法

为了减少递归深度和提高效率,可以采用三数取中法选择基准值,并在小数组中使用插入排序。

优化代码

public class QuickSort {
private static final int MAX_LENGTH_INSERTION_SORT = 7;
public static void main(String[] args) {
int[] array = {50, 10, 90, 30, 70, 40, 80, 60, 20};
quickSort(array);
System.out.println(Arrays.toString(array));
}
private static int[] quickSort(int[] array) {
if (array == null) {
throw new NullPointerException("array is null!");
}
if (array.length <= MAX_LENGTH_INSERTION_SORT) {
insertionSort(array);
return array;
}
int pivotIndex = partition(array);
int[] left = new int[pivotIndex];
int[] right = new int[array.length - pivotIndex - 1];
System.arraycopy(array, 0, left, 0, pivotIndex);
System.arraycopy(array, pivotIndex + 1, right, 0, right.length);
return merge(quickSort(left), quickSort(right));
}
private static int partition(int[] array) {
int pivot = array[0];
int low = 0;
int high = array.length - 1;
while (low < high) {
while (high > low && array[high] >= pivot) {
high--;
}
swap(array, low, high);
while (low < high && array[low] <= pivot) {
low++;
}
swap(array, low, high);
}
return low;
}
private static void swap(int[] array, int i, int j) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
private static int[] merge(int[] left, int[] right) {
int[] result = new int[left.length + right.length];
int i = 0, j = 0;
for (int k = 0; k < result.length; k++) {
if (i < left.length && (j >= right.length || left[i] <= right[j])) {
result[k] = left[i++];
} else {
result[k] = right[j++];
}
}
return result;
}
private static void insertionSort(int[] array) {
for (int i = 1; i < array.length; i++) {
int temp = array[i];
int j = i - 1;
while (j >= 0 && array[j] > temp) {
array[j + 1] = array[j];
j--;
}
array[j + 1] = temp;
}
}
}

希尔排序

基本描述

希尔排序通过将数组按固定增量分组,对每组使用插入排序算法进行排序,最终通过逐渐减小增量完成整个数组的排序。

优化代码

public class ShellSort {
public static void main(String[] args) {
int[] array = {50, 10, 90, 30, 70, 40, 80, 60, 20};
shellSort(array);
System.out.println(Arrays.toString(array));
}
private static void shellSort(int[] array) {
int gap = array.length / 2;
while (gap > 0) {
for (int i = gap; i < array.length; i++) {
for (int j = i; j >= gap; j -= gap) {
if (array[j] < array[j - gap]) {
swap(array, j, j - gap);
}
}
}
gap /= 2;
}
}
private static void swap(int[] array, int i, int j) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}

归并排序

基本描述

归并排序通过将数组分成两半,分别对每半使用归并排序,再将有序的子数组合并成一个完整有序数组。

实现代码

public class MergeSort {
public static void main(String[] args) {
int[] array = {50, 10, 90, 30, 70, 40, 80, 60, 20};
int[] sortedArray = mergeSort(array);
System.out.println(Arrays.toString(sortedArray));
}
private static int[] mergeSort(int[] array) {
if (array.length <= 1) {
return array;
}
int mid = array.length / 2;
int[] left = Arrays.copyOfRange(array, 0, mid);
int[] right = Arrays.copyOfRange(array, mid, array.length);
int[] sortedLeft = mergeSort(left);
int[] sortedRight = mergeSort(right);
return merge(sortedLeft, sortedRight);
}
private static int[] merge(int[] left, int[] right) {
int[] result = new int[left.length + right.length];
int i = 0, j = 0;
for (int k = 0; k < result.length; k++) {
if (i < left.length && (j >= right.length || left[i] <= right[j])) {
result[k] = left[i++];
} else {
result[k] = right[j++];
}
}
return result;
}
}

总结

以上是对几种常见排序算法的详细介绍,包括基本描述、优化方法和实现代码。通过合理选择排序算法和优化策略,可以在不同的场景下实现高效的数据排序。

转载地址:http://lnhwz.baihongyu.com/

你可能感兴趣的文章
Neo私链
查看>>
nessus快速安装使用指南(非常详细)零基础入门到精通,收藏这一篇就够了
查看>>
Nessus漏洞扫描教程之配置Nessus
查看>>
Nest.js 6.0.0 正式版发布,基于 TypeScript 的 Node.js 框架
查看>>
NetApp凭借领先的混合云数据与服务把握数字化转型机遇
查看>>
NetBeans IDE8.0需要JDK1.7及以上版本
查看>>
netcat的端口转发功能的实现
查看>>
netfilter应用场景
查看>>
netlink2.6.32内核实现源码
查看>>
Netpas:不一样的SD-WAN+ 保障网络通讯品质
查看>>
NetScaler的常用配置
查看>>
netsh advfirewall
查看>>
NETSH WINSOCK RESET这条命令的含义和作用?
查看>>
Netty WebSocket客户端
查看>>
netty 主要组件+黏包半包+rpc框架+源码透析
查看>>
Netty 异步任务调度与异步线程池
查看>>
Netty中集成Protobuf实现Java对象数据传递
查看>>
Netty事件注册机制深入解析
查看>>
Netty原理分析及实战(四)-客户端与服务端双向通信
查看>>
Netty客户端断线重连实现及问题思考
查看>>