【算法导论】合并排序法
2013-06-08 15:41
246 查看
分治法:将原问题划分为n个规模较小而结构与原问题相似的子问题;递归地解决这些子问题,然后再合并其结果,就得到了原问题的解。分治法在每一个递归上都有三个步骤:分解、解决、合并。而在本文中的合并排序法正是运用了这种分而治之的策略:把一个n个元素的数组先分成两个数组,然后继续分下去,知道分成n个数组;然后将其逐一合并排序,最终得到排列好了的数组。下面我们首先看一看合并排序了原理框图:(图中黑色部分看不见不要紧,只需了解是将数组L、R中浅颜色的元素从小到大依次填入数组A中)
上述原理的具体代码实现如下:
下面演示了合并排序在对一个数组的处理过程:
上图中的合并排序过程的总的测试程序如下:
注意:我是在vs2008上运行的,与vc 6.0有点区别,主要是循环体中的循环变量的作用域,出错体现在循环变量的重复定义上。例如:在vs2008或vs2010上,程序为:
#include<stdio.h>
void main()
{
int i=0;
for(int i=0;i<5;i++)
printf("%d ",i);
}
则在VC 6.0上需改为:
#include<stdio.h>
void main()
{
int i=0;
for(i=0;i<5;i++)
printf("%d ",i);
}
原文:http://blog.csdn.net/tengweitw/article/details/9056485
作者:nineheadedbird
上述原理的具体代码实现如下:
/*************************************** / 合并排序 /输入:数组arrayA、数组长度、p q r为数组下标 /输出:由小到大的数组 /时间复杂度:n ***************************************/ void Merge(int* arrayA,int p,int q,int r) { int i=0; int j=0; int n1=q-p+1;//计算两个数组的长度 int n2=r-q;//且这两个数组是已排列好的数组 int arrayL[100]={0};//数组大小要大于n1 int arrayR[100]={0};//数组大小要大于n2 for(i=0;i<n1;i++)//对两个数组赋初值 arrayL[i]=arrayA[p+i]; arrayL[i]=10000;//作为哨兵,判断是否到结尾 for(i=0;i<n2;i++) //也可以不用哨兵 arrayR[i]=arrayA[q+i+1]; arrayR[i]=10000; i=0;j=0; for(int k=p;k<=r;k++) { if(arrayL[i]<=arrayR[j]) arrayA[k]=arrayL[i++]; else arrayA[k]=arrayR[j++]; } }
下面演示了合并排序在对一个数组的处理过程:
上图中的合并排序过程的总的测试程序如下:
#include<iostream>
#include<ctime>
using namespace std;
void Merge(int* arrayA,int p,int q,int r);
void MergeSort(int* arrayA,int p,int r);
void main()
{
clock_t start,finish;
double totaltime;
start=clock();
int arrayA[6]={5,2,4,6,1,3};
int Length=sizeof(arrayA)/sizeof(int);
MergeSort(arrayA,0,5);
for(int i=0;i<Length;i++)
cout<<arrayA[i];
cout<<endl;
finish=clock();
totaltime=(double)(finish-start)/CLOCKS_PER_SEC;
cout<<"此两个程序的运行时间为"<<totaltime<<"秒!"<<endl;
//上述由于数组太小,运行时间很短,可以循环
}
/*************************************** / 合并排序 /输入:数组arrayA、数组长度、p q r为数组下标 /输出:由小到大的数组 /时间复杂度:n ***************************************/ void Merge(int* arrayA,int p,int q,int r) { int i=0; int j=0; int n1=q-p+1;//计算两个数组的长度 int n2=r-q;//且这两个数组是已排列好的数组 int arrayL[100]={0};//数组大小要大于n1 int arrayR[100]={0};//数组大小要大于n2 for(i=0;i<n1;i++)//对两个数组赋初值 arrayL[i]=arrayA[p+i]; arrayL[i]=10000;//作为哨兵,判断是否到结尾 for(i=0;i<n2;i++) //也可以不用哨兵 arrayR[i]=arrayA[q+i+1]; arrayR[i]=10000; i=0;j=0; for(int k=p;k<=r;k++) { if(arrayL[i]<=arrayR[j]) arrayA[k]=arrayL[i++]; else arrayA[k]=arrayR[j++]; } }
/***************************************
/
/输入:数组arrayA、p r为数组下标,用于对数组p-r的元素排序
/输出:由小到大的数组
/时间复杂度:最坏情况下为nlgn
***************************************/
void MergeSort(int* arrayA,int p,int r)
{
int q=0;
if(p<r)
{
q=(p+r)/2;//将数组进行分解
MergeSort(arrayA,p,q);
MergeSort(arrayA,q+1,r);
Merge(arrayA,p,q,r);
}
}
注意:我是在vs2008上运行的,与vc 6.0有点区别,主要是循环体中的循环变量的作用域,出错体现在循环变量的重复定义上。例如:在vs2008或vs2010上,程序为:
#include<stdio.h>
void main()
{
int i=0;
for(int i=0;i<5;i++)
printf("%d ",i);
}
则在VC 6.0上需改为:
#include<stdio.h>
void main()
{
int i=0;
for(i=0;i<5;i++)
printf("%d ",i);
}
原文:http://blog.csdn.net/tengweitw/article/details/9056485
作者:nineheadedbird
相关文章推荐
- 【算法导论】合并排序法
- 算法导论示例-Queue
- 算法导论之动态规划之最大子数组
- [算法导论]贪心算法(greedy algorithm)
- 算法导论-------------快排的研究
- 算法导论—4.1-5
- 【算法导论】贪心算法之活动安排问题
- 【算法导论】最优二叉搜索树
- 算法导论 5.1-3
- 舍伍德算法(转 用来说明算法导论题目!!!)
- 【算法导论】简单哈希表的除法实现
- 【算法导论】快速排序
- 算法导论: 第八章 线性时间排序
- 【算法导论】贪心算法,递归算法,动态规划算法总结
- 快速排序的算法导论划分形式和hoare划分
- 算法导论——各种排序算法Java实现
- 算法导论之插入排序
- 一个菜鸟的算法导论学习笔记【Chapter 3】
- 【算法导论】桶排序
- 【算法导论】拓扑排序