數據結構 || 常見的排序算法@歸併排序

歸併排序

基本思想
  • 歸併排序(MERGE-SORT)是建立在歸併操作上的一種有效的排序算法,該算法是採用分治法(Divide and Conquer)的一個非常典型的應用。
  • 將已有序的子序列合併,得到完全有序的序列;
  • 即先使每個子序列有序,再使子序列段間有序。
  • 若將兩個有序表合併成一個有序表,稱爲二路歸併
圖解過程

在這裏插入圖片描述

代碼實現
  • 實現分解的過程
  • 利用遞歸的思想將一個完整的數組分解成最小單位
  • 注意最小區間的判定條件
  • 注意區間劃分的邊界條件
  • 函數的功能:是以數組下標的方式將原來數組中的數據分割成最小單位,以便進行排序
//歸併排序
//區間爲[left,right)
//左閉右開的區間
void _MergeSort(int *array,int left,int right,int *arr){
  if(right==left+1){
    //區間中只剩一個數字
    return;
  }

  if(left>=right){
    //區間內沒有數了
    return ;
  }
  
  int mid=(right-left)/2+left;


  //此處的mid+left的原因是
  //可能存在left爲非0 的位置開始,若不加left不能得到準確的mid
  
  //區間被分成左右兩個小區間
  //[left,mid)
  //[mid,right)
  //先把左右兩個小區間進行排序,分治算法,遞歸解決
  _MergeSort(array,left,mid,arr);
  _MergeSort(array,mid,right,arr);

  //左右兩個小區間已經有序了
  //合併兩個有序數組
  Merge(array,left,mid,right,arr);
}

//歸併排序
void MergeSort(int *array,int size){

  //讓所有的排序在一個固定的區間中執行
  int* arr=new int[size];
  _MergeSort(array,0,size,arr);
  delete[] arr;
}
  • 實現合併和排序的過程
  • 合併的過程中存在的兩種情況
  • 1.左邊區間中的數普遍小於右邊區間中的數,左邊的數已經全部寫入新的空間中而右邊區間中的還有剩餘,
  • 2.右邊區間中的數普遍小於左邊區間中的數,右邊的數已經全部寫入新的空間總而左邊區間中的還有剩餘
  • 解決辦法
  • 左邊還是右邊區間中的數已經全部放到新的空間中後,將另外一邊中剩餘的數全部放到新的空間中(因爲其已經有序了)
  • 函數功能:將分割開的數據進行整合並排序
//合併兩個有序數組
//array[left,mid)
//array[mid,right)
void Merge(int *array,int left,int mid,int right ,int* arr){
  int size=right-left;//區間大小

  int _left_index=left; 
  int _right_index=mid;
  int arr_index=0;

  while(_left_index< mid && _right_index < right ){

    if(array[_left_index]<= array[_right_index]){
      arr[arr_index]=array[_left_index];
      _left_index++;
    }else{
      arr[arr_index]=array[_right_index];
      _right_index++;
    }
      arr_index++; 
  }


  //走到這裏說明有一個區間的數已經被移動完了
  //需要將另一個區間中的數加到新的空間中
  
  while(_left_index< mid){
    arr[arr_index++]=array[_left_index++];
  }

  while(_right_index< right){
    arr[arr_index++]=array[_right_index++];
  }
  
  for(int i=0;i<size;i++){
    array[left+i]=arr[i];
  }

}
測試
  • 代碼
void TestSort(){
  int array[]={1,3,7,9,6,4,54,76,34,66};
  int size=sizeof(array)/sizeof(array[0]);
  PrintArray(array,size);
  MergeSort(array,size);
  PrintArray(array,size);

  int array1[]={66,44,33,22,11,9,8,7};
  int size1=sizeof(array)/sizeof(array[0]);

  Merge_Sort(array1,size1);
  PrintArray(array1,size1);
}

int main(){
  TestSort();
  return 0;
}
  • 運行結果

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章