东莞企业网站建设价格,网站优化公司的seo做的好,专业做电子的外贸网站建设,做网站 被谷歌收录文章目录 1. 排序的概念及引用1.1 排序的概念1.2 常见的排序算法 2. 常见排序算法的实现2.1 插入排序2.1.1基本思想#xff1a;2.1.2 直接插入排序2.1.3 希尔排序( 缩小增量排序 ) 2.2 选择排序2.2.1基本思想#xff1a;2.2.2 直接选择排序:2.2.3 堆排序 2.3 交换排序2.3.1冒… 文章目录 1. 排序的概念及引用1.1 排序的概念1.2 常见的排序算法 2. 常见排序算法的实现2.1 插入排序2.1.1基本思想2.1.2 直接插入排序2.1.3 希尔排序( 缩小增量排序 ) 2.2 选择排序2.2.1基本思想2.2.2 直接选择排序:2.2.3 堆排序 2.3 交换排序2.3.1冒泡排序2.3.2 快速排序 2.4 归并排序2.4.1 基本思想2.4.2 海量数据的排序问题 3. 排序算法复杂度及稳定性分析 1. 排序的概念及引用
1.1 排序的概念
排序所谓排序就是使一串记录按照其中的某个或某些关键字的大小递增或递减的排列起来的操作。 稳定性假定在待排序的记录序列中存在多个具有相同的关键字的记录若经过排序这些记录的相对次序保持 不变即在原序列中r[i]r[j]且r[i]在r[j]之前而在排序后的序列中r[i]仍在r[j]之前则称这种排序算法是稳定的否则称为不稳定的。 内部排序数据元素全部放在内存中的排序。 外部排序数据元素太多不能同时放在内存中根据排序过程的要求不能在内外存之间移动数据的排序。
1.2 常见的排序算法 2. 常见排序算法的实现
2.1 插入排序
2.1.1基本思想
直接插入排序是一种简单的插入排序法其基本思想是 把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中直到所有的记录插入完为止得到一个新的有序序列 。实际中我们玩扑克牌时就用了插入排序的思想。
2.1.2 直接插入排序
当插入第i(i1)个元素时前面的array[0],array[1],…,array[i-1]已经排好序此时用array[i]的排序码与array[i-1],array[i-2],…的排序码顺序进行比较找到插入位置即将array[i]插入原来位置上的元素顺序后移
代码实现
public static void insertSort(int[] array){for (int i 1; i array.length; i) {int tmp array[i];int j i-1;for (; j 0; j--) {if(array[j] tmp){array[j1] array[j];}else{break;}}array[j1] tmp;}}直接插入排序的特性总结 元素集合越接近有序直接插入排序算法的时间效率越高时间复杂度O(N^2)空间复杂度O(1)它是一种稳定的排序算法稳定性稳定 2.1.3 希尔排序( 缩小增量排序 )
希尔排序法又称缩小增量法。希尔排序法的基本思想是先选定一个整数把待排序文件中所有记录分成多个组所有距离为的记录分在同一组内并对每一组内的记录进行排序。然后取重复上述分组和排序的工作。当到达1时所有记录在统一组内排好序。 代码实现 public static void hillSort(int[] array){int gap array.length;while(gap 1){gap/2;hill(array,gap);}}public static void hill(int[] array,int gap){for (int i gap; i array.length; i) {int tmp array[i];int j i - gap;for (; j 0 ; j-gap) {if(array[j] tmp){array[jgap] array[j];}else {break;}}array[jgap] tmp;}}希尔排序的特性总结 希尔排序是对直接插入排序的优化。当gap 1时都是预排序目的是让数组更接近于有序。当gap 1时数组已经接近有序的了这样就会很快。这样整体而言可以达到优化的效果。我们实现后可以进行性能测试的对比。希尔排序的时间复杂度不好计算因为gap的取值方法很多导致很难去计算因此在好些树中给出的希尔排序的时间复杂度都不固定稳定性不稳定 2.2 选择排序
2.2.1基本思想
每一次从待排序的数据元素中选出最小或最大的一个元素存放在序列的起始位置直到全部待排序的数据元 素排完 。
2.2.2 直接选择排序:
在元素集合array[i]–array[n-1]中选择关键码最大(小)的数据元素 若它不是这组元素中的最后一个(第一个)元素则将它与这组元素中的最后一个第一个元素交换 在剩余的array[i]–array[n-2]array[i1]–array[n-1]集合中重复上述步骤直到集合剩余1个元素
代码实现 代码一
public static void selectSort(int[] array){for (int i 0; i array.length; i) {int min i;for (int j i1; j array.length; j) {if(array[j] array[min]){min j;}}swap(array,min,i);}}public static void swap(int[] array,int i,int j){int tmp array[i];array[i] array[j];array[j] tmp;}代码二
public static void selectSort1(int[] array){int left 0;int right array.length-1;while(left right){int max left;int min left;for (int j left1; j right; j) {if(array[j] array[min]){min j;}if(array[j] array[max]){max j;}}swap(array,min,left);if(left max){max min;}swap(array,max,right);left;right--;}}public static void swap(int[] array,int i,int j){int tmp array[i];array[i] array[j];array[j] tmp;}【直接选择排序的特性总结】 直接选择排序思考非常好理解但是效率不是很好。实际中很少使用时间复杂度O(N^2)空间复杂度O(1)稳定性不稳定 2.2.3 堆排序
堆排序(Heapsort)是指利用堆积树堆这种数据结构所设计的一种排序算法它是选择排序的一种。它是通过堆来进行选择数据。需要注意的是排升序要建大堆排降序建小堆。 代码实现
public static void heapSort(int[] array){int end array.length-1;createHeap(array);while(end 0){swap(array,0,end);siftDown(array,0,end);end--;}}
public static void createHeap(int[] array){for (int i (array.length-1-1)/2; i 0; i--) {siftDown(array,i,array.length);}}private static void siftDown(int[] array, int parent, int length) {int child parent*2 1;while(child length){if(child1 length array[child] array[child1]){child;}if(array[child] array[parent]){swap(array,child,parent);parent child;child child*2 1;}else{break;}}}
【堆排序的特性总结】 堆排序使用堆来选数效率就高了很多。时间复杂度O(N*logN)空间复杂度O(1)稳定性不稳定 2.3 交换排序
基本思想所谓交换就是根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置交换排序的特 点是将键值较大的记录向序列的尾部移动键值较小的记录向序列的前部移动。
2.3.1冒泡排序
代码实现
public static void bubbleSort(int[] array){for (int i 0; i array.length-1; i) {boolean flg false;for (int j 0; j array.length-1-i; j) {if(array[j] array[j1]){swap(array,j,j1);flg true;}}if(!flg){break;}}}【冒泡排序的特性总结】 冒泡排序是一种非常容易理解的排序时间复杂度O(N^2)空间复杂度O(1)稳定性稳定 2.3.2 快速排序
快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法其基本思想为任取待排序元素序列中的某元素作为基准值按照该排序码将待排序集合分割成两子序列左子序列中所有元素均小于基准值右子序列中所有元素均大于基准值然后最左右子序列重复该过程直到所有元素都排列在相应位置上为止。
代码实现
public static void quickSort(int[] array){quick(array,0,array.length-1);}public static void quick(int[] array,int start,int end){if(start end){return;}int mid midIndex(array,start,end);swap(array,mid,start);int quickIndex quickationHole(array,start,end);quick(array,start,quickIndex-1);quick(array,quickIndex1,end);}public static int quickation(int[] array,int left ,int right){int tmp left;while(left right){while(left right array[right] array[tmp]){right--;}while(left right array[left] array[tmp]){left;}swap(array,left, right);}swap(array,left,tmp);return left;}public static int quickationHole(int[] array,int left,int right){int tmp array[left];while(left right){while(left right array[right] tmp){right--;}array[left] array[right];while(left right array[left] tmp){left;}array[right] array[left];}array[left] tmp;return right;}public static int midIndex(int[] array,int start,int end){int mid (start end)2;if(array[start] array[end]){if(array[mid] array[start]){return start;}else if (array[end] array[mid]){return end;}else {return mid;}}else{if(array[mid] array[start]){return end;}else if (array[end] array[mid]){return start;}else {return mid;}}}非递归实现
public static void quickSortNor(int[] array){int start 0;int end array.length-1;StackInteger stack new Stack();int quickIndex quickationHole(array,start,end);if(start1 quickIndex){stack.push(start);stack.push(quickIndex-1);}if(quickIndex1 end){stack.push(quickIndex1);stack.push(end);}while(!stack.empty()){end stack.pop();start stack.pop();quickIndex quickationHole(array,start,end);if(start1 quickIndex){stack.push(start);stack.push(quickIndex-1);}if(quickIndex1 end){stack.push(quickIndex1);stack.push(end);}}}public static int quickationHole(int[] array,int left,int right){int tmp array[left];while(left right){while(left right array[right] tmp){right--;}array[left] array[right];while(left right array[left] tmp){left;}array[right] array[left];}array[left] tmp;return right;}【快速排序总结】 快速排序整体的综合性能和使用场景都是比较好的所以才敢叫快速排序 时间复杂度O(N*logN) 空间复杂度O(logN) 稳定性不稳定
2.4 归并排序
2.4.1 基本思想
归并排序MERGE-SORT是建立在归并操作上的一种有效的排序算法,该算法是采用分治法Divide andConquer的一个非常典型的应用。将已有序的子序列合并得到完全有序的序列即先使每个子序列有序再使子序列段间有序。若将两个有序表合并成一个有序表称为二路归并。 归并排序核心步骤 代码实现
public static void mergeSort(int[] array){mergeSortFun(array,0,array.length-1);}private static void mergeSortFun(int[] array, int left, int right) {if(left right){return;}int mid (left right)/2;mergeSortFun(array,left,mid);mergeSortFun(array,mid1,right);merge(array,left,mid,right);}private static void merge(int[] array,int left,int mid,int right){int s1 left;int e1 mid;int s2 mid1;int e2 right;int[] tmparr new int[right-left1];int k 0;while(s1 e1 s2 e2){if(array[s1] array[s2]){tmparr[k] array[s1];}else{tmparr[k] array[s2];}}while(s1 e1){tmparr[k] array[s1];}while (s2 e2){tmparr[k] array[s2];}for (int i 0; i tmparr.length; i) {array[lefti] tmparr[i];}}非递归先实现
public static void mergeSortNor(int[] array){int gap 1;while(gap array.length){for(int i 0;i array.length;i igap*2){int left i;int mid left gap -1;int right mid gap;if(mid array.length){mid array.length-1;}if (right array.length) {right array.length-1;}merge(array,left,mid,right);}gap*2;}}private static void merge(int[] array,int left,int mid,int right){int s1 left;int e1 mid;int s2 mid1;int e2 right;int[] tmparr new int[right-left1];int k 0;while(s1 e1 s2 e2){if(array[s1] array[s2]){tmparr[k] array[s1];}else{tmparr[k] array[s2];}}while(s1 e1){tmparr[k] array[s1];}while (s2 e2){tmparr[k] array[s2];}for (int i 0; i tmparr.length; i) {array[lefti] tmparr[i];}}【归并排序总结】 归并的缺点在于需要O(N)的空间复杂度归并排序的思考更多的是解决在磁盘中的外排序问题。时间复杂度O(N*logN)空间复杂度O(N)稳定性稳定 2.4.2 海量数据的排序问题
外部排序排序过程需要在磁盘等外部存储进行的排序 前提内存只有 1G需要排序的数据有 100G 因为内存中因为无法把所有数据全部放下所以需要外部排序而归并排序是最常用的外部排序
先把文件切分成 200 份每个 512 M分别对 512 M 排序因为内存已经可以放的下所以任意排序方式都可以进行 2路归并同时对 200 份有序文件做归并过程最终结果就有序了
3. 排序算法复杂度及稳定性分析