# 【算法导论】分治法及归并排序

(1).原问题==（划分）== >>若干个更小规模的子问题。

(2).要求子问题的求解方法与原问题相同。

（1）分解(Divide)：将当前问题划分成若干子问题

（2）解决(Conquer)：递归解子问题，如果子问题足够小则直接解

（3）合并(Combine)：将子问题的解合并长原问题

/*
《Introduction to Algorithms(second edition)》
chapter2，MERGE_SORT()
date：2014-9-18
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>

#define MAX 50

typedef struct
{
int arr[MAX+1];
int length;
}SortArr;

SortArr *CreateSortArr()
{
int i = 0;
char buf[4*MAX] = "";
char *ptr = NULL;
SortArr *sortArr = (SortArr *)malloc(sizeof(SortArr));
memset(sortArr, 0, sizeof(SortArr));

printf("请输入待排序数据，以逗号分隔，以分号结束\n"
"例：23,12,65,36,35;\n"
"input:");
scanf("%s", buf);

ptr = buf;
sortArr->arr[i] = 0;	//arr[0]不存值用作哨兵单元
i = 1;
while(*ptr != ';')
{
sortArr->arr[i] = atoi(ptr);
i++;

ptr = strstr(ptr, ",");
if(!ptr)
{
break;
}
ptr++;
}
sortArr->length = (i - 1);

return sortArr;
}

int merge(int arr[], int p, int q, int r)
{
int i = 0;
int j = 0;
int k = 0;
int n1 = 0;
int n2 = 0;
int *leftArr = NULL;
int *rightArr = NULL;

n1 = q - p + 1;
n2 = r - q;

//为了和arr[]下标保持一致，leftArr[0]和rightArr[0]不用
leftArr = (int *)malloc((n1 + 2) * sizeof(int));
rightArr = (int *)malloc((n2 + 2) * sizeof(int));

for(i = 1; i <= n1; i++)
{
leftArr[i] = arr[p+i-1];
}
for(j = 0; j <= n2; j++)
{
rightArr[j] = arr[q+j];
}

i = 1;
j = 1;

//将最后一个数设置为哨兵
leftArr[n1+1] = INT_MAX;
rightArr[n2+1] = INT_MAX;

for(k = p; k <= r; k++)
{
if(leftArr[i] <= rightArr[j])
{
arr[k] = leftArr[i];
i++;
}
else
{
arr[k] = rightArr[j];
j++;
}
}

free(leftArr);
free(rightArr);
return 0;
}

int mergeSort(int arr[], int p, int r)
{
int q = 0;

if(p < r)
{
q = (p + r) / 2;
mergeSort(arr, p, q);
mergeSort(arr, (q+1), r);
merge(arr, p, q, r);
}

return 0;
}

int MergingSortRecursion(SortArr *sortArr)
{
mergeSort(sortArr, 1, sortArr->length);
return 0;
}

int PrintArray(SortArr sortArr)
{
int i = 0;

for(i = 1; i <= sortArr.length; i++)
{
printf("%d,", sortArr.arr[i]);
}
printf("\b;\n");

return 0;
}

int main()
{
SortArr *sortArr = NULL;
sortArr = CreateSortArr();

printf("\nBefore Sort：\t");
PrintArray(*sortArr);

MergingSortRecursion(sortArr);

printf("Sorted Array：\t");
PrintArray(*sortArr);

free(sortArr);

return 0;
}


• 本文已收录于以下专栏：

## 《算法导论》读书笔记（二）——分治法

• vinson0526
• 2013年09月02日 22:15
• 907

## 算法导论：归并排序java实现

• xidian_db
• 2015年03月30日 16:33
• 389

## 算法导论学习：归并排序法的实现

• qq_17256847
• 2016年04月14日 16:13
• 297

## 归并排序与分治算法详解

• freestyle4568
• 2015年12月04日 16:00
• 1816

## MIT算法导论学习笔记-Lecture3：分治法

• ai552368625
• 2014年07月25日 09:01
• 1944

## 【算法导论】归并排序

• cyp331203
• 2014年12月02日 21:42
• 1040

## 老生常谈——分治法与归并排序

• dd864140130
• 2016年03月11日 23:18
• 1159

## 算法导论——归并排序

• Anger_Coder
• 2013年09月30日 11:16
• 2552

## 分治法-----归并排序（C语言描述）

• LCYong_
• 2016年11月25日 15:16
• 1756

## 分治法之归并排序（优化版）

#include #define THRESHOLD 28 void ModMerge(int Array[],int TempArray[],int left,int right,int mi...
• niushitang
• 2013年03月02日 11:34
• 2029

举报原因： 您举报文章：【算法导论】分治法及归并排序 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)