常见排序算法
来源:互联网 发布:$sql 编辑:程序博客网 时间:2024/06/11 07:21
/* * 排序算法: * 交换排序:快速排序(O(NlogN),不稳定)、冒泡排序(O(N^2),稳定) * 插入排序:直接插入排序(O(N^2),稳定)、希尔排序(O(N^1.3)不稳定) * 选择排序:直接选择排序(O(N^2),不稳定),堆排序(O(NlogN),不稳定) * 归并排序(O(NlogN),稳定) */public class Sort { /* * 1.快速排序,该方法有三个参数,数组arr,需要进行排序的部分数组(由low和high截取),然后找 * 一个基准值(一般为需要排序的数组的第一个元素),确定基准值所在的位置(start=end时),再使用 * 递归对基准值两边的元素继续进行快排。 * * 简言之,快排第一步就是确定基准值的位置,然后再进行递归求解。 */ public static void quicklySort(int arr[], int low, int high) { int key = arr[low]; int start = low; int end = high; while (start < end){ while (arr[end] >= key && start < end){ end--; } arr[start] = arr[end]; while (arr[start] <= key && start < end){ start++; } arr[end] = arr[start]; } arr[start] = key; // 将基准值填到相应位置 if (start > low) quicklySort(arr, low, start - 1); if (end < high) quicklySort(arr, end + 1, high); } /* * 2.冒泡排序,遇见比当前数小的就交换顺序 */ public static void bubbleSort(int arr[]) { int temp; for (int i = 0; i < arr.length; i++){ for (int j = arr.length - 1; j > i; j--){ //从后往前冒,当然也可以从前往后沉 if (arr[j] < arr[j - 1]){ temp = arr[j]; arr[j] = arr[j - 1]; arr[j - 1] = temp; } } } } /* * 3.直接插入排序,假设数组第一个元素自成一个有序序列,从第二个元素起,依次与前面的元素进行 * 比较,插入到正确的位置以构成有序序列,直到最后一个元素插入到正确位置从而使得整个数组有序。 */ public static void insertionSort(int arr[]) { int temp; for (int i = 1; i < arr.length; i++){ //i表示从哪个位置的元素开始与它之前的元素进行比较 int j = i; while (j > 0 && arr[j] < arr[j - 1] ){//这里不用for循环是因为使用for循环则无论arr[j]是否小于arr[j-1],都要进行j--的操作 temp = arr[j]; arr[j] = arr[j - 1]; arr[j - 1] = temp; j--; } } } /* * 4.希尔排序,改进的直接插入排序,先将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的)分别进行 * 直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入 * 排序。因为直接插入排序在元素基本有序的情况下(接近最好情况),效率是很高的,因此希尔排序在时间效率上比前两种方法有 * 较大提高。步长的选择是希尔排序的重要部分。只要最终步长为1任何步长序列都可以工作。 */ public static void shellSort(int arr[]) { int increment; for (increment = arr.length / 2; increment > 0; increment /= 2){ //增量之后进行直接插入排序 for (int j = increment; j < arr.length; j++){ if (arr[j] < arr[j - increment]){ int temp = arr[j]; int k = j - increment; while (k >= 0 && arr[k] > temp){ arr[k + increment] = arr[k]; k -= increment; } arr[k + increment] = temp; } } } } /* * 5.直接选择排序,思想就是从第一个元素开始遍历数组,找到数组中的最小元素跟第一个元素交换 * 位置,然后接着从第二个元素开始重复刚才的过程,直到最后一个元素,跟冒泡不同,直接选择排序 * 是每一次遍历只交换一次元素,而冒泡则是只要发现当前元素比前面的元素小就要交换位置。 */ public static void selectionSort(int arr[]) { int min;//记录最小元素的索引位置 int temp; for (int i = 0; i < arr.length - 1; i++){ min = i; for (int j = i + 1; j < arr.length; j++){ if (arr[j] < arr[min]){ min = j; } } temp = arr[i]; arr[i] = arr[min]; arr[min] = temp; } } /* * 6.堆排序,升序构建最大堆(父大于子), * 首先,构建最大堆buildMaxHeap();需要借助筛选函数heapScreen(); * 其次,将堆顶元素跟堆得最后一个元素交换位置(最大值放后边) * */ //n为构建堆的节点总数 public static void buildMaxHeap(int arr[], int n) { //1.构建最大堆 for (int i = (n - 1) / 2; i >= 0; i--){//从最后一个非叶子结点开始筛选 i = (n - 1) / 2 heapScreen(arr, i, n); } } //筛选,即调整元素位置,使之满足最大堆的性质,i为开始节点,n为节点总数 public static void heapScreen(int arr[], int i, int n) { int temp = arr[i]; int j = 2 * i + 1;//左孩子 while (j < n){ if (j + 1 < n && arr[j] < arr[j + 1]) j++; if (arr[j] <= temp) break; arr[i] = arr[j]; i = j; j = 2 * i + 1; } arr[i] = temp; } public static void heapSort(int arr[]) { for (int i = arr.length; i > 0; i-- ){ buildMaxHeap(arr,i); System.out.println(arr[0]); //注意:这里交换元素不能用swap函数,这涉及到引用传递的问题。详情见博客 int temp = arr[0]; arr[0] = arr[i - 1]; arr[i - 1] = temp; } } /*7、归并排序 * 步骤:先递归拆分(sort),然后合并(merge),排序在合并中实现 */ public static void mergeSort(int arr[]){ sort(arr, 0, arr.length - 1); } public static void sort(int arr[], int low, int high) { if (low < high){ int mid = (low + high) / 2; sort(arr, 0, mid); sort(arr, mid + 1, high); merge(arr, low, mid, high); } } public static void merge(int arr[], int low, int mid, int high) { int i = low; int j = mid + 1; int temp[] = new int[arr.length];//定义长度为arr.length的数组是为了下标能跟arr对上 int k = low;//临时数组temp的下标 while (i <= mid && j <= high){ if (arr[i] <= arr[j]) temp[k++] = arr[i++]; else temp[k++] = arr[j++]; } while (i <= mid) temp[k++] = arr[i++]; while (j <= high) temp[k++] = arr[j++]; for (int n = low; n <= high; n++) arr[n] = temp[n]; }}
0 0
- 常见的排序算法
- 常见排序算法
- 常见排序算法代码
- 常见排序算法
- 常见排序算法总结
- 常见排序算法
- 常见排序算法学习
- 常见排序算法总结
- 常见的排序算法
- 常见排序算法分析
- 常见排序算法总结
- 常见排序算法
- 常见排序算法
- 常见排序算法介绍
- 常见排序算法小结
- 常见排序算法总结
- 常见经典排序算法
- 常见排序算法
- 线索二叉树C/C++
- gcc/g++ 动态编译和链接问题
- mysql 特殊函数
- iOS10 不能跳转系统设置解决办法(1)
- gcc/g++编译参数详解
- 常见排序算法
- list转换datatable
- iReport-5.6.0启动闪退的某些原因
- Glide 动态设置图片宽高的解决办法
- php手册精句收集
- 【干货】英雄联盟选择JFrog Artifactory 作为Docker注册中心的八大理由
- IntelliJ IDEA一些好用的功能(持续更新)
- 今年目标,随时更新
- jquery datatables 图标的导出功能(excel pdf之类)文件