排序之插入、归并、快速排序
来源:互联网 发布:ubuntu登录界面循环 编辑:程序博客网 时间:2024/06/05 20:54
一、插入排序
最简单的排序方法,类似玩扑克,开始时我们的左手为空,之后我们每次从桌子上拿走一张牌并插入左手中的正确位置。
我们可以将牌分为三部分,左手中的已排序好的牌,右手中的一张牌,桌子上的一堆牌。而为了找到一张牌的正确位置,我们从右到左将它与已在手中的每张牌进行比较,保证左手中的牌总是排序好的。
public void insertionSort(int a[]){ for(int i=1;i<a.length;i++){ int key=a[i]; int j=i-1; while(j>=0&&a[j]>key){ a[j+1]=a[j]; j--; } a[j+1]=key; }}
算法很简单,但是算法时间复杂度为O(n²),除非数组已经完全排序好,这时的时间复杂度为O(n)。
二、归并排序
同样假定有两堆牌面朝上的牌,每堆都已排序,最小的牌在顶上,我们希望把这两堆牌合并成一堆排序好的牌。我们只要不断的从两堆牌的顶上选取较小的那一张,直到一堆为空就好。
就如a[p..q]和a[q+1…r]各自都按照升序排列,我们需要重新安排数组a中的位置使a[p,r]按照升序排列,可以采用同样的办法。
public void merge(int a[],int p,int q,int r){ int[] temp=new int[r-p+1]; int i=p; int j=q+1; int k=0; while(i<=q&&j<=r){ if(a[i]<a[j]){ temp[k]=a[i]; i++; }else{ temp[k]=a[j]; j++; } k++; } if(i>q){ while(j<=r){ temp[k++]=a[j++]; } }else{ while(i<=q){ temp[k++]=a[i++]; } } int x=p; for(int l=0;l<r-p+1;l++){ a[x++]=temp[l]; }}
接下来我们采用自顶向下的方法就好:
public void mergeSort(int a[],int p,int r){ if(p<r){ int mid=(p+r)/2; mergeSort(a, p, mid); mergeSort(a, mid+1, r); merge(a, p, mid, r); }}
归并排序的时间复杂度为O(nlgn),明显优于插入排序。
三、快速排序
将数组a[p..r]分为两部分,左半部分a[p..q-1]都小于等于a[q],右半部分a[q+1…r]都大于a[q]。
方法就是通过将数组a[p..r-1]的所有元素都与a[r]进行比较,只要比a[r]小的都扔到左边,找到一个扔一个。
public int partition(int a[],int p,int r){ int i=p-1; int j=p; while(j<r){ if(a[j]<a[r]){ i++; int temp=a[j]; a[j]=a[i]; a[i]=temp; } j++; } int temp=a[i+1]; a[i+1]=a[r]; a[r]=temp; return i+1; }
然后我们通过递归调用快速排序,对a[p,q-1],a[q+1,r]进行排序:
public void quickSort(int a[],int p,int r){ if(p<r){ int q=partition(a,p,r); quickSort(a,p,q-1); quickSort(a,q+1,r); }}
快速排序的时间复杂度同样为O(nlgn),但是存在最坏情况,就是在已排序好的数组时,划分时左右两部分会分别包括0个元素和n-1个元素,这种情况下,时间复杂度为O(n²)。
阅读全文
0 0
- 排序之插入、归并、快速排序
- 排序算法之插入排序、归并排序、快速排序
- 插入、归并、快速排序
- Scala插入排序、归并排序、快速排序
- 快速排序、插入排序、归并排序
- 练习《算法导论》之排序:插入排序,归并排序,堆排序,快速排序
- 排序之归并、快速排序
- 插入排序、希尔排序、堆排序、归并排序、快速排序
- 排序(插入排序,希尔排序,归并排序,快速排序)
- 排序:插入,希尔,堆,快速,归并排序
- 插入排序,快速排序,堆排序,归并排序
- 直接插入排序、归并排序、推排序、快速排序
- 链表之排序(插入、选择、归并、快速、冒泡)
- 数据操作之《排序套餐:冒泡、选择、插入、快速、归并》
- 数据操作之《排序套餐:冒泡、选择、插入、快速、归并》
- 排序之归并排序和快速排序
- 排序之选择排序、堆排序、归并排序、快速排序
- 比较排序之插入和归并排序
- 匿名方法的一些使用方法备忘
- Git - 如何修改开源项目并推送给作者 / 克隆远程仓库到本地
- 关于JAVA中substring()和indexOf()的用法
- 《Spring揭秘》笔记——prototype作用域的“坑”
- 典型关联分析(Canonical Correlation Analysis)
- 排序之插入、归并、快速排序
- CSS样式覆盖规则
- 【异常】cvc-elt.1: 找不到元素 'beans'报错(ehcache-spring)
- instead of 触发器
- Android之Adapter解析
- 基于高德地图API实现车辆轨迹回放并显示实时坐标
- html2word html转换为word 使用docx4j
- ip的基本知识及dhcp服务器的配置
- Kotlin语法(二)