归并排序算法

来源:互联网 发布:手机怎么破解网络限制 编辑:程序博客网 时间:2024/06/08 12:38
// 归并排序.
// 思路:
//      1:将数据一切为二.
//        2:如果数据为一了,就不再切割了.否则,重复1.
//      3:对切成的一个一个数据两两合并为一个元素.这个合并后的元素里的两个元素,保证有序.
//      4:重复3
#include <stdio.h>
#include <stdlib.h>

// 合并数据
// 思路:
//      1:生成临时两个数组,arrayLeft[beginIndex,partation],arrayRight[partation+1,endIndex];
//      2:将array的数据copy到arrayLeft,arrayRigh中.
//      3:比较arrayLeft[beginIndex,partation],arrayRight[partation+1,endIndex],将小的付给当前的array中.
//      4:当arrayLeft,arrayRight中有一个数据处理完后,将剩下的没处理完的数据全部顺序拷贝到array中.
//      5:合并结束
void merge(int array[],unsigned int beginIndex,unsigned int partationIndex,unsigned int endIndex){
    const unsigned int leftArrayLength = partationIndex-beginIndex+1;
    const unsigned int rightArrayLength = endIndex-partationIndex;
    //1:生成临时两个数组,arrayLeft[beginIndex,partation],arrayRight[partation+1,endIndex];
    // 这里很不爽,C语言支持array[变量]给数组分配内存.所以才有了下面的几个指针.
    int *arrayLeft = (int*)malloc(sizeof(int)*leftArrayLength);
    int *arrayRight = (int*)malloc(sizeof(int)*rightArrayLength);
    int *pLeftArrayCurrent = arrayLeft;
    int *pRightArrayCurrent = arrayRight;
    //2:将array的数据copy到arrayLeft,arrayRigh中.
    int i = beginIndex;
    while(i<=partationIndex){
        *pLeftArrayCurrent = array[i];
        ++pLeftArrayCurrent;
        ++i;
    }
    //记得将当前指针复位到数组的头
    pLeftArrayCurrent = arrayLeft;
    
    while(i<=endIndex){
        *pRightArrayCurrent = array[i];        
        ++pRightArrayCurrent;
        ++i;           
    }
    //记得将当前指针复位到数组的头
    pRightArrayCurrent = arrayRight;

    int left = 0;
    int right = 0;
    int index = beginIndex;
    //3:比较arrayLeft[beginIndex,partation],arrayRight[partation+1,endIndex],将小的付给当前的array中.
    while(left < leftArrayLength && right < rightArrayLength){
        if(*pLeftArrayCurrent <= *pRightArrayCurrent){
            array[index] = *pLeftArrayCurrent;
            ++index;
            ++pLeftArrayCurrent;
            ++left;
        }else{
            array[index] = *pRightArrayCurrent;
            ++index;
            ++pRightArrayCurrent;
            ++right;
        }
        //printf("%d,%d\n",*pLeftArrayCurrent,*pRightArrayCurrent);
    }
    //4:当arrayLeft,arrayRight中有一个数据处理完后,将剩下的没处理完的数据全部顺序拷贝到array中.
    while(left < leftArrayLength){
        array[index] = *pLeftArrayCurrent;
        ++pLeftArrayCurrent;
        ++left;
        ++index;
    }
    while(right < rightArrayLength){
        array[index] = *pRightArrayCurrent;
        ++pRightArrayCurrent;
        ++right;
        ++index;
    }
    if(arrayLeft != 0){
        free(arrayLeft);
    }
    if(arrayRight != 0){
        free(arrayRight);
    }
    //5:合并结束
    return;
}

void merge_sort(int array[],unsigned int beginIndex,unsigned int endIndex){
    //1:将数据一切为二.
    //以待排序的数据的起点和终点的中间点为分割点
    unsigned int partationIndex = beginIndex + (endIndex-beginIndex)/2;
    //2:如果数据为一了,就不再切割了.否则,重复1.
    if(beginIndex == endIndex){
        return;
    }else{
        merge_sort(array,beginIndex,partationIndex);
        merge_sort(array,partationIndex+1,endIndex);
    }
    //3:对切成的一个一个数据两两合并为一个元素.这个合并后的元素里的两个元素,保证有序.
    merge(array,beginIndex,partationIndex,endIndex);
}

/////////
#include "merge_sort.h"

void printArray(int array[],unsigned int len){
    for(unsigned int i =0; i<len;++i){
        printf("%d ",array[i]);
    }
    printf("\n");
}

int main(int argc,char** argv){
    int arr[] = {12, 6, 11, 13, 2, 5, 23, 11, 6, 7, 6};
    int arr_size = sizeof(arr)/sizeof(arr[0]);
    printArray(arr,arr_size);
    merge_sort(arr,0,arr_size-1);
    printArray(arr,arr_size);
    return 0;
}
0 0
原创粉丝点击