原地歸併排序

2021-07-10 12:28:29 字數 1720 閱讀 3955

原地歸併排序相比於普通歸併排序,不需要開拓額外空間就可進行兩個有序陣列的merge,故空間複雜度為o(1)

無論是原地歸併排序還是普通歸排序 最外層的遞迴形式都是統一的,如下

void mergesort(int *arr,int low,int high)

}

下面首先給出普通的merge 函式,需要申請輔助陣列,現將待合併的兩個陣列都拷進去。

#define max_len 20

int b[max_len];

void merge(int *arr,int low,int

mid,int high)

while(i<=mid) arr[k++]=b[i++];

while(j<=high) arr[k++]=b[j++];

}

下面給出原地歸併排序中merge函式的原理介紹

i 往後移動,找到第乙個arr[i]>arr[j]的索引。如圖找到30

j往後一棟,找到第乙個arr[j]>arr[i]的索引。如圖找到55

交換i到index-1和index到j的部分,採用區域性陣列迴圈移動的方法,通過三次陣列逆序實現。交換後陣列前半部分區域性有序,之後重複進行此步驟即可實現兩個有序陣列的合併。

**如下:

void reverse(int *arr,int n)      //逆序操作

void merge(int *arr,int begin,int mid,int end)

exchange(arr+i,j-i,j-i-step);

i+=step;}}

附上完整的測試**

#include 

#include

#define max_len 20

int b[max_len];

void reverse(int *arr,int n) //逆序操作

}void exchange(int *arr,int n,int i) //將含有n個元素的陣列迴圈左移i個位置

//void merge(int *arr,int begin,int mid,int end)

////

// exchange(arr+i,j-i,j-i-step);

// i+=step;

// }

//}//

void merge(int *arr,int low,int mid,int high)

while(i<=mid) arr[k++]=b[i++];

while(j<=high) arr[k++]=b[j++];

}void mergesort(int *arr,int low,int high)

}int main(int argc, char

const *argv)

; int testbrr = ;

int len=sizeof(arr)/sizeof(arr[0]);

mergesort(arr,0,len-1);

for (int i=0;iprintf("%d ",arr[i]);

return

0;}

原地歸併排序

原地歸併排序 原地歸併排序不需要輔助陣列既可以歸併。關鍵在於merge函式。假設有兩段遞增的子陣列arr begin.mid 1 和arr mid.end 但是整個陣列不是遞增的。其中i begin,j mid,k end 第一步 i往後移動,找到第乙個arr i arr j 的索引,假設陣列元素如...

自頂向下的原地歸併排序

歸併排序是一種簡單的遞迴排序演算法。思路 歸併排序即是將兩個有序的陣列歸併成乙個更大的有序陣列。那麼我們要將乙個陣列排序,我們可以先將這個陣列分成兩半分別排序,然後將結果歸併起來。其 歸併排序的速度非常快,但是卻需要額外的空間。為什麼需要額外的空間尼?因為我們使用歸併排序時是將兩個不同的有序陣列歸併...

Java版 原地二路歸併排序

思想 先將原始陣列劃分為n個較小的子陣列,然後對每個子陣列兩兩進行排序並合併為乙個次子陣列 重複上述過程直到次子陣列的個數為1即為排序後的原始陣列 時間複雜度 o n logn 最好 壞情況 空間複雜度 o n 為了解決原始二路歸併排序空間複雜度較高的情況而產生的,思想很巧妙,很是佩服。它在將原始的...