再读算法导论关于归并排序
来源:互联网 发布:sql怎么统计班级人数 编辑:程序博客网 时间:2024/05/22 06:33
回顾算法导论的第一个讲解的算法就是归并排序,我们把归并排序分解为两个步骤,第一步考虑如何进行归并,第二步把问题分解为多次归并排序和归并,这是一个典型的分治思想。
每一层的调用有三个步骤:
分解:将原问题分解成若干子问题
解决:解决这些子问题,递归求解各个子问题。若子问题规模足够小,则直接求解。
合并:将这些子问题的解合并成原问题的解。
要使用分治的前提是问题是线性可以合并的,如果是非线性问题,使用分治时问题将会变得很复杂。
我们将合并的数组理解为扑克牌,先把它分为两堆牌,然后进行合并。当然数值上不会是扑克牌的数值,大家可以设想下手里面有和他要排序数值一样的扑克牌。
归并排序的算法主要集中于归并这一操作,抛开递归,我们单独分析归并这一操作,首先将两个堆底部放入哨兵牌,可以理解为扑克牌中王一样,它是一个还有特殊的值,为了简化这里放入100;结果每当显露出哨兵牌,他不可能为较小的牌,除非两个堆都已经显露出哨兵牌。但这种情况一旦发生,我们的归并操作也就结束了。因为我们事先知道刚好执行r-p+1张牌将被放置到输出堆。
代码如下:
#include <stdio.h>#include <iostream>using namespace std;void Merge(int* A,int p,int q,int r){int n1= q-p+1;int n2= r-q;int *L= new int[n1+1];int *R= new int[n2+1];int i=0;int j=0;for(i=0;i<n1;i++){L[i]=A[p+i-1];}for(j=0;j<n2;j++){R[j]=A[q+j];}L[n1] = 100;//代表数组中不可能出现的无穷大的数R[n2] = 100;//代表数组中不可能出现的无穷大的数i = 0;j = 0;for(int k = p-1;k < r; k++){if(L[i]<=R[j]){A[k] = L[i];i = i+1;}else{A[k] = R[j];j = j+1;}}}void Merge_Sort(int *A,int p,int r){if(p<r){int q=(p+r)/2;Merge_Sort(A,p,q);Merge_Sort(A,q+1,r);Merge(A,p,q,r);}}int A[15] = {11,12,13,14,15,1,2,3,4,5,6,7,8,9,10}; int main(int argc, char **argv){Merge_Sort(A,1,15);for(int i=0;i<15;i++){cout<<A[i]<<"\t";}cout<<endl;system("pause");return 0;}
- 再读算法导论关于归并排序
- 再读算法导论,排序一(归并排序)。
- 【算法导论】归并排序
- [算法导论]归并排序
- 算法导论-----归并排序
- 【算法导论】归并排序
- 算法导论-归并排序
- 算法导论-归并排序
- 算法导论 归并排序
- 算法导论-归并排序
- 《算法导论》--归并排序
- 算法导论--归并排序
- 算法导论一——关于MergeSort(归并排序)总结
- 算法导论P17 归并排序
- 算法导论_归并排序
- 算法导论学习------归并排序
- 算法导论之归并排序
- 【算法导论】归并排序实现
- TRS WCM SQL injection
- Java加密技术——非对称加密算法RSA
- sun cluster
- ZOJ 2136 Longest Ordered Subsequence(LIS)
- 有关Expander组件的研究
- 再读算法导论关于归并排序
- 将Vim改造为强大的IDE—Vim集成Ctags/Taglist/Cscope/Winmanager/NERDTree/OmniCppComplete(有图有真相)
- 利用android源码实现获取汉字的拼音
- Sixth calibration example - Combining two independent calibrations of the same camera
- JS实现商品倒计时
- EWS 基于B/S模式的视窗平台 打造最佳用户体验及最佳性价比
- 禁止文件被蜘蛛程序查看的说明
- 可停靠窗口
- Win8 metro Zip