<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      基礎排序算法(四)堆排序

      一 堆排序

      堆排序是一種非常高效且獨特的排序算法,它巧妙地將數據結構中的“堆”應用于排序過程。

      1.1 特性介紹

      堆排序特性總結

      特性 說明
      核心思想 利用這種數據結構進行選擇排序。將待排序列構造成一個大頂堆(或小頂堆),從而不斷將堆頂元素(最大值或最小值)與序列末尾元素交換,并調整堆結構,最終得到有序序列
      時間復雜度 建堆:O(n);排序過程:O(n log n)。總體時間復雜度為 O(n log n),且最好、最壞、平均情況均如此
      空間復雜度 O(1),是原地排序算法,只需要常數級別的額外空間用于元素交換
      穩定性 不穩定。因交換堆頂和末尾元素時,可能改變相等元素的原始相對順序
      主要優勢 時間復雜度穩定,不會出現像快速排序那樣的最壞O(n2)情況;原地排序,空間效率高
      主要劣勢 常數因子較大,通常比平均情況下的快速排序慢;對小規模數據排序效率相對不高;不穩定

      1.2 算法工作原理

      堆排序的運作過程清晰地分為“建堆”和“排序”兩大階段。下圖以數組 [12, 11, 13, 5, 6, 7]為例,展示了構建大頂堆以及后續排序的關鍵步驟:
      圖片

      1.2.1 構建堆(Heapify)??

      這是堆排序的第一步,目標是將一個無序的完全二叉樹調整成一個??大頂堆??(對于升序排序)。大頂堆的性質是:每個節點的值都??大于或等于??其左右子節點的值。

      • 通常從??最后一個非葉子節點??開始(索引為 n/2 - 1,其中 n是數組長度),依次向前遍歷每個非葉子節點。
      • 對每個非葉子節點,執行“向下調整”操作:比較該節點與其左右子節點的值,如果子節點中有值更大的,則交換它們的位置,并遞歸地對被交換的子節點進行同樣的調整,確保以該節點為根的子樹滿足堆的性質。

      1.2.2 排序??

      一旦大頂堆構建完成,堆頂元素(根節點)就是整個序列中的最大值。

      • 交換與調整??:將堆頂元素與堆中最后一個元素交換。此時,最大值就位于數組的末尾,可以視為已排序部分。
      • 縮小堆范圍??:將堆的大小減一(即忽略最后一個已排序的元素)。
      • ??重新調整堆??:由于新的堆頂元素可能破壞堆的性質,因此需要對剩余的未排序序列(從新的根節點開始)再次進行向下調整,使其重新成為大頂堆。
      • 重復上述“交換-調整-縮小”步驟,直到堆的大小變為1,此時整個數組就有序了。

      1.3 復雜度分析

      1.3.1 時間復雜度 O(n log n) 的由來??:

      • ??建堆階段??:雖然需要調整n/2個節點,但由于二叉樹的結構特性,大部分調整操作在較低的層進行。建堆操作的時間復雜度經分析為 ??O(n)??。
      • ??排序階段??:需要進行n-1次交換和調整。每次調整堆(向下調整)的時間復雜度與當前堆的高度相關,即 ??O(log n)??。因此,排序階段的總時間復雜度為 ??O(n log n)??。
        堆排序的整體時間復雜度為 ??O(n log n)??,并且這個性能在最好、最壞和平均情況下都保持一致,非常穩定。

      1.3.2 ??空間復雜度 O(1) 的由來??:

      堆排序的所有操作(交換、調整)都是在原數組上進行的,只需要固定數量的額外變量(如用于交換的臨時變量 temp),因此是??原地排序??,空間復雜度為 ??O(1)??。

      1.4 使用場景

      堆排序在以下場景中表現出色:

      ??需要穩定的最壞情況性能??:當無法承受快速排序最壞情況下O(n2)的時間復雜度時,堆排序的O(n log n)最壞情況性能是可靠的選擇。
      ??內存空間受限??:由于是原地排序,空間復雜度為O(1),非常適合嵌入式系統等內存緊張的環境。
      ??尋找Top K元素??:不需要完全排序整個序列,只需找出最大或最小的K個元素。可以構建一個大小為K的小頂堆(找最大K個)或大頂堆(找最小K個),然后遍歷剩余元素進行調整,效率很高。
      ??實時數據流處理??:堆結構適合處理不斷產生新數據的場景,可以動態維護當前數據的極值或特定順序。

      然而,對于??小規模數據??,簡單排序如??插入排序??可能因常數因子更小而實際更快。若??需要穩定性??(保持相等元素的原始順序),則應選擇??歸并排序??等穩定算法。

      1.5 代碼實現

      1.5.1 c 語言實現

      以下是堆排序的一個典型C語言實現,包含了關鍵的堆調整(heapify)函數和排序主函數。

      #include <stdio.h>
      
      // 交換數組中兩個元素的值
      void swap(int *a, int *b) {
          int temp = *a;
          *a = *b;
          *b = temp;
      }
      
      // 堆調整函數(大頂堆)
      // arr: 待調整的數組
      // n: 當前堆的大小(即需要調整的數組長度)
      // i: 待調整的根節點索引
      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) {
              swap(&arr[i], &arr[largest]);
              heapify(arr, n, largest); // 遞歸調整受影響的子樹
          }
      }
      
      // 堆排序主函數
      void heapSort(int arr[], int n) {
          // 1. 構建初始大頂堆
          // 從最后一個非葉子節點開始向上調整
          for (int i = n / 2 - 1; i >= 0; i--)
              heapify(arr, n, i);
      
          // 2. 逐個從堆頂提取元素
          for (int i = n - 1; i > 0; i--) {
              // 將當前堆頂元素(最大值)與末尾元素交換
              swap(&arr[0], &arr[i]);
              // 交換后,調整剩余的元素(從0到i-1),使其重新成為大頂堆
              heapify(arr, i, 0);
          }
      }
      
      // 打印數組函數
      void printArray(int arr[], int n) {
          for (int i = 0; i < n; i++)
              printf("%d ", arr[i]);
          printf("\n");
      }
      
      // 主函數測試
      int main() {
          int arr[] = {12, 11, 13, 5, 6, 7};
          int n = sizeof(arr) / sizeof(arr[0]);
      
          printf("排序前的數組: \n");
          printArray(arr, n);
      
          heapSort(arr, n);
      
          printf("排序后的數組: \n");
          printArray(arr, n);
          return 0;
      }
      

      1.5.2 關鍵點解釋

      • heapify函數:這是堆排序的核心。它確保以節點 i為根的子樹滿足大頂堆的性質。通過比較根節點與其左右子節點,找到最大值,并在需要時進行交換和遞歸調整。
      • heapSort函數:
        • ??建堆循環??:for (int i = n / 2 - 1; i >= 0; i--)從最后一個非葉子節點開始,自底向上地調用 heapify,最終構建出整個大頂堆。
        • ?排序循環??:for (int i = n - 1; i > 0; i--)每次循環將堆頂(最大值)與當前未排序序列的最后一個元素交換,然后對新的堆頂調用 heapify來調整剩余元素,使其恢復成大頂堆。

      1.6 與常見排序算法比較

      排序算法比較

      算法 平均時間復雜度 最壞時間復雜度 空間復雜度 穩定性 主要特點與適用場景
      堆排序 O(n log n) O(n log n) O(1) 不穩定 最壞性能穩定,原地排序,適合內存受限和需要穩定最壞情況性能的場景
      快速排序 O(n log n) O(n2) O(log n) 不穩定 平均性能極佳,是許多標準庫的實現選擇,但對初始數據敏感,最壞情況性能差
      歸并排序 O(n log n) O(n log n) O(n) 穩定 性能穩定,是穩定的O(n log n)排序,但需要O(n)額外空間,適合外部排序和對穩定性有要求的場景
      插入排序 O(n2) O(n2) O(1) 穩定 對小規模或基本有序數據效率很高,常作為快速排序或歸并排序的輔助排序

      1.7 總結

      總的來說,堆排序是一種基于??堆數據結構??的高效排序算法,其??時間復雜度穩定在O(n log n)??,并且是??原地排序??,空間復雜度為O(1)。雖然在實際應用中可能不如快速排序快速,且是??不穩定??排序,但在??需要保證最壞情況性能、內存空間有限或需要解決Top K問題??等特定場景下,它依然是一個非常有價值的選擇。理解堆排序對于深入掌握數據結構和算法設計思想具有重要意義。

      posted on 2025-10-31 11:33  weiwei2021  閱讀(3)  評論(0)    收藏  舉報

      主站蜘蛛池模板: 香蕉av777xxx色综合一区| 四虎永久在线精品免费播放| 国产一二三五区不在卡| 亚洲人成网站999久久久综合| 国产精品香港三级国产av| 日本一区二区三区激情视频| 亚洲国产一区二区三区| 亚洲天堂精品一区二区| 久久五月丁香激情综合| 欧美级特黄aaaaaa片| 丰满少妇内射一区| 亚洲欧洲日产国码久在线| 久久九九日本韩国精品| 九九热视频精选在线播放| 日韩AV高清在线看片| 狠狠躁夜夜躁无码中文字幕| 亚洲一区二区三区在线观看精品中文 | 久久精品国产亚洲av麻豆小说| 成年午夜性影院| 亚洲中文字幕精品一区二区三区 | 国产精品办公室沙发| 亚洲an日韩专区在线| 国产精品福利自产拍久久| 綦江县| 大香伊蕉在人线国产最新2005| 亚洲高潮喷水无码AV电影| 日本深夜福利在线观看| 狠狠躁夜夜躁人人爽天天古典 | 一级女性全黄久久生活片| 精品国产乱码久久久久夜深人妻 | 男女裸体影院高潮| 国产99在线 | 免费| 做暖暖视频在线看片免费| 国产精品中文字幕二区| 久热这里只精品视频99| 日本三级香港三级人妇99| 亚洲国产成人精品无色码| 亚洲国产成人综合精品| 激情伊人五月天久久综合| 欧美极品色午夜在线视频| 久久99精品久久久久久9|