归并排序

思路

知识点:分治法

步骤:1、分割 2、治理

采用递归分割

递归容易出,segmentation fault。注意边界条件。
只有在分割时,用的递归。分成了一个个函数块,从始至终,只有一个原始数组,变化了边界范围,来分块。

java代码

 //分治
    public static int[] divide(int[] data,int start,int end){
        int mid=(end+start)/2;
        if(start<end){
            divide(data,start,mid);
            divide(data,mid+1,end);
            //合并
            merge(data,start,mid,end);
        }
        return data;
    }
    //合并
    public static void merge(int[] data,int start,int mid,int end){
        int left=start;
        int right=mid+1;
        int k=start;//注意k起始值随着归并子区间变化
        int[] temp=new int[data.length];
        //把较小的数移到新数组中
        while (left<=mid&&right<=end){
            if (data[left]<data[right]){
                temp[k++]=data[left++];
            }else {
                temp[k++]=data[right++];
            }
        }
        //左边剩余的移到数组
        while (left<=mid){
            temp[k++]=data[left++];
        }
        //右边剩余移到数组
        while (right<=end){
            temp[k++]=data[right++];
        }
        //复制到原始数组
        while (start<=end){
            data[start]=temp[start];
            start++;
        }
    }

    public static void main(String[] args) {
        int arr[]={3,1,2,8,7,5,9,4,6,0};
        int[] result=divide(arr,0,9);
//        System.out.println(Arrays.toString(arr));
        for(int r:result)
            System.out.print(r+" ");
    }

c代码

//合并子区间
void merge(int data[],int start,int mid,int end){
  int left=start; 
  int right=mid+1;   
  int* temp=(int *)malloc((end-start+1)*sizeof(int));//给临时数组分配空间
  int k=start;

  //把排序好的合并
  while (left<=mid&&right<=end)
  {
    if(data[left]<data[right])
      temp[k++]=data[left++];
    else
      temp[k++]=data[right++];
  }
    //把剩下的放入
    while (right<=end)
      temp[k++]=data[right++];
    while (left<=mid)
      temp[k++]=data[left++];
  
  //复制到原始数组
  while (start<=end){
    data[start]=temp[start];
    start++;
  } 
  free(temp);
}
//入口
void mergeSort(int data[],int start,int end){ 
    int mid=(start+end)/2;
    if(start<end){
      //划分左右子区间
      mergeSort(data,start,mid);
      mergeSort(data,mid+1,end);
      //归并排好序的左右
      merge(data,start,mid,end);
    }
}

int main() {
  int arr[]={3,1,2,8,7,5,9,4,6,0};
  mergeSort(arr,0,9);
  for(int i=0;i<10;i++) cout<<arr[i]<<" ";
  return 0;
}
posted @ 2021-12-10 19:37  Infinite_V胜  阅读(30)  评论(0)    收藏  举报