日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

归并排序(代码注释超详细)

發布時間:2023/11/27 生活经验 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 归并排序(代码注释超详细) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

歸并排序:

? ? ? ? ? ? ? (復制粘貼百度百科沒什么意思),簡單來說,就是對數組進行分組,然后分組進行排序,排序完最后再整合起來排序!

我看了很多博客,都是寫的8個數據呀什么的(2^4,分組方便),我就想著,要是10個數據呢,他們那種就沒怎么講清楚,下面我來講一下我所理解的歸并排序!

思路整理如下所示:

?下面用代碼來實現(代碼注釋超詳細):

用來判斷整合幾次的最外層循環!

void MergeSort(int *arr, int len) //這塊用了函數調用  當然你給上面那玩意寫到這個里面完全可以
{for(int i=1; i<len; i*=2)//首先來看假如數組有八位滿足不滿足條件 (2^3)<8不成立 也就是四四合并之后   就完成了合并  查看上面圖 滿足條件//再來看假如有10個值  (2^4)<10不成立   也就是八八合并之后  需要四次合并  查看上圖  滿足條件{Merge(arr, len, i); //調用函數主體   直接寫到這個循環中也完全ok}
}

函數主體:

//8 6 3 2 7 1 9 5 4 0
//如上所示 單個數的時候 L1 = H1就是這個數字本身
//68  23  17  59  04
//這塊拿前兩個分好的數組為例 arr[L1] = 6  arr[H1] = 8  arr[L2] = 2  arr[H2] = 3
//2368    1579    04
//拿這組舉例的話  arr[L1] = 2  arr[H1] = 8   arr[L2] = 1   arr[H2] = 9
//12356789    04
//arr[L1] = 1   arr[H1] = 9   arr[L2] = 0   arr[H2] = 4
void Merge(int* arr, int len, int gap)
{//數組本身空間不夠,這塊早堆區申請一個和數組等長的動態內存int* brr = (int*)malloc(sizeof(int) * len);assert(brr != NULL);//int L1 = 0;   //這塊就到歸并排序的精髓了   假設第一步,gap的值是1  一一合并L1 = 0  H1 = 0int H1 = L1 + gap - 1;  //接上行 合并之后L1 = 0,H1 = 1int L2 = H1 + 1;    //到這兒之后  按照上圖來說68 23   arr[L1] = 6  arr[H1] = 8;int H2 = L2 + gap - 1 < len ? L2 + gap - 1 : len - 1;//那么arr[L2] = 2   arr[H2] = 3 ; L2 = H1 + 1 = 2 ; //H2 = L2 + gap - 1 < len ? L2 + gap - 1 : len - 1 = 3;這里寫個三目運算符主要是用來判斷L2+gap如果越界len的話,那么H2的下標值為len-1int i = 0;// 堆區申請來的空間brr存放數據的下標while (L2 < len)     //這塊為什么要L2 < len 呢 先想一下 如果用L1 H1的話 跑到后期 L2早就越界了導致左邊的白跑{					 //然后使用L2的時候可以保證右邊的數組最少取到一個值  使用H2的話會導致提前越界  導致有些數據不能成功排序while (L1 < H1 && L2 < H2){if (arr[L1] <= arr[L2]){brr[i++] = arr[L1++]; //這塊后置++的原因是先用再加 難以理解的話可以寫成下面這種/*brr[i] = arr[L1];i++, L1++;*/}else{brr[i++] = arr[L2++];}}while (L1 <= H1)//因為上面的內層while中是 "&&" 可能其中一項滿足 但是另外一項不滿足  因此退出了while循環 因此寫這么一句 {               //如果左邊還有數據  挪下來brr[i++] = arr[L1++];}while (L2 <= H2)//如果右邊組還有數據,挪下來{brr[i++] = arr[L2++];}L1 = H2 + 1;  //因為數據得遍歷完分組排序  這是在新的分好的數組中的左值與右值  與上面一毛一樣H1 = L1 + gap - 1;L2 = H1 + 1;H2 = L2 + gap - 1 < len ? L2 + gap - 1 : len - 1;}//這塊退出while就是右邊的arr中數組L2越界了(while(L2<len)) 此時右邊肯定沒有數據了//至于arr中左邊的數組還有沒有值  不確定再來個判斷while (L1 < len){brr[i++] = arr[L1++];}//然后再將brr中數組導入到arr中即可  for (int i = 0; i < len; i++){arr[i] = brr[i];}free(brr); //堆區空間的釋放
}

將代碼寫一塊就是:

//8 6 3 2 7 1 9 5 4 0
//如上所示 單個數的時候 L1 = H1就是這個數字本身
//68  23  17  59  04
//這塊拿前兩個分好的數組為例 arr[L1] = 6  arr[H1] = 8  arr[L2] = 2  arr[H2] = 3
//2368    1579    04
//拿這組舉例的話  arr[L1] = 2  arr[H1] = 8   arr[L2] = 1   arr[H2] = 9
//12356789    04
//arr[L1] = 1   arr[H1] = 9   arr[L2] = 0   arr[H2] = 4
void Merge(int* arr, int len, int gap)
{//數組本身空間不夠,這塊早堆區申請一個和數組等長的動態內存int* brr = (int*)malloc(sizeof(int) * len);assert(brr != NULL);//int L1 = 0;   //這塊就到歸并排序的精髓了   假設第一步,gap的值是1  一一合并L1 = 0  H1 = 0int H1 = L1 + gap - 1;  //接上行 合并之后L1 = 0,H1 = 1int L2 = H1 + 1;    //到這兒之后  按照上圖來說68 23   arr[L1] = 6  arr[H1] = 8;int H2 = L2 + gap - 1 < len ? L2 + gap - 1 : len - 1;//那么arr[L2] = 2   arr[H2] = 3 ; L2 = H1 + 1 = 2 ; //H2 = L2 + gap - 1 < len ? L2 + gap - 1 : len - 1 = 3;這里寫個三目運算符主要是用來判斷L2+gap如果越界len的話,那么H2的下標值為len-1int i = 0;// 堆區申請來的空間brr存放數據的下標while (L2 < len)     //這塊為什么要L2 < len 呢 先想一下 如果用L1 H1的話 跑到后期 L2早就越界了導致左邊的白跑{					 //然后使用L2的時候可以保證右邊的數組最少取到一個值  使用H2的話會導致提前越界  導致有些數據不能成功排序while (L1 < H1 && L2 < H2){if (arr[L1] <= arr[L2]){brr[i++] = arr[L1++]; //這塊后置++的原因是先用再加 難以理解的話可以寫成下面這種/*brr[i] = arr[L1];i++, L1++;*/}else{brr[i++] = arr[L2++];}}while (L1 <= H1)//因為上面的內層while中是 "&&" 可能其中一項滿足 但是另外一項不滿足  因此退出了while循環 因此寫這么一句 {               //如果左邊還有數據  挪下來brr[i++] = arr[L1++];}while (L2 <= H2)//如果右邊組還有數據,挪下來{brr[i++] = arr[L2++];}L1 = H2 + 1;  //因為數據得遍歷完分組排序  這是在新的分好的數組中的左值與右值  與上面一毛一樣H1 = L1 + gap - 1;L2 = H1 + 1;H2 = L2 + gap - 1 < len ? L2 + gap - 1 : len - 1;}//這塊退出while就是右邊的arr中數組L2越界了(while(L2<len)) 此時右邊肯定沒有數據了//至于arr中左邊的數組還有沒有值  不確定再來個判斷while (L1 < len){brr[i++] = arr[L1++];}//然后再將brr中數組導入到arr中即可  for (int i = 0; i < len; i++){arr[i] = brr[i];}free(brr); //堆區空間的釋放
}void MergeSort(int *arr, int len) //這塊用了函數調用  當然你給上面那玩意寫到這個里面完全可以
{for(int i=1; i<len; i*=2)//首先來看假如數組有八位滿足不滿足條件 (2^3)<8不成立 也就是四四合并之后   就完成了合并  查看上面圖 滿足條件//再來看假如有10個值  (2^4)<10不成立   也就是八八合并之后  需要四次合并  查看上圖  滿足條件{Merge(arr, len, i); //調用函數主體   直接寫到這個循環中也完全ok}
}

主要就是H2的取值怎么取值和思路是重點那塊是重點!

“但凡辛苦,皆是禮物”

總結

以上是生活随笔為你收集整理的归并排序(代码注释超详细)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。