您的位置:首页 > 其它

跟着《算法导论》学习——插入排序与归并排序

2013-12-20 13:52 344 查看
读前声明:本人所写帖子主要为了记录本人学习的一个过程,无他想法,由于内容比较肤浅,如有雷同,非常正常!!!

本文内容:

本文主要是参考《算法导论》这本书,完成部分算法编写,可能编程习惯或者风格比较差,还请多多批评。

1、插入排序(Insertion Sort)

插入排序是对少量元素进行排序的有效算法,其机理与很多人打牌时,整理手中牌时的做法差不多。开始摸牌时,我们的左手是空的,牌面朝下放在桌上,接着,一次从桌上摸起一张牌,并将它插入到左手一把牌中的正确位置上。为了找到这张牌的正确位置,要将它与手中已有的每一张牌从右到左的比较。

其代码如下:void InsertionSort(int a[],int n)
{
for(int j=1;j<n;j++)
{
int key = a[j];
int i = j-1;
while (i>=0&&a[i]>key)
{
a[i+1] = a[i];
i--;
}
a[i+1] = key;
}
2、归并排序(Merge sort)
归并排序是分治法(Divide-and-Conquer)的一个应用。分治法的的策略如下:将原问题划分为n个规模较小而结构与原问题相似的子问题;递归地解决这些子问题,然后再合并其结果,就得到原问题的解。分治模式在每一层递归都有三个步骤:

分解(Divide):将原问题分解成一系列子问题;

解决(Conquer):递归地求解各子问题,若子问题足够小,则直接求解;

合并(Combine):将子问题的结果合并成原问题的解

归并排序完全按照上述模式,直观的操作如下:

分解:将n个元素分成各含n/2个元素的子序列;

解决:用合并排序法对两个子序列递归地排序;

合并:合并两个已排序的子序列以得到排序结果。

在对子序列排序时,其长度为1时递归结束,单个元素被视为已排序的。

合并排序的关键步骤在于合并步骤中的合并两个已排序子序列。为做排序,引入一个辅助过程Merge,其过程是将两个子序列经过比较,合并成一个大的排好序的数组。

Merge子函数如下:

void Merge(int a[],int b[],int left,int middle,int right)
{
for (int i=left;i<=right;i++)
{
b[i] = a[i];
}
int s1 = left;
int s2 = middle+1;
int t = left;
while (s1<=middle&&s2<=right)
{
if (b[s1]<=b[s2])
{
a[t++] = b[s1++];
}
else
{
a[t++] = b[s2++];
}
}
if (s1==middle+1)
{
while (s2<=right)
{
a[t++] = b[s2++];
}
}
if (s2==right+1)
{
while (s1<=middle)
{
a[t++] = b[s1++];
}
}
}
归并排序算法过程:
void MergeSort(int a[],int b[],int left,int right)
{
if(left>=right) return;
int middle = (left+right)/2;
MergeSort(a,b,left,middle);
MergeSort(a,b,middle+1,right);
Merge(a,b,left,middle,right);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息