查詢導致 C 語言中歸併排序最壞情況的排列


概念

對於給定的一組元素,確定這些元素的哪種排列會導致歸併排序的最壞情況?

我們知道,漸進地,歸併排序總是消耗 O(n log n) 時間,但是需要更多比較的情況在實踐中通常會消耗更多時間。現在我們基本上需要確定輸入元素的一種排列,這種排列在實現典型的歸併排序演算法時會導致最大數量的比較。

示例

將以下元素集視為已排序陣列:11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26

會導致歸併排序最壞情況的結果輸入陣列是:11 19 15 23 13 21 17 25 12 20 16 24 14 22 18 26

方法

我們研究如何為輸入集獲得歸併排序的最壞情況輸入?

現在我們嘗試自下而上構建陣列

現在假設已排序陣列為 {11, 12, 13, 14, 15, 16, 17, 18}。

現在為了構建歸併排序的最壞情況,導致上述已排序陣列的合併操作應產生最大的比較次數。因此,參與合併操作的左子陣列和右子陣列應儲存已排序陣列的交替元素,使得左子陣列為 {11, 13, 15, 17},右子陣列為 {12, 14, 16, 18}。因此,陣列的每個元素將至少比較一次,這將導致最大比較次數。現在我們也對左子陣列和右子陣列實現相同的邏輯。對於陣列 {11, 13, 15, 17},最壞情況是其左子陣列和右子陣列分別為 {11, 15} 和 {13, 17},而對於陣列 {12, 14, 16, 18},最壞情況將發生在 {12, 14} 和 {16, 18}。

完整演算法

GenerateWorstCase(arr[])

  • 現在我們建立兩個輔助陣列 left 和 right,並在其中儲存交替的陣列元素。

  • 我們呼叫左子陣列的 GenerateWorstCase - GenerateWorstCase (left)

  • 我們呼叫右子陣列的 GenerateWorstCase GenerateWorstCase (right)

  • 現在我們將左子陣列和右子陣列的所有元素複製回原始陣列。

示例

現場演示

// C program to generate Worst Case of Merge Sort
#include <stdlib.h>
#include <stdio.h>
// Indicates function to print an array
void printArray(int A1[], int size1){
   for (int i = 0; i < size1; i++)
      printf("%d ", A1[i]);
   printf("
"); } // Indicates function to join left and right subarray int join(int arr1[], int left1[], int right1[], int l1, int m1, int r1){    int i; // So used in second loop    for (i = 0; i <= m1 - l1; i++)       arr1[i] = left1[i];    for (int j = 0; j < r1 - m1; j++)       arr1[i + j] = right1[j]; } // Indicates function to store alternate elemets in left // and right subarray int split(int arr1[], int left1[], int right1[], int l1, int m1, int r1){    for (int i = 0; i <= m1 - l1; i++)       left1[i] = arr1[i * 2];    for (int i = 0; i < r1 - m1; i++)       right1[i] = arr1[i * 2 + 1]; } // Indicates function to generate Worst Case of Merge Sort int generateWorstCase(int arr1[], int l1, int r1){    if (l1 < r1){       int m1 = l1 + (r1 - l1) / 2;       // creating two auxillary arrays       int left1[m1 - l1 + 1];       int right1[r1 - m1];       // Storing alternate array elements in left       // and right subarray       split(arr1, left1, right1, l1, m1, r1);       // Recursing first and second halves       generateWorstCase(left1, l1, m1);       generateWorstCase(right1, m1 + 1, r1);       // joining left and right subarray       join(arr1, left1, right1, l1, m1, r1);    } } // Driver code int main(){    // Initializes sorted array    int arr1[] = { 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 };    int n1 = sizeof(arr1) / sizeof(arr1[0]);    printf("Sorted array is
");    printArray(arr1, n1);    // generating worst Case of Merge Sort    generateWorstCase(arr1, 0, n1 - 1);    printf("
Input array that will result in " "worst case of merge sort is
");    printArray(arr1, n1);    return 0; }

輸出

Sorted array is
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
Input array that will result in worst case of merge sort is
11 19 15 23 13 21 17 25 12 20 16 24 14 22 18 26

更新於:2020-7-23

249 次瀏覽

開啟您的職業生涯

完成課程後獲得認證

開始
廣告