排序算法总结
来源:互联网 发布:淘宝店铺导航css模板 编辑:程序博客网 时间:2024/04/30 06:43
最近在刷leetcode,被虐n次之后决定先搞一下基础建设,把排序整理一下。差不多两天的时间(主要是快速排序把我搞到头大),终于出了一篇比较简陋的笔记。暂且看着,留着后面用。
***华丽的分割线,下面是笔记***
各类排序算法总结
交换排序,选择排序,插入排序,合并排序
基本排序(直接对内存中的 数据进行排序)
交换排序
选择排序
插入排序
合并排序
冒泡排序
快速排序
选择排序
堆排序
插入排序
Shell排序
若对于一些大的 文件,采用 多路归并排序。将文件分为几个能读入内存的小部分,然后分别读入进行排序。
*** 分隔线***
冒泡排序:
比较简单,原理这里不写了就。复杂度:average和worst都是O(n2)。
选择排序:
进行n-1次循环,每次循环都找出剩余数组里最小的一个,然后跟当前元素互换。
复杂度:average和worst都是O(n2)。
代码:
public void selectSort(int[] arr){for(int i=0;i<arr.length;i++){int k = i;for(int j=i+1;i<arr.length;j++){if(arr[j]<arr[k]) k=j;}if(k!=i){int temp = arr[k];arr[k] = arr[i];arr[i] = temp;}}}
插入排序:
思想流程:
1)先把前两个数据排好序。
2)将第三个数据插入到前面排好序的数组里。
3)以此类推。
思想很简单,就是把后面紧挨的数往前扫,如果被扫的数比这个数大,就存到后面去,直到发现一个比这个数小的就停止。
说的不清楚。。。上代码:
public static void insertSort(int[] a){int len = a.length;for(int i=1;i<len;i++){int temp = a[i];int j=i-1;for(;j>=0;j--){if(a[j]>=temp){a[j+1] = a[j];}else{break;}}a[j+1] = temp;}}
Shell排序:虽然不知道为什么叫Shell排序。。。
根据Shell排序的思想,自己写的代码跟书上的不太一样。
排序流程如下:
1) 将n个元素的数组分成n/2个数字序列,比如8个数字除以2是4个数字序列,然后第一个数据和第n/2+1个数据为一对。。。
2)依次循环是每一个序列对排好顺序。
3)然后再变为n/4个序列,再次排序。这里我没太懂,我的代码理解是以n/4为间隔划分整个数组,然后依次比较每一对组合的大小,小的放前面,大的 放后面。书中用的是插入排序,好混乱不懂==
4)不断重复上述过程,直到序列减少为最后一个。我的理解是序列间隔最后变为1,这样每相邻两个数字都是有序的 ,所以整个数组就是有序的了。
上代码:注释部分是书上的代码。
public static void shellSort(int[] arr){int len = arr.length;//for(int r = len/2;r>=1;r/=2)//{//for(int i=r;i<len;i++)//{//int temp = arr[i];//int j=i-r; //mark the other element of a pair//while(j>=0 && temp<arr[j])//{//arr[j+r] = arr[j];//j-=r;//}//arr[j+r]=temp;//}//}for(int r = len/2;r>=1;r/=2){for(int i=0;i<len-r;i++){if(arr[i]>arr[i+r]){int temp = arr[i];arr[i] = arr[i+r];arr[i+r] = temp;}}}}
QuickSort快速排序:
思路:找一个基准元素,随便哪个都可以,然后把比它小的数字都排到左边,比它大的数字都排到右边。然后递归。快速排序可以被形容为:挖坑填数+分治法。
先上代码:
public static void quickSort(int[] arr, int left, int right){if(left < right){int i = left;int j = right;int base = arr[left];while(i<j){while(arr[j]>=base && i<j)j--;if(i<j){arr[i++] = arr[j];}while(arr[i]<base && i<j)i++;if(i<j){arr[j--] = arr[i];}}arr[i] = base;quickSort(arr,left,i-1);quickSort(arr,i+1,right);}}
While是为了挖坑填数,填好一层后用递归分治。
几点注意:在内层有个if判断,它的用途是为了防止如果j从后往前找没找到比arr[i]小 的数,这个时候就不用填数然后移动i了,否则在大while结束后给arr[i]赋值时会赋错位置。
归并排序:
思路:把数组分成两个部分排序,排好之后再把两个部分合起来。如果被分的 两个部分还可以继续分,则分至最小后排序,然后合并。
上代码:
public static void mergeSort(int[] arr,int first, int last){if(first>=last)return;int mid = (first+last)/2;mergeSort(arr,first,mid);mergeSort(arr,mid+1,last);mergeArray(arr,first,mid,last);}public static void mergeArray(int[] arr, int first, int mid, int last){int i = first;int j = mid+1;int[] temp = new int[last-first+1];int k = 0;while(i<=mid && j<=last){temp[k++] = arr[i]<arr[j]? arr[i++]:arr[j++];}while(i<=mid){temp[k++] = arr[i++];}while(j<=last){temp[k++] = arr[j++];}for(int m=0;m<temp.length;m++)arr[first+m] = temp[m];}
mergeArray负责把排好序的两个部分合并成一个部分,然后返回到上一级mergeSort继续合并。
关键点:在整个数组中,分组是靠下标实现的。
总结
归并排序的空间复杂度为O(n),其余都大部分都是O(1)。
时间复杂度总结:
Average
Worst
Bubble Sort
N2
N2
Select Sort
N2
N2
Insert Sort
N2
N2
Quick Sort
nlogn
N2
Shell Sort
N3/2
N2
Merge Sort
nlogn
Nlogn
由此可以看出,mergesort是效率较高的,尤其是当排序的数量较多时,但需要额外的系统资源。
***华丽的分割线结束***码字不易,大神勿喷,欢迎指正。
- 算法--排序算法总结
- 算法:排序算法总结
- 算法:排序算法总结
- 算法-排序算法总结
- 算法-排序算法总结
- 【排序算法】排序算法总结
- 排序算法总结---希尔排序
- 排序算法总结---冒泡排序
- 排序算法总结----快速排序
- 排序算法总结---希尔排序
- 排序算法总结【内排序】
- 排序算法之内排序总结
- 排序算法总结:冒泡排序
- 【排序算法总结】冒泡排序
- 【排序算法总结】选择排序
- 排序算法总结
- 排序算法大总结
- 排序算法总结
- GDAL Qt 开发
- VC获取IP、子网掩码、网关、广播地址
- 深入 HBase 架构解析(2)
- C++STL 常用 函数 用法
- SAP HANA 基础架构简介(二)
- 排序算法总结
- Unity - Camera
- 前端性能提升方法
- IntentFilter详解
- [转] A Brief Overview Of Vulkan API
- 判断一个数是否是回文数
- 优秀程序设计的原则
- Nginx 的 TCP 负载均衡介绍
- eclipse配置文件eclipse.ini参数解释