分治思想

编写自然归并合并排序算法

算法描述:对于初始给定的数组,通常存在多个长度大于1的已自然排好序的子数组段.例如,若数组a中元素为{4,8,3,7,1,5,6,2},则自然排好序的子数组段有{4,8},{3,7},{1,5,6},{2}.用一次对数组a的线性扫描就足以找出所有这些排好序的子数组段.然后将相邻的排好序的子数组段两两合并,构成更大的排好序的子数组段({3,4,7,8},{1,2,5,6}).继续合并相邻排好序的子数组段,直至整个数组已排好序。

1. 需求分析

1. 该程序编写与运行环境VC++6.0;

2. 输入的形式和输入值的范围:这是已经给定好的,无需再输入

3. 输出的形式:按从小到大的顺序依次输出一组整数,如:{1,2,3,4,5,6,7,8}

4.  程序所能达到的功能:对于初始给定的数组,通常存在多个长度大于1的已自然排好序的子数组段 ,然后将相邻的排好序的子数组段两两合并,构成更大的排好序的子数组段,继续合并相邻排好序的子数组段,直至整个数组已排好序。

3.  概要设计

1.  若要用程序实现以上功能,需要定义的数据结构(对数据的描述)有int类型和整型数组。

2. 本程序包含的函数有主函数main函数和子函数merge()、copy()、mergeSort ()函数;所用的循环有for循环;


4.详细设计

1. 主函数内数据定义与初始化:

int  i;   int c[8]={4,8,3,7,1,5,6,2};

2. main()的实现:

int main()

{

int  i;

intc[8]={4,8,3,7,1,5,6,2};

mergeSort(c,0,7);

       cout<<"{";

       for(i=0;i<8;i++)

       {cout<<c[i]<<",";}

       cout<<"}";

 

return 0;

}

 

merge()函数的实现:

void merge(int a[],int b[],int left,int mn,int right)

{

int i=left;

int j=mn+1;

int k=left;

   while(i<=mn&&j<=right)//i的取值范围为[left,mn],j的取值范围为[mn+1,right]

{

    if(a[i]<a[j])

    b[k++]=a[i++];

 else

        b[k++]=a[j++];

}

if(i>mn)//说明右边元素比左边元素多

{

          int z;

         for(z=j;z<=right;z++)

                b[k++]=a[z];

}

else

{

       int z;

       for(z=i;z<=right;z++)

b[k++]=a[z];

}

 

}

mergeSort( ) 函数的实现:

void mergeSort(int a[], int left, int right)

{

int *b=new int[];

      if(left<right) {//至少有2个元素

      inti=(left+right)/2;  //取中点

     mergeSort(a, left, i);

     mergeSort(a, i+1, right);

      merge(a, b,left, i, right);  //合并到数组b

      copy(a, b,left, right);    //复制回数组a

      }

}

 

Copy()函数的实现:

void copy(int a[],int b[], int left,int  right)

{

int i;

for(i=left;i<=right;i++)

        a[i]=b[i];}

5.调试分析

main()的时间复杂度为O(n),空间复杂度为O(1):

int main()

{

int  i;

intc[8]={4,8,3,7,1,5,6,2};

mergeSort(c,0,7);

       cout<<"{";

       for(i=0;i<8;i++)

       {cout<<c[i]<<",";}

       cout<<"}";

 

return 0;

}

 

merge()函数的时间复杂度为O(n),空间复杂度为O(n):

void merge(int a[],int b[],int left,int mn,int right)

{

int i=left;

int j=mn+1;

int k=left;

   while(i<=mn&&j<=right)//i的取值范围为[left,mn],j的取值范围为[mn+1,right]

{

    if(a[i]<a[j])

    b[k++]=a[i++];

 else

        b[k++]=a[j++];

}

if(i>mn)//说明右边元素比左边元素多

{

          int z;

         for(z=j;z<=right;z++)

                b[k++]=a[z];

}

else

{

       int z;

       for(z=i;z<=right;z++)

b[k++]=a[z];

}

 

}

mergeSort( ) 的时间复杂度为O(1),空间复杂度为O(1):

void mergeSort(int a[], int left, int right)

{

int *b=new int[];

      if(left<right) {//至少有2个元素

      inti=(left+right)/2;  //取中点

     mergeSort(a, left, i);

     mergeSort(a, i+1, right);

      merge(a, b,left, i, right);  //合并到数组b

      copy(a, b,left, right);    //复制回数组a

      }

}

 

Copy()的时间复杂度为O(n),空间复杂度为O(n):

void copy(int a[],int b[], int left,int  right)

{

int i;

for(i=left;i<=right;i++)

               a[i]=b[i]}

该程序调试采用单步跟踪法,首先先初始化数据,然后开始进入merge()函数,

然后单步跟踪mergeSort(),在单步跟踪copy(),遇到main()函数cout调试结束;

 

6.使用说明

#include<iostream.h>

void merge(int a[],int b[],int left,intmn,int right)

{

inti=left;int j=mn+1; int k=left;

while(i<=mn&&j<=right)//i的取值范围为[left,mn],j的取值范围为[mn+1,right]

{

    if(a[i]<a[j])b[k++]=a[i++];

     elseb[k++]=a[j++];          }

if(i>mn)//说明右边元素比左边元素多

{ intz;  for(z=j;z<=right;z++) b[k++]=a[z];     }

else{intz; for(z=i;z<=right;z++)   b[k++]=a[z]; }}

void copy(int a[],int b[], int left,int  right)

{

int i;

for(i=left;i<=right;i++)

        a[i]=b[i];

}

void mergeSort(int a[], int left, int right)

{

int*b=new int[];

     if (left<right) {//至少有2个元素

     int i=(left+right)/2;  //取中点

     mergeSort(a, left, i);

     mergeSort(a, i+1, right);

     merge(a, b, left, i, right);  //合并到数组b

     copy(a, b, left, right);    //复制回数组a

      }

}

int main()

{

int  i;

intc[8]={4,8,3,7,1,5,6,2};

mergeSort(c,0,7);

       cout<<"{";

       for(i=0;i<8;i++)

       {cout<<c[i]<<",";}

       cout<<"}";

 

return0;

}

基本思想:将待排序元素分成大小大致相同的2个子集合,分别对两个字集合排序,最终将排好的子集合合并成为所要求的排好序的集合;

以上程序在VC++6.0环境下编写与运行的,该程序采用c++编程,执行该程序时,无需输入,主函数的的数据类型和初始化之后,调用merge()函数,转到merge()函数之后,merge函数递归调用它本身,再调用mergeSort()函数和copy()函数,最后输出;

7.测试结果


猜你喜欢

转载自blog.csdn.net/ccccc49813645075/article/details/80201540
今日推荐