归并排序

来源:互联网 发布:关闭数据库的命令 编辑:程序博客网 时间:2024/06/08 18:44

归并排序

归并排序是又一类不同的排序算法。“归并”的含义是将两个或两个以上的有序表组合成一个新的有序表。

归并操作的工作原理如下:
1. 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
2. 设定两个指针,最初位置分别为两个已经排序序列的起始位置
3. 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
4. 重复步骤3直到某一指针超出序列尾
5. 将另一序列剩下的所有元素直接复制到合并序列尾

递归代码实现:

#include <stdio.h>#define MAXSIZE 10void sout(int num[] ,int n ){    int j ;    for (j=0 ; j<n ; j++)        printf("%d ",num[j]);    printf("\n");}//实现归并,并把最后结果存到list1里面void merging(int *list1,int list1_size,int *list2,int list2_size){    int i,j,k,m;    int temp[MAXSIZE];    i = j = k = 0;    while (i<list1_size && j<list2_size)    {        if (list1[i] < list2[j])            temp[k++] = list1[i++];        else            temp[k++] = list2[j++];    }    while (i<list1_size)        temp[k++] = list1[i++];    while (j<list2_size)        temp[k++] = list2[j++];    for (m=0 ; m<(list1_size+list2_size);m++)        list1[m] = temp[m];    sout(list1,list1_size+list2_size);}void MergeSort(int k[],int n){    if ( n>1)    {        int *list1 = k;        int list1_size = n/2;        int *list2 = k+n/2;        int list2_size = n-list1_size;        MergeSort(list1,list1_size);        MergeSort(list2,list2_size);        merging(list1,list1_size,list2,list2_size);    }}int main(){    int i,a[10] = {5,2,6,0,3,9,1,7,4,8};    MergeSort(a,10);    printf("排序后的结果是:");    for (i=0 ; i<10 ; i++)        printf("%d ",a[i]);    printf("\n");    return 0;}

递归要不断的调用自身导致大量的空间消耗,时间消耗,算法的效率降低。
归并的迭代算法

#include <stdio.h>#include <stdlib.h>#define MAXSIZE 10void sout(int num[] ,int n ){    int j ;    for (j=0 ; j<n ; j++)        printf("%d ",num[j]);    printf("\n");}void MergeSort(int k[],int n){   int i , left_min , left_max , right_min , right_max ;   //开辟一个与元素组相同大小的临时空间   int *temp = (int*)malloc(n*sizeof(int));   for (i=1 ; i<n ;i*=2)//步长   {       //每次都从数组的头元素开始       for (left_min=0 ; left_min< n-i ;left_min = right_max)       {           right_min = left_max = left_min+i;           right_max = left_max + i ;           //最大只能为n ,超过了则要改为n           if (right_max > n)            right_max = n ;           int next = 0;           while (left_min < left_max && right_min < right_max)           {               if (k[left_min] < k[right_min])                temp[next++] = k[left_min++];               else                temp[next++] = k[right_min++];           }           //上面循环结束的条件有两个,如果是左边的游标尚未到达,那么需要把            //数组接回去,如果右边没到达,说明右边的数据比较大,则不用移动位置           while (left_min < left_max)           {               //左边的数据较大,直接把它们接到数组的min之前就行了               k[--right_min] = k[--left_max];           }           while (next > 0)           {               //把排好序的那部分数组返回到k               k[--right_min] = temp[--next];           }       }   }}int main(){    int i,a[10] = {5,2,6,0,3,9,1,7,4,8};    MergeSort(a,10);    printf("排序后的结果是:");    for (i=0 ; i<10 ; i++)        printf("%d ",a[i]);    printf("\n");    return 0;}
0 0
原创粉丝点击