八大排序(Java实现)+ 桶排序

2024-05-27 03:04
文章标签 java 实现 排序 八大

本文主要是介绍八大排序(Java实现)+ 桶排序,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

准备工作

排序规则

按照自然序排序(从左往右,从小到大)

工具类

public class SortUtil {/*** 交换 arr[a] 与 arr[b]* @param arr 数组* @param a index a* @param b index b*/public static void swap(int[] arr, int a, int b) {int temp = arr[a];arr[a] = arr[b];arr[b] = temp;}
}

测试类

public class EightSortMethod {public static void main(String[] args) {int[] arr;// 1. 冒泡排序(Bubble Sort): 通过相邻元素的比较和交换来将较大的元素逐渐从后面移动到数组的末尾,较小的元素逐渐从前面移动到数组的开头。arr = new int[]{1, 5, 8, 2, 6, 0, 16, 88, 29, 91, 777};System.out.println(Arrays.toString(BubbleSort.sort(arr)));// 2. 选择排序(Selection Sort): 每次从未排序的部分选择最小(或最大)的元素,然后将其与未排序部分的第一个元素交换,直到所有元素排序完成。arr = new int[]{1, 5, 8, 2, 6, 0, 16, 88, 29, 91, 777};System.out.println(Arrays.toString(SelectionSort.sort(arr)));// 3. 插入排序(Insertion Sort): 将数组分成已排序和未排序两部分,每次从未排序部分取出一个元素插入到已排序部分的适当位置,直到所有元素都插入完毕。arr = new int[]{1, 5, 8, 2, 6, 0, 16, 88, 29, 91, 777};System.out.println(Arrays.toString(InsertionSort.sort(arr)));// 4. 希尔排序(Shell Sort): 是插入排序的一种改进版本,它通过将数组分成多个子序列来排序,每个子序列使用插入排序进行排序,不断缩小子序列的间隔直到为1。arr = new int[]{1, 5, 8, 2, 6, 0, 16, 88, 29, 91, 777};System.out.println(Arrays.toString(ShellSort.sort(arr)));// 5. 归并排序(Merge Sort): 采用分治法的思想,将数组递归地分成两个子数组,然后将两个有序子数组合并为一个有序数组,直到整个数组有序。arr = new int[]{1, 5, 8, 2, 6, 0, 16, 88, 29, 91, 777};System.out.println(Arrays.toString(MergeSort.sort(arr)));// 6. 快速排序(Quick Sort): 也是采用分治法的思想,通过选取一个基准元素,将数组分成两个子数组,左边的子数组小于等于基准元素,右边的子数组大于基准元素,然后递归地对两个子数组进行排序。arr = new int[]{1, 5, 8, 2, 6, 0, 16, 88, 29, 91, 777};System.out.println(Arrays.toString(QuickSort.sort(arr)));// 7. 堆排序(Heap Sort): 利用堆这种数据结构来实现的一种排序算法,通过构建最大堆(或最小堆)来实现排序。arr = new int[]{1, 5, 8, 2, 6, 0, 16, 88, 29, 91, 777};System.out.println(Arrays.toString(HeapSort.sort(arr)));// 8. 计数排序(Counting Sort): 非比较排序算法,适用于一定范围内的整数排序,它通过统计每个元素的个数来实现排序。arr = new int[]{1, 5, 8, 2, 6, 0, 16, 88, 29, 91, 777};System.out.println(Arrays.toString(CountingSort.sort(arr)));}
}

1. 冒泡排序(Bubble Sort)

通过相邻元素的比较和交换来将较大的元素逐渐从后面移动到数组的末尾,较小的元素逐渐从前面移动到数组的开头。

public class BubbleSort {public static int[] sort(int[] arr) {int n = arr.length;for (int i = 0; i < n-1; i++) {for (int j = 0; j < n - 1 - i; j++) {if (arr[j] > arr[j + 1]) SortUtil.swap(arr, j, j + 1);}}return arr;}
}

2. 选择排序(Selection Sort)

每次从未排序的部分选择最小(或最大)的元素,然后将其与未排序部分的第一个元素交换,直到所有元素排序完成。

public class SelectionSort {public static int[] sort(int[] arr) {int n = arr.length;for (int i = 0; i < n; i++) {int minIndex = i;for (int j = i + 1; j < n; j++) {if (arr[j] < arr[minIndex]) minIndex = j;}SortUtil.swap(arr, i, minIndex);}return arr;}
}

3. 插入排序(Insertion Sort)

将数组分成已排序和未排序两部分,每次从未排序部分取出一个元素插入到已排序部分的适当位置,直到所有元素都插入完毕。

public class InsertionSort {public static int[] sort(int[] arr) {int n = arr.length;for (int i = 1; i < n; i++) {int x = arr[i];int end = i-1;while (end >= 0 && arr[end] > x) {arr[end + 1] = arr[end];end--;}arr[end+1] = x;}return arr;}
}

4. 希尔排序(Shell Sort)

是插入排序的一种改进版本,它通过将数组分成多个子序列来排序,每个子序列使用插入排序进行排序,不断缩小子序列的间隔直到为1。

public class ShellSort {public static int[] sort(int[] arr) {int n = arr.length;for (int gap = n / 2; gap > 0; gap /= 2) {for (int i = gap; i < n; i++) {int x = arr[i];int end = i - gap;while (end >= 0 && arr[end] > x) {arr[end + gap] = arr[end];end -= gap;}arr[end + gap] = x;}}return arr;}
}

5. 归并排序(Merge Sort)

采用分治法的思想,将数组递归地分成两个子数组,然后将两个有序子数组合并为一个有序数组,直到整个数组有序。

public class MergeSort {public static int[] sort(int[] arr) {mergeSort(arr, 0, arr.length - 1);return arr;}private static void mergeSort(int[] arr, int l, int r) {if (l >= r) return;int m = l + (r - l) / 2;mergeSort(arr, l, m);mergeSort(arr, m + 1, r);merge(arr, l, m, r);}private static void merge(int[] arr, int l, int m, int r) {int leftLen = m - l + 1;int rightLen = r - m;int[] left = new int[leftLen];int[] right = new int[rightLen];for (int i = 0; i < leftLen; i++) left[i] = arr[l + i];for (int i = 0; i < rightLen; i++) right[i] = arr[m + 1 + i];int lIndex = 0, rIndex = 0, mergeIndex = l;while (lIndex < leftLen && rIndex < rightLen) {arr[mergeIndex++] = left[lIndex] < right[rIndex] ? left[lIndex++] : right[rIndex++];}while (lIndex < leftLen) {arr[mergeIndex++] = left[lIndex++];}while (rIndex < rightLen) {arr[mergeIndex++] = right[rIndex++];}}
}

6. 快速排序(Quick Sort)

也是采用分治法的思想,通过选取一个基准元素,将数组分成两个子数组,左边的子数组小于等于基准元素,右边的子数组大于基准元素,然后递归地对两个子数组进行排序。

public class QuickSort {public static int[] sort(int[] arr) {quickSort(arr, 0, arr.length - 1);return arr;}private static void quickSort(int[] arr, int l, int r) {if (l >= r) return;int pivot = partition(arr, l, r);quickSort(arr, l, pivot - 1);quickSort(arr, pivot + 1, r);}private static int partition(int[] arr, int l, int r) {int pivot = l;while (l < r) {while (l < r && arr[r] >= arr[pivot]) r--;while (l < r && arr[l] <= arr[pivot]) l++;SortUtil.swap(arr, l, r);}SortUtil.swap(arr, l, pivot);return l;}
}

7. 堆排序(Heap Sort)

利用堆这种数据结构来实现的一种排序算法,通过构建最大堆(或最小堆)来实现排序。

public class HeapSort {public static int[] sort(int[] arr) {int n = arr.length;// 建立大根堆for (int i = n / 2 - 1; i >= 0; i--) heapify(arr, n, i);// 删除法调整成小根堆for (int i = n - 1; i > 0; i--) {SortUtil.swap(arr, i, 0);// 注意第二个参数是 i 不是 nheapify(arr, i, 0);}return arr;}private static void heapify(int[] arr, int n, int i) {int largest = i;int left = 2 * i + 1;int right = 2 * i + 2;if (left < n && arr[left] > arr[largest]) largest = left;if (right < n && arr[right] > arr[largest]) largest = right;if (largest != i) {SortUtil.swap(arr, i, largest);heapify(arr, n, largest);}}}

8. 计数排序(Counting Sort)

非比较排序算法,适用于一定范围内的整数排序,它通过统计每个元素的个数来实现排序。

public class CountingSort {public static int[] sort(int[] arr) {int max = Arrays.stream(arr).max().getAsInt();int min = Arrays.stream(arr).min().getAsInt();int range = max - min + 1;int[] count = new int[range];for (int i : arr) count[i - min]++;int j = 0;for (int i = 0; i < range; i++) {while (count[i]-- > 0) arr[j++] = i + min;}return arr;}
}

9. 桶排序(Bucket Sort)

计数排序的改进

public class BucketSort {public static int[] sort(int[] arr) {// Step 1: 确定桶的数量和范围int maxValue = Arrays.stream(arr).max().getAsInt();int minValue = Arrays.stream(arr).min().getAsInt();int range = (maxValue - minValue) / arr.length + 1; // 桶的范围int bucketSize = (maxValue - minValue) / range + 1; // 桶的数量// Step 2: 创建桶并分配元素List<List<Integer>> buckets = new ArrayList<>();for (int i = 0; i < bucketSize; i++) buckets.add(new ArrayList<>());for (int num : arr) {int bucketIndex = (num - minValue) / range;buckets.get(bucketIndex).add(num);}// Step 3: 对每个桶中的元素进行排序(这里使用了Java内置的排序方法)for (List<Integer> bucket : buckets) Collections.sort(bucket);// Step 4: 合并各个桶中的元素int index = 0;for (List<Integer> bucket : buckets) {for (int num : bucket) {arr[index++] = num;}}return arr;}
}

这篇关于八大排序(Java实现)+ 桶排序的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1006344

相关文章

springboot集成easypoi导出word换行处理过程

《springboot集成easypoi导出word换行处理过程》SpringBoot集成Easypoi导出Word时,换行符n失效显示为空格,解决方法包括生成段落或替换模板中n为回车,同时需确... 目录项目场景问题描述解决方案第一种:生成段落的方式第二种:替换模板的情况,换行符替换成回车总结项目场景s

SpringBoot集成redisson实现延时队列教程

《SpringBoot集成redisson实现延时队列教程》文章介绍了使用Redisson实现延迟队列的完整步骤,包括依赖导入、Redis配置、工具类封装、业务枚举定义、执行器实现、Bean创建、消费... 目录1、先给项目导入Redisson依赖2、配置redis3、创建 RedissonConfig 配

SpringBoot中@Value注入静态变量方式

《SpringBoot中@Value注入静态变量方式》SpringBoot中静态变量无法直接用@Value注入,需通过setter方法,@Value(${})从属性文件获取值,@Value(#{})用... 目录项目场景解决方案注解说明1、@Value("${}")使用示例2、@Value("#{}"php

SpringBoot分段处理List集合多线程批量插入数据方式

《SpringBoot分段处理List集合多线程批量插入数据方式》文章介绍如何处理大数据量List批量插入数据库的优化方案:通过拆分List并分配独立线程处理,结合Spring线程池与异步方法提升效率... 目录项目场景解决方案1.实体类2.Mapper3.spring容器注入线程池bejsan对象4.创建

线上Java OOM问题定位与解决方案超详细解析

《线上JavaOOM问题定位与解决方案超详细解析》OOM是JVM抛出的错误,表示内存分配失败,:本文主要介绍线上JavaOOM问题定位与解决方案的相关资料,文中通过代码介绍的非常详细,需要的朋... 目录一、OOM问题核心认知1.1 OOM定义与技术定位1.2 OOM常见类型及技术特征二、OOM问题定位工具

Python的Darts库实现时间序列预测

《Python的Darts库实现时间序列预测》Darts一个集统计、机器学习与深度学习模型于一体的Python时间序列预测库,本文主要介绍了Python的Darts库实现时间序列预测,感兴趣的可以了解... 目录目录一、什么是 Darts?二、安装与基本配置安装 Darts导入基础模块三、时间序列数据结构与

基于 Cursor 开发 Spring Boot 项目详细攻略

《基于Cursor开发SpringBoot项目详细攻略》Cursor是集成GPT4、Claude3.5等LLM的VSCode类AI编程工具,支持SpringBoot项目开发全流程,涵盖环境配... 目录cursor是什么?基于 Cursor 开发 Spring Boot 项目完整指南1. 环境准备2. 创建

Python使用FastAPI实现大文件分片上传与断点续传功能

《Python使用FastAPI实现大文件分片上传与断点续传功能》大文件直传常遇到超时、网络抖动失败、失败后只能重传的问题,分片上传+断点续传可以把大文件拆成若干小块逐个上传,并在中断后从已完成分片继... 目录一、接口设计二、服务端实现(FastAPI)2.1 运行环境2.2 目录结构建议2.3 serv

C#实现千万数据秒级导入的代码

《C#实现千万数据秒级导入的代码》在实际开发中excel导入很常见,现代社会中很容易遇到大数据处理业务,所以本文我就给大家分享一下千万数据秒级导入怎么实现,文中有详细的代码示例供大家参考,需要的朋友可... 目录前言一、数据存储二、处理逻辑优化前代码处理逻辑优化后的代码总结前言在实际开发中excel导入很

Spring Security简介、使用与最佳实践

《SpringSecurity简介、使用与最佳实践》SpringSecurity是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架,本文给大家介绍SpringSec... 目录一、如何理解 Spring Security?—— 核心思想二、如何在 Java 项目中使用?——