演算法筆記005:堆排序【變治法】

來源:互聯網
上載者:User

標籤:演算法   com   play   log   系統   alt   max   system   family   

目錄

1 問題描述 

2 解決方案 

2.1  堆排序原理簡介 

2.2  變治法原理簡介 

2.3  具體編碼 

2.4  運行結果 

 

1 問題描述(1)實驗題目

   用基於變治法的堆排序演算法對任意一組給定的資料進行排序

(2)實驗目的

   1)深刻理解並掌握變治法的設計思想;

   2)掌握堆的概念以及如何用變治法把任意給定的一組資料改變成堆;

   3)提高應用變治法設計演算法的技能。

(3)實驗要求

   1)設計與實現堆排序演算法;

   2)待排序的資料可以手工輸入(通常規模比較小,10個資料左右),用以檢測程式的正確性;也可以電腦隨機產生(通常規模比較大,1500-3000個資料左右),用以檢驗(用計數法)堆排序演算法的時間效率。

 

2 解決方案2.1  堆排序原理簡介

堆可以定義為一顆二叉樹,樹的節點中包含鍵(每個節點是一個鍵),並且滿足下面兩個條件:

(1)樹的形狀要求——這顆二叉樹是基本完備的(或者簡稱為完成二叉樹),這意味著,樹的每一層都是滿的,除了最後一層最右邊的元素有可能缺位。

(2)父母優勢要求,又稱為堆特性——每一個節點的鍵都要大於或等於它子女的鍵(對於任何孩子節點也要自動滿足父母優勢要求)。

2.2  變治法原理簡介

變治法:首先,在“變”的階段,出於這一或者那樣的原因,把問題的執行個體變得更容易求解(PS:類似本文求解問題,在排序前先把數組中數進行成堆處理);然後,在第二階段或者說“治”的階段,對執行個體進行求解。

根據我們對問題執行個體的變換方式,變治思想有3種主要的類型:

(1)變換為同樣問題的一個更簡單或者更方便的執行個體——我們稱之為執行個體化簡;

(2)變換為同樣執行個體的不同表現——我們稱之為改變表現;

(3)變換為另一個問題的執行個體,這種問題的演算法是已知的——我們稱之為問題的化簡。

2.3  具體編碼
package com.liuzhen.heapsort;public class HeapSort {    /*將array[a]和array[b]、array[c]中最大值進行比較,如果較小則將array[a]與array[b]、array[c]中最大值    進行交換,否則直接返回數組array*/    public static int[] getMaxA(int[] array,int a,int b ,int c){        int temp = 0;        if(array[b] >= array[c]){            if(array[a] < array[b]){                temp = array[a];                array[a] = array[b];                array[b] = temp;            }        }        else{            if(array[a] < array[c]){                temp = array[a];                array[a] = array[c];                array[c] = temp;            }        }        return array;    }        //根據堆排序父母優勢規則,返回一個給定長度的數組的成堆結果    public static int[] getHeapSort(int[] array , int len){        boolean judge = true;        while(judge){            //根據堆排序父母優先規則,對數組array進行排序            for(int i = 1;i <= len/2;i++){               if((2*i+1) < len)                      array = getMaxA(array,i,(2*i),(2*i+1));               if((2*i) == len-1){    //當2*i == len-1時,說明array[i]只有一個左孩子節點a[2*i]                   int temp = 0;                   if(array[i] < array[2*i]){                       temp = array[i];                       array[i] = array[2*i];                       array[2*i] = temp;                   }               }            }                        //遍曆數組array,一旦出現根節點小於其葉子節點時,跳出for迴圈            int j;            for(j = 1;j < len/2;j++){                if((2*j+1) < len){                    if(array[j] < array[2*j])                        break;                    if(array[j] < array[2*j+1])                        break;                }                if((2*j) == len-1){                    if(array[j] < array[2*j])                        break;                }            }                        if(j == len/2)  //如果j==len/2,說明遍曆結果符合堆定序,直接結束while迴圈                judge = false;        }                return array;    }        //使用數組成堆,對一個數組元素進行從小到大排序,並返回排序後的結果    public static int[] getResultSort(int[] array , int len){        array =  getHeapSort(array , len);           //首先對數組進行堆排序處理        int temp = 0;        //數組值交換中間變數        int sortLen = len;   //排序過程中,需要重新進行堆排序的數組長度,並初始化為array的總長度        while(sortLen > 2){    //            for(int i = 1;i < len;i++)//                System.out.print(array[i]+"\t");//            System.out.println();            temp = array[1];             //交換array[0]和array[sortLen-1]的值,即把最大的值放在未排序的數組最後一位            array[1] = array[sortLen-1];            array[sortLen-1] = temp;                        sortLen = sortLen - 1;                   //交換成功後,未排序的數組長度自動減1                        array = getHeapSort(array,sortLen);      //對未排序的數組,重新進行堆排序                }                return array;    }        //初始化一個長度為n的隨機數組    public static int[] initArray(int n){        int[] result = new int[n];        result[0] = 0;        for(int i = 1;i < n;i++)            result[i] = (int)(Math.random()*1000); //採用隨機函數隨機產生0~1000之間的數        return result;            }        public static void main(String args[]){        int[] array = {0,1,4,5,3,5,23,45,12,23,34,56,78,23,24,25}; //此處定義數組,對array[1]到array[len-1]進行排序        int len = array.length;        int[] result = getResultSort(array,len);        System.out.println("手動輸入數組,使用堆排序,最終排序結果:");        for(int i = 1;i < len;i++){            System.out.print(result[i]+"\t");        }                System.out.println();        System.out.println();        int[] oneArray = initArray(1000);        int len1 = 1000;        int[] result1 = getResultSort(oneArray,len1);        System.out.println("系統隨機產生的長度為1000的數組(其值均在0~1000之間),使用堆排序,最終排序結果:");        for(int j = 1;j < len1;j++){            System.out.print(result1[j]+"\t");            if(j%15 == 0)                System.out.println();        }        }}
2.4  運行結果

 

演算法筆記005:堆排序【變治法】

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.