数据结构中几种排序算法的整理
2017-01-03 16:10
465 查看
几种排序算法的整理
选择排序交换排序
插入排序
归并排序
各种排序算法的比较
1. 选择排序
主要思想: 给定一个序列,从中选出一个最值作为第一个元素,之后重复这一步骤,直到所有元素都被放置在确定的位置,主要的算法有简单选择排序和堆排序。简单选择排序
该算法的平均时间复杂度是O(n^2),空间复杂度为O(1),属于不稳定排序。每趟排序都能定下一个元素的位置。以下为算法的实现代码:
public static void SelectSort(int[] array, int n) { int min, k; for (int i = 0; i < n; i++) { min = i;//min用于标记最小元素的下标位置 for (int j = i; j < n; j++) { if (array[j] < array[min]) { min = j; } } if (i != min) { k = array[i]; array[i] = array[min]; array[min] = k; } } }
即给定一个数组,从下标i=0开始判断,每次找寻出最小的元素,与i位置的元素交换,使得每次的最小值放置到i处,i++,重复以上操作,直到i=n-1,结束排序。
堆排序
该算法的平均时间复杂度是O(nlogn),空间复杂度为O(1),属于不稳定排序算法。每趟排序都能定下一个元素的位置。以下为算法的实现代码:
public static void HeapSort(int[] arrayt, int n) { int[] array = new int[n + 1]; for (int i = 1; i <= n; i++) array[i] = arrayt[i - 1];// 数组从下标1开始存数据,便于树的遍历 int k; for (int i = n / 2; i > 0; i--) // 初始化调整堆,从n/2(最后一个非叶子结点)处向上调整堆 HeapAdjust(array, i, n); for (int i = n; i > 1; i--) { // 每次调整,都能确定一个元素的位置 放在i位置 k = array[i]; array[i] = array[1]; array[1] = k;// 将堆顶元素与未排序序列的最后一个元素互换 HeapAdjust(array, 1, i - 1);// 调整堆 } for (int j = 1; j < n; j++) System.out.print(array[j] + " "); System.out.println(array ); } /** 向下调整堆的算法 * array 待排序数组 * s 堆调整的起始下标 * m 堆调整的终止下标 */ public static void HeapAdjust(int[] array, int s, int m) { int k = array[s]; for (int i = 2 * s; i <= m; i = i * 2) { if (i < m && array[i] < array[i + 1])// 求出左右子树中比较小的结点 i++; if (k >= array[i]) // 使得父节点为最大值结点 break; array[s] = array[i]; s = i; } array[s] = k; }
即,将数组元素搭建成树形结构,首先建立初始堆(大顶堆),然后将堆顶元素和未排序序列的最后一个元素互换。之后不断调整堆,并交换堆顶元素和未排序序列的最后一个元素。重复上述操作,直到所有元素排序完成。
2. 交换排序
主要思想:不断比较序列中两个元素的大小,并做一定的交换调整,直到整个序列有序。主要的算法有冒泡排序和快速排序。冒泡排序
该算法的平均时间复杂度是O(n^2),空间复杂度为O(1),属于稳定排序。每趟排序都能定下一个元素的位置。以下为算法的实现代码:
public static void BubbleSort(int[] array, int n) { boolean flag;// 作为标记 for (int i = n - 1; i >= 0; i--) {// 每次遍历 确定一个最大元素 放在i处 flag = false; int k; for (int j = 0; j < i; j++) { if (array[j] > array[j + 1]) { flag = true; k = array[j]; array[j] = array[j + 1]; array[j + 1] = k; } } if (!flag) break; } }
从下标j=0开始,不断比较左右两个元素的大小,将大的元素放在右边,直到j=i,将最大的元素放在i处,之后i–,而j又从0开始判断。其中flag用于标记该趟比较时候已经有序,有序flag=false,停止遍历,结束。
快速排序
该算法的平均时间复杂度是O(nlogn),空间复杂度为O(logn),属于不稳定排序。每趟排序都能定下一个元素的位置。以下为算法的实现代码:
public static void QuickSort(int[] array, int n) { Qsort(array, 0, n - 1); } // 递归形式 划分 cb89 后 分别排序 public static void Qsort(int[] array, int low, int high) { if (low < high) { int pivotLoc = Partition(array, low, high);//求出枢轴的位置 Qsort(array, low, pivotLoc - 1);//根据枢轴划分左右,分别排序 Qsort(array, pivotLoc + 1, high); } } // 一次划分,找出枢轴最后落下的i位置 public static int Partition(int[] array, int low, int high) { int pivot = array[low];// 子表第一个元素作为枢轴 while (low < high) { while (low < high && array[high] >= pivot) high--;//跟高位比较大小,直到碰到高位小的元素 array[low] = array[high]; while (low < high && array[low] <= pivot) low++;//跟低位比较大小,直到碰到低位大的元素 array[high] = array[low]; } array[low] = pivot; return low;//返回枢轴的位置 }
首先定下一个枢轴,然后以其为标杆,将比该枢轴元素大的元素放置其右侧,而比它小的元素放置于其左侧。之后再分别对这两部分元素进行同样的操作。
3. 插入排序
主要思想:假定已存在一个元素,然后将剩余元素依次与其比较大小,比该元素大的放在其后面,若比该元素小,则继续往前比较,直到找到一个合适的位置插入。主要的算法有直接插入算法和希尔排序算法。直接插入算法
该算法的平均时间复杂度是O(n^2),空间复杂度为O(1),属于稳定排序。以下为算法的实现代码:
public static void InsertSort(int[] array, int n) { int k, j; for (int i = 1; i < n; i++) { if (array[i] < array[i - 1]) { k = array[i]; for (j = i - 1; j >= 0 && array[j] > k; j--) array[j + 1] = array[j]; array[j + 1] = k; } } }
从序列的第二个元素开始判断,分别与其前一元素进行比较,来确定要插入的位置。
希尔排序算法
该算法的平均时间复杂度是O(d),空间复杂度为O(1),属于不稳定排序。以下为算法的实现代码:
public static void ShellSort(int[] array, int n) { int dk;// 增量 int k, j; for (dk = n / 2; dk >= 1; dk = dk / 2) { for (int i = dk; i < n; i++) { if (array[i] < array[i - dk]) { k = array[i]; for (j = i - dk; j >= 0 && array[j] > k; j -= dk) array[j + dk] = array[j]; array[j + dk] = k; } } } }
希尔排序算法实际上是直接插入的改进版,加入了增量。
4. 归并排序
主要思想: 首先将序列中每个元素看成一个有序序列,然后不断归并相邻两个有序序列组成一个新的有序序列,直到将原始的整个序列变成有序序列,这种算法称为二路归并排序。该算法的平均时间复杂度为O(nlogn),空间复杂度为O(n),属于稳定排序。其算法的代码实现如下:public static void MergeSort(int[] array, int n) { MSort(array, 0, n - 1); } // 递归调用,进行分割和合并 public static void MSort(int[] array, int low, int high) { if (low < high) { int mid = (low + high) / 2; MSort(array, low, mid); MSort(array, mid + 1, high); Merge(array, low, mid, high); } } public static void Merge(int[] array, int low, int mid, int high) { int[] B = new int[high - low + 1];// 辅助数组B int k = 0; int i = low, j = mid + 1; while (i <= mid && j <= high) { if (array[i] < array[j]) B[k++] = array[i++]; else B[k++] = array[j++]; } while (i <= mid)//防止两个有序序列的元素个数不相等 B[k++] = array[i++]; while (j <= high) B[k++] = array[j++]; // 将B中元素放回A中 for (int v = 0; v < k; v++) array[low + v] = B[v]; }
5. 各种排序算法的比较
相关文章推荐
- 数据结构中几种排序算法的Java实现
- 数据结构常见的八大排序算法(详细整理)
- Python全栈开发之5、几种常见的排序算法以及collections模块提供的数据结构
- 数据结构中的几种排序算法
- Informix数据表结构分析资料整理之约束查询代码
- Informix数据表结构分析资料整理之约束查询代码
- SQL——表结构、表数据的复制,有风整理
- [翻译]C#数据结构与算法 – 第三章基本排序算法
- 数据结构基础--排序: 各种排序算法全分析
- 数据结构算法面试题精选及整理-随机数rand7生成rand10函数
- Informix数据表结构分析资料整理之约束查询代码
- 数据结构(C#)_排序算法(冒泡排序)
- 数据结构中一些排序算法演示
- 由排序算法引出的数据结构
- 由排序算法引出的数据结构
- Informix数据表结构分析资料整理之字段类型说明和查询SQL语句
- 整理最近新学到的几种sql写法(一)动态“循环”更新表内数据
- 数据结构(C#)_排序算法(冒泡排序)
- 线性链表 各种操作整理 数据结构
- Informix数据表结构分析资料整理之字段类型说明和查询SQL语句