C#堆排序演算法

追逐時光者發表於2023-10-09

前言

堆排序是一種高效的排序演算法,基於二叉堆資料結構實現。它具有穩定性、時間複雜度為O(nlogn)和空間複雜度為O(1)的特點。

堆排序實現原理

  1. 構建最大堆:將待排序陣列構建成一個最大堆,即滿足父節點大於等於子節點的特性。
  2. 將堆頂元素與最後一個元素交換:將最大堆的堆頂元素與堆中的最後一個元素交換位置,將最大元素放到了陣列的末尾。
  3. 重新調整堆:對剩餘的n-1個元素進行堆調整,即將堆頂元素下沉,重新形成最大堆。
  4. 重複步驟2和3,直到堆中的所有元素都被排列好。

堆排序程式碼實現

        public static void HeapSort(int[] array)
        {
            int arrayLength = array.Length;

            //構建最大堆
            for (int i = arrayLength / 2 - 1; i >= 0; i--)
                Heapify(array, arrayLength, i);

            //依次取出堆頂元素,並重新調整堆
            for (int i = arrayLength - 1; i >= 0; i--)
            {
                //將堆頂元素與當前最後一個元素交換
                int temp = array[0];
                array[0] = array[i];
                array[i] = temp;

                //重新調整堆
                Heapify(array, i, 0);
            }
        }

        private static void Heapify(int[] arr, int n, int i)
        {
            int largest = i; //假設父節點最大
            int left = 2 * i + 1; //左子節點
            int right = 2 * i + 2; //右子節點

            //如果左子節點大於父節點,則更新最大值
            if (left < n && arr[left] > arr[largest])
                largest = left;

            //如果右子節點大於父節點和左子節點,則更新最大值
            if (right < n && arr[right] > arr[largest])
                largest = right;

            //如果最大值不是當前父節點,則交換父節點和最大值,並繼續向下調整堆
            if (largest != i)
            {
                int swap = arr[i];
                arr[i] = arr[largest];
                arr[largest] = swap;

                Heapify(arr, n, largest);
            }
        }

        public static void HeapSortRun()
        {
            int[] array = { 19, 27, 46, 48, 50, 2, 4, 44, 47, 36, 38, 15, 26, 5, 3, 99, 888, 0, -1 };
            Console.WriteLine("排序前陣列:" + string.Join(", ", array));

            HeapSort(array);

            Console.WriteLine("排序後陣列:" + string.Join(", ", array));
        }

執行結果

總結

堆排序是一種高效的排序演算法,透過構建最大堆和反覆調整堆的操作,實現對陣列的排序。其時間複雜度為O(nlogn),並且具有較好的穩定性和空間效率。但是由於其涉及大量的元素交換操作,所以在實際應用中,可能不如快速排序等演算法效率高。

相關文章