数据结构中几种排序算法的整理
来源:互联网 发布:python help 函数 编辑:程序博客网 时间:2024/06/07 00:34
几种排序算法的整理
- 选择排序
- 交换排序
- 插入排序
- 归并排序
各种排序算法的比较
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[n]);} /** 向下调整堆的算法 * 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); }// 递归形式 划分后 分别排序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. 各种排序算法的比较
- 数据结构中几种排序算法的整理
- 数据结构排序算法及代码整理
- 数据结构之排序算法整理(1)
- 数据结构之排序算法整理(2)
- 数据结构之排序算法整理(3)
- 数据结构之排序算法整理(4)
- 数据结构之排序算法整理(5)
- 数据结构中几种排序算法的Java实现
- 排序算法的比较整理
- 整理的排序算法总结
- 排序算法的代码整理
- 常用的排序算法整理
- 整理的常见排序算法
- 数据结构-常见的排序算法
- 数据结构的八大排序算法
- 【数据结构】数据结构中常用的排序算法
- 数据结构与算法整理之排序(一)
- 【数据结构算法】——内部排序整理总结
- Https和Http的区别
- 归并排序法
- TIME_WAIT状态的连接过多是什么原因?
- MD5算法原理与实现
- 查看oracle的归档日志及空间占用率,清除归档日志
- 数据结构中几种排序算法的整理
- 如何分辨IP地址的类型
- Binary Tree Level Order Traversal II
- 课程设计:小学生考试系统
- RAM ROM and Flash
- Protobuf使用手册
- js文章网站集锦
- 子集和问题
- 菜单对号标记