算法學習:堆排序

  • 背景介紹:
    是指利用堆這種數據結構所設計的一種排序算法。堆積是一個近似完全二叉樹的結構,并同時滿足堆積的性質:即子結點的鍵值或索引總是小于(或者大于)它的父節點。

  • 算法規則:
    堆是具有下列性質的完全二叉樹:每個結點的值都大于或等于其左右孩子結點的值,稱為大頂堆;或者每個結點的值都小于或等于其左右孩子結點的值,稱為小頂堆。將待排序的序列構造成一個大頂堆。此時,整個序列的最大值就是堆頂的根節點。將它移走(其實就是將其與堆數組的末尾元素交換,此時末尾元素就是最大值),然后將剩余的n-1個序列重新構造成一個堆,這樣就會得到n個元素中的次最大值。如此反復執行,就能得到一個有序序列了。

  • 代碼實現(Java版本)

      /** 
       * 堆排序 
       */  
      private static void heapSort(int[] arr) {   
          // 將待排序的序列構建成一個大頂堆  
          for (int i = arr.length / 2; i >= 0; i--){   
              heapAdjust(arr, i, arr.length);   
          }  
        
          // 逐步將每個最大值的根節點與末尾元素交換,并且再調整二叉樹,使其成為大頂堆  
          for (int i = arr.length - 1; i > 0; i--) {   
              swap(arr, 0, i); // 將堆頂記錄和當前未經排序子序列的最后一個記錄交換  
              heapAdjust(arr, 0, i); // 交換之后,需要重新檢查堆是否符合大頂堆,不符合則要調整  
          }  
      }  
    
      /** 
       * 構建堆的過程 
       * @param arr 需要排序的數組 
       * @param i 需要構建堆的根節點的序號 
       * @param n 數組的長度 
      */  
      private static void heapAdjust(int[] arr, int i, int n) {  
          int child;  
          int father;   
          for (father = arr[i]; leftChild(i) < n; i = child) {  
              child = leftChild(i);  
            
              // 如果左子樹小于右子樹,則需要比較右子樹和父節點  
              if (child != n - 1 && arr[child] < arr[child + 1]) {  
                  child++; // 序號增1,指向右子樹  
              }  
                
              // 如果父節點小于孩子結點,則需要交換  
              if (father < arr[child]) {  
                  arr[i] = arr[child];  
              } else {  
                  break; // 大頂堆結構未被破壞,不需要調整  
              }  
          }  
          arr[i] = father;  
      }  
    
      // 獲取到左孩子結點  
      private static int leftChild(int i) {  
          return 2 * i + 1;  
      }  
        
      // 交換元素位置  
      private static void swap(int[] arr, int index1, int index2) {  
          int tmp = arr[index1];  
          arr[index1] = arr[index2];  
          arr[index2] = tmp;  
      }
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 排序算法是最基本最常用的算法,不同的排序算法在不同的場景或應用中會有不同的表現,我們需要對各種排序算法熟練才能將它...
    若丶天下閱讀 448評論 0 1
  • 概述 排序有內部排序和外部排序,內部排序是數據記錄在內存中進行排序,而外部排序是因排序的數據很大,一次不能容納全部...
    蟻前閱讀 5,223評論 0 52
  • 概述:排序有內部排序和外部排序,內部排序是數據記錄在內存中進行排序,而外部排序是因排序的數據很大,一次不能容納全部...
    每天刷兩次牙閱讀 3,747評論 0 15
  • 1. 第一種人:天才且努力的人,他們和平常人不同,極少迷茫,就算人生失意,也能很快恢復,他們注定成為人生贏家。 2...
    空白WYC閱讀 842評論 0 0
  • 女性進入青春期,開始月經來潮,性器官也開始逐漸發育完善,這個時期會發現一些之前存在的問題,也有月經來潮后出現的新問...
    三葉秋閱讀 9,867評論 2 112