分治合并排序

//分治合并排序算法
//原理:把两个已经排序好的序列进行合并,成为一个排序好的序列。
//1. 在解决一个问题时,算法要一次或多次的调用自身来解决相关的子问题,这些算法一般采用分治策略:
//   将原来的问题划分为n个规模较小而结构和原问题类似的子问题,递归地解决这些问题,然后合并其结
//   果就得到原来问题的解。
//   分治法在每一层递归时都有三个步骤:
//   a. 分解Divede:将原问题分解为一系列的子问题
//   b. 解决Conquer:递归解决问题,若问题较小,直接解决问题
//   c. 合并Combine: 将原来的结果合并成原问题的解
//
//2. 排序过程
//   以下列程序的打印结果为例
//Example for Divide and Conquer Sort!
//输入数组:Input Array A[12] = {2,11,7,7,9,11,5,3,3,0,1,3}
//Sort...
//Merge:A[0..11] 要排序0-11下标的数据
//Merge:A[0..5]  则要先排序0-5下标的数据
//Merge:A[0..2]  再分解为要排序0-2下标的数据
//Merge:A[0..1]  再分解为要排序0-1下标的数据
//Merge:A[0],Return 再分解为排序0下标的数据,当然这里就没法再分了
//Merge:A[1],Return 同上
//Combine:A[0...0...1] = {2,11} 合并0-1下标的数据
//Merge:A[2],Return 不能分的下标2的数据
//Combine:A[0...1...2] = {2,7,11} 合并0-1和2的数据
//Merge:A[3..5] 同样分解3-5下标
//Merge:A[3..4]
//Merge:A[3],Return
//Merge:A[4],Return
//Combine:A[3...3...4] = {7,9}
//Merge:A[5],Return
//Combine:A[3...4...5] = {7,9,11} 合并的3-5下标数据
//Combine:A[0...2...5] = {2,7,7,9,11,11} 合并的0-5下标数据
//Merge:A[6..11] 同样分解6-11
//Merge:A[6..8]
//Merge:A[6..7]
//Merge:A[6],Return
//Merge:A[7],Return
//Combine:A[6...6...7] = {3,5}
//Merge:A[8],Return
//Combine:A[6...7...8] = {3,3,5}
//Merge:A[9..11]
//Merge:A[9..10]
//Merge:A[9],Return
//Merge:A[10],Return
//Combine:A[9...9...10] = {0,1}
//Merge:A[11],Return
//Combine:A[9...10...11] = {0,1,3}
//Combine:A[6...8...11] = {0,1,3,3,3,5}合并的6-11下标数据
//Combine:A[0...5...11] = {0,1,2,3,3,3,5,7,7,9,11,11} 全部合并起来

#include "stdio.h"

//函数功能:将Array数据中的[left..middle]和[middle+1..right]两个数据序列
//          (这两个序列假设已经为升序序列)进行升序组合
//输入:    Array: 待组合序列
//          left:  左侧序列开始下标位置
//          middle:左侧序列结束下标位置,同时middle+1为右侧序列开始下标位置
//          right: 右侧序列结束下标位置
//输出:    Array: 已组合排序的序列
//返回:    0申请内存错误,1成功
int Combine(int *Array,int left,int middle,int right)
{
 int i,i1,i2;
 int start = left;

 int *pArrayNew;
 
 if (right == left) return;

 pArrayNew = (int*)malloc((right-left+1)*sizeof(int));
 if (NULL == pArrayNew) {
  printf("Error Sort:Can't Alloc Memery!\n");
  return 0; 
 }
 
 i = 0;
 i1 = left;
 i2 = middle+1;
 while(start <= right) {
  start++;
  if (i1 == (middle+1)) { //左侧数据合并完毕,只合并右侧数据
   pArrayNew[i++] = Array[i2++];
   continue;
  }
  if (i2 == (right+1)) { //右侧数据合并完毕,只合并左侧数据
   pArrayNew[i++] = Array[i1++];
   continue;
  }
  if (Array[i1] < Array[i2]) {
   pArrayNew[i++] = Array[i1++];
  } else {
   pArrayNew[i++] = Array[i2++];
  }
 }

 memcpy(&Array[left],pArrayNew,(right-left+1)*sizeof(int));


 printf("Combine:A[%d...%d...%d] = {",left,middle,right);
 for (i = left; i <= right;i++) {
  printf("%d",Array[i]);
  if (i != right) {
   printf(",");
  }
 }
 printf("}\n");

 
 free(pArrayNew);
 return 1;
}


//函数功能:将piArrayIn数据中的iSize个数据进行升序排序
//输入:    piArrayIn:待排序序列
//          iStart:排序数据的开始位置下标,取0
//          iEnd:  排序数据的最后位置下标,取piArrayIn的长度-1
//输出:    piArrayIn:已排序序列
//返回:    0申请内存错误,1成功
int MergeSort(int *piArrayIn,int iStart,int iEnd)
{
 int iMid;
 if (iStart == iEnd) {
  printf("Merge:A[%d],Return\n",iStart);
  return;
 }
 printf("Merge:A[%d..%d]\n",iStart,iEnd);
 iMid = (iEnd - iStart)/2;
 if ( MergeSort(piArrayIn,iStart,iStart+iMid) == 0) {
  return 0; 
 }
 if ( MergeSort(piArrayIn,iStart+iMid+1,iEnd) == 0) {
  return 0; 
 }
 return Combine(piArrayIn,iStart,iStart+iMid,iEnd);
}


////////////////////////////////////////////////////////
//TEST Code
#define ARRAY_LEGTH 12
int A[ARRAY_LEGTH];

int main()
{
 int i;
 
 srand((int)time(0));
 printf("Example for Divide and Conquer Sort!\n");
 

 printf("Input Array A[%d] = {",ARRAY_LEGTH);
 for (i = 0; i < ARRAY_LEGTH; i++) {
  A[i] = rand()%ARRAY_LEGTH; 
  printf("%d",A[i]);
  if (i != ARRAY_LEGTH-1) {
   printf(","); 
  }
 }
 printf("}\n");

 printf("Sort...\n"); 

 MergeSort(A,0,ARRAY_LEGTH-1);
 
 printf("After Sort:A[%d] = {",ARRAY_LEGTH); 
 for (i = 0; i < ARRAY_LEGTH; i++) { 
  printf("%d",A[i]);
  if (i != ARRAY_LEGTH-1) {
   printf(","); 
  }
 }
 printf("}\n");

 return 1;
}

 

你可能感兴趣的:(算法,null,input,merge)