分治法排序:
1、把大問題分為小問題
2、求每個小問題的解
3、和1反方向,把各個解合併起來
實現:
1、啟用兩個緩存,一個放前半部份問題,一個放后半部份問題
2、只用一個大緩存,用index的大小區分問題規模
#include<stdio.h>
#include<malloc.h>
void megre_pre(int *pre,int first, int mid, int last)
{
int *left,*right;
int i,j,k;
left = (int *) malloc(sizeof(int)*(mid-first+1));
right= (int *) malloc(sizeof(int)*(last-mid));
if ((left == NULL)||(right == NULL))
printf("error\n");
for(i=0;i<=mid-first;i++) //前半部份長度
{
left[i]=pre[first+i];
}
for (j=0;j<=last-mid-1;j++) //後半部份長度,求差值得到
{
right[j]=pre[mid+j+1];
}
for( k=0,i = 0,j = 0;(i<=mid-first) && (j<= last-mid-1); k++)
{
if(left[i]<=right[j])
{
pre[first+k] = left[i++]; //起始位置first很重要
}
else
{
pre[first+k] = right[j++];
}
}
while(i<=(mid-first))
{
pre[first+k] = left[i];
k++;
i++;
}
while(j<=(last-mid-1))
{
pre[first+k] = right[j];
k++;
j++;
}
free(left);
free(right);
}
void mergeweb(int *a,int p, int q,int r)
{
int i,j,k;
int *tmp = (int *)malloc((r - p + 1) * sizeof(int)); i = p;
j = q + 1;
k = 0;
while(i <= q && j <= r)
{
if(a[i] < a[j])
{
tmp[k] = a[i++];
}
else
{
tmp[k] = a[j++];
}
k++;
}
while(i <= q)
{
tmp[k++] = a[i++];
}
while(j <= r)
{
tmp[k++] = a[j++];
}
for (i = 0; i < k; i++)
{
a[p + i] = tmp[i];
}
free(tmp);
}
void merge_sort(int *pre,int first,int last)
{
if (first < last)
{
int q = (first + last)/2;
merge_sort(pre,first,q);
merge_sort(pre,q+1,last);
megre_pre(pre,first,q,last);
}
}
int main()
{
int pre_arr[11];
int i;
for (i=0; i<=10; i++)
{
pre_arr[i] = 10-i;
}
printf("sorted before:\n");
for (i=0; i<=10; i++)
{
printf("%d ",pre_arr[i]);
if(i>0 && (i%4) == 0)
printf("\n");
}
merge_sort(pre_arr,0,10);
printf("\n sorted after:\n");
for (i=0; i<=10; i++)
{
printf("%d ",pre_arr[i]);
if(i>0 && (i%4) == 0 )
printf("\n");
}
return 0;
}