归并、快排算法的学习

来源:互联网 发布:淘宝店铺好听的名字 编辑:程序博客网 时间:2024/05/11 15:05


        任何基于相邻两个元素之间比较的交换算法,其平均时间复杂度为O(n2)。主要涉及到的是插入、选择和冒泡排序三种。因此为了降低时间复杂度,不再限制比较在仅仅2个相邻的元素间。主要指归并算法、快速排序算法和shell排序。

1.  归并排序:将一个序列分为两个长度相等的子序列,对每一个子序列进行排序,再将它们合并成一个序列。合并的过程称为归并。

void mergeSort(int a[], int l, int r){int m = 0;if(l >= r)return;m = (l+r)/2;mergeSort(a, l, m);//对左边的子序列执行归并算法mergeSort(a, m+1, r);//对右边的子序列执行归并算法merge(a, l, m, r);//将由上两步生成的有序子列通过插入排序合并为一个return;}


 

void merge(int a[], int le, int m, int r){int b[SIZE];int i=le, j=m+1;int index = le;while(i<=m&&j<=r){b[index++] = a[i]<a[j] ? a[i++] : a[j++];}if(i<=m)//左边的子序列后部分未加入到b数组中{while(i<=m)b[index++] = a[i++];}else//右边的子序列剩余部分加入到b数组中{while(j<=r)b[index++] = a[j++];}for(i=le;i<=r;i++){a[i]=b[i];}}

时间复杂度分析:

所以T(n)=O(nlogn)

 

2.  快速排序:每次排序选择一个轴值,小于轴值的都放在其左边,大于轴值的都放在轴值右边。

void quickSort(int a[], int l, int r){if(l<r){int p=partition(a,l,r);//p是所选轴值的下标quickSort(a,l,p-1);quickSort(a,p+1,r);}}

 

int partition(int a[],int l,int r){int i=l;int j=r+1;int x=a[l];while(1){while(a[++i]<x);while(a[--j]>x);if(i>=j)break;swap(a,i,j);}a[l] = a[j];a[j] = x;return j;}

该算法元素比较的次数,在最坏情况下是O(n2)。

因为Partition(a,l,r)的每次调用中,元素的比较次数最多为r-l. 把快排过程按照划分来分层,则第一次只调用partition 1次,涉及n个元素;第二次调用partition 2次,涉及n-1个元素……所以在最坏情况下总的比较次数不超过n(n-1)/2。因此quickSort算法最坏情况下的时间复杂度为O(n2)。

平均时间复杂度为O(nlogn).

原创粉丝点击