归并排序
实现思想:
归并的含义很明显就是将两个或者两个以上的有序表组合成一个新的有序表。
归并排序中一般所用到的是2-路归并排序,即将含有n个元素的序列看成是n个有序的子序列,
每个子序列的长度为1,而后两两合并,得到n/2个长度为2或1的有序子序列,再进行两两合并。。。
直到最后由两个有序的子序列合并成为一个长度为n的有序序列。
2-路归并的核心操作是将一维数组中前后相邻的两个有序序列归并为一个有序序列。
2-路归并的代码:
/*
蒋有绪的arr[start...mid]和有序的arr[mid+1...end]
合并为有序的arr[start...end]
*/
void merge(int *arr,int start,int mid,int end)
{
int i=start;
int j=mid+1;
int k=0;
//brr为辅助数组
int *brr=(int *)malloc((end-start+1)*sizeof(int));
//比较两个有序序列中的元素,将较小的元素插入到brr
while(i<=mid&&j<=end)
{
if(arr[i]<=arr[j])
brr[k++]=arr[i++];
else
brr[k++]=arr[j++];
}
//将arr 序列中剩余的元素复制到brr
while(i<=mid)
brr[k+]=arr[i++];
while(j<=end)
brr[k++]=arr[j++];
//将brr 复制到arr,使arr[start..end]有序
for(i=0;i<k;i++)
arr[i+start]=brr[i];
//释放brr所占空间
free(brr);
brr=0;
}
/*
对arr[start...end]内的元素进行归并排序
归并排序后的顺序为从小到大
*/
void sort(int *arr,int start,int end)
{
if(start<end)
{
int mid=(start+end)/2;
sort(arr,start,mid);
sort(arr,mid+1,end);
merge(arr,start,mid,end);
}
}
void merge_sort(int *arr,int len)
{
sort(arr,0,len-1);
}
为了避免递归使用malloc和free,用这种经典的实现方式
void merge(int *arr,int *brr,int start,int mid,int end)
{
int i=start;
int j=mid+1;
int k=0;
//比较两个有序序列中的元素,将较小的元素插入到brr中
while(i<=mid&&j<=end)
{
if(arr[i]<=arr[j])
brr[k++]=arr[i++];
else
brr[k++]=arr[j++];
}
while(i<=mid)
brr[k++]=arr[i++];
while(j<=end)
brr[k++]=arr[j++];
for(i=0;i<k;i++)
arr[i+start]=brr[i];
}
void sort(int *arr,int *brr,int start,int end)
{
if(start<end)
{
int mid=(start+end)/2;
sort(arr,brr,start,mid);
sort(arr,brr,mid+1,end);
merge(arr,brr,start,mid,end);
}
}
void merge_sort(int *arr,int len)
{
int *brr=(int *)malloc(len*sizeof(int));
sort(arr,brr,0,len-1);
free(brr);
brr=0;
}
归并排序的最好最坏和平均时间复杂度都是O(n*logn),但是需要额外的长度为n的辅助数组
快速排序:
实现思想
快速排序的基本思想如下:
1、从待排序列中任选一个元素作为枢轴;
2、将序列中比枢轴大的元素全部放在枢轴的右边,比枢轴小的元素全部放在其左边;
3、以枢轴为分界线,对其两边的两个子序列重复执行步骤1和2中的操作,直到最后每个子序列中只有一个元素。
void quick_sort(int *arr,int low,int high)
{
int pos;
if(low<high)
{
pos=findPos(arr,low,high);
quick_sort(arr,low,pos-1);
quick_sort(arr,pos+1,high);
}
}
/*
该函数返回分割点数值所在的位置,a为待排序数组的首地址,
low刚开始表示排序范围内的第一个元素的位置,逐渐向右移动,
high刚开始表示排序范围内的最后一个位置,逐渐向左移动
*/
int findPos(int *arr,int low,int high)
{
int val=arr[low];
while(low<high)
{
while(low<high&&arr[high]>=val)
high--;
arr[low]=arr[high];
while(low<high&&arr[low]<=val)
low++;
arr[high]=arr[low];
//最终low=high
arr[low]=val;
return low;
}
}
通常,快速排序被认为在所有同数量级(平均时间复杂度均为O(n*logn))的排序方法中,平均性能最好
所以通常枢轴元素的选择一般基于“三者取中”的原则,即比较首元素、末元素、中间元素的值,取三者中中间大小的那个。
分享到:
相关推荐
归并算法和快速排序算法,归并中考虑了归并的分解,不要归并的1,当小于分界是用简单排序实现
快速排序、归并排序、基数排序等排序算法比较,比较时间性能,采用C++语言实现。。。
算法设计实验报告,包括:快速排序和归并排序两种算法各自的基本思想、时间复杂度分析,C++实现代码,两种算法运行时间的比较,运行截图,实验心得。
快速排序算法c++实现,快速实现插入排序十万个数(调用)。可以改成输入。并附加了程序运行计时,用于测试时间复杂度,可以移除。绝对能用
自己写的三个排序算法的比较。快速排序、归并排序、简单排序 对三个排序算法所消耗时间进行统计,比较时间效率 程序是在Linux下用C写的,vc下并未做测试。
JAVA排序大全 冒泡 快速 选择 归并排序
直接插入排序 选择排序 堆排序 归并排序 快速排序 冒泡排序等七种排序方法
直接插入排序 冒泡排序 快速排序 直接选择排序 堆排序 二路归并排序 C#源代码 使用C#实现的数据结构中的排序算法
归并排序,排序等算法,数据结构,快速排序,链表排序归并排序,排序等算法,数据结构,快速排序,链表排序
选择排序、插入排序、冒泡排序以及快速排序和归并排序的C语言实现,绝对可用
快速排序、归并排序、堆排序 并比较排序时间 数据结构与算法
插入排序、选择排序、希尔排序、堆排序、冒泡、双向冒泡、快速排序、归并排序、递归的归并排序、基数排序
计算机算法课程的作业,用c++实现了归并排序和快速排序,并比较了两种算法的速度。测试数据为随机生成,可设置为10万、100万、1000万大小的数组。在代码中提供了详细的注释,在容易出错的地方进行了解释。下面是得到...
插入排序、冒泡排序、归并排序、快速排序四种排序方式的C++实现,各写成了一个函数,主函数中可以选择调用那一个。初始化数组时用的是随机种子srand((int)time(0))。在宏中定义数组大小。
冒泡排序,选择排序,插入排序,希尔排序,堆排序,归并排序,快速排序源码实现,里面有详细讲解,对新手应该有帮助
自己编写的基于java的快速排序和归并算法
编程实现 快速排序,堆排序,归并排序,插入排序,选择排序; 对于不同的数组大小,比较这些算法的复杂度; 数组的测试,分为已排序数组和随机数组。
随机产生1000个0~9的数,并分别用堆排序,快速排序,归并排序将产生的这1000个随机数排序,并将排序结果写入文件
用C实现快速排序,归并排序,冒泡排序,希尔等常见排序,代码编译后可使用
7大排序算法(快速排序,冒泡排序,选择排序,归并排序,插入排序,希尔排序,堆排序)实现源码