莊周夢(mèng)蝶

          生活、程序、未來(lái)
             :: 首頁(yè) ::  ::  :: 聚合  :: 管理
          1。概念:堆是一種特殊的二叉樹(shù),具備以下兩種性質(zhì)
          1)每個(gè)節(jié)點(diǎn)的值都大于(或者都小于,稱(chēng)為最小堆)其子節(jié)點(diǎn)的值
          2)樹(shù)是完全平衡的,并且最后一層的樹(shù)葉都在最左邊
          這樣就定義了一個(gè)最大堆。

          2。堆可以用一個(gè)數(shù)組表示,有如下性質(zhì):
          heap[i]>=heap[2*i+1]? 其中0<=i<=(n-1)/2
          heap[i]>=heap[2*i+2]? 其中0<=i<=(n-2)/2

          3。用數(shù)組實(shí)現(xiàn)堆,
          1)插入操作
          自頂向下,偽代碼:
          ??heapEnqueue(el)
          ??????將el放在堆尾
          ??????
          while?el不在根節(jié)點(diǎn)并且el>parent(el)
          ??????????交換el及其父節(jié)點(diǎn)

          自底向上,偽代碼:
          ?FloydAlgrithm(data[])
          ?????
          for?i=最后一個(gè)非葉節(jié)點(diǎn)的下標(biāo),i>=0;i--
          ??????調(diào)用moveDown(data,i,n
          -1)恢復(fù)以data[i]為根的樹(shù)的堆性質(zhì)
          ??
          2)moveDown的方法實(shí)現(xiàn),此方法是堆排序的關(guān)鍵,也是刪除操作的關(guān)鍵。刪除操作,將根節(jié)點(diǎn)刪除,并把最末的樹(shù)葉換到根節(jié)點(diǎn),通過(guò)moveDown方法找到正確的位置,恢復(fù)堆性質(zhì)。

          4。堆的一個(gè)實(shí)現(xiàn):
          // heap.java
          // demonstrates heaps
          // to run this program: C>java HeapApp
          import java.io.*;
          ////////////////////////////////////////////////////////////////
          class Node
          {
          private int iData; // data item (key)
          // -------------------------------------------------------------
          public Node(int key) // constructor
          { iData = key; }
          // -------------------------------------------------------------
          public int getKey()
          { return iData; }
          // -------------------------------------------------------------
          public void setKey(int id)
          { iData = id; }
          // -------------------------------------------------------------
          } // end class Node
          ////////////////////////////////////////////////////////////////
          class Heap
          {
          private Node[] heapArray;
          private int maxSize; // size of array
          private int currentSize; // number of nodes in array
          // -------------------------------------------------------------
          public Heap(int mx) // constructor
          {
          maxSize = mx;
          currentSize = 0;
          heapArray = new Node[maxSize]; // create array
          }
          // -------------------------------------------------------------
          public boolean isEmpty()
          { return currentSize==0; }
          // -------------------------------------------------------------
          public boolean insert(int key)
          {
          if(currentSize==maxSize)
          return false;
          Node newNode = new Node(key);
          heapArray[currentSize] = newNode;
          trickleUp(currentSize++);
          return true;
          } // end insert()
          // -------------------------------------------------------------
          public void trickleUp(int index)
          {
          int parent = (index-1) / 2;
          Node bottom = heapArray[index];

          while( index > 0 &&
          heapArray[parent].getKey() < bottom.getKey() )
          {
          heapArray[index] = heapArray[parent]; // move it down
          index = parent;
          parent = (parent-1) / 2;
          } // end while
          heapArray[index] = bottom;
          } // end trickleUp()
          // -------------------------------------------------------------
          public Node remove() // delete item with max key
          { // (assumes non-empty list)
          Node root = heapArray[0];
          heapArray[0] = heapArray[--currentSize];
          trickleDown(0);
          return root;
          } // end remove()
          // -------------------------------------------------------------
          public void trickleDown(int index)
          {
          int largerChild;
          Node top = heapArray[index]; // save root
          while(index < currentSize/2) // while node has at
          { // least one child,
          int leftChild = 2*index+1;
          int rightChild = leftChild+1;
          // find larger child
          if(rightChild < currentSize && // (rightChild exists?)
          heapArray[leftChild].getKey() <
          heapArray[rightChild].getKey())
          largerChild = rightChild;
          else
          largerChild = leftChild;
          // top >= largerChild?
          if( top.getKey() >= heapArray[largerChild].getKey() )
          break;
          // shift child up
          heapArray[index] = heapArray[largerChild];
          index = largerChild; // go down
          } // end while
          heapArray[index] = top; // root to index
          } // end trickleDown()
          // -------------------------------------------------------------
          public boolean change(int index, int newValue)
          {
          if(index<0 || index>=currentSize)
          return false;
          int oldValue = heapArray[index].getKey(); // remember old
          heapArray[index].setKey(newValue); // change to new

          if(oldValue < newValue) // if raised,
          trickleUp(index); // trickle it up
          else // if lowered,
          trickleDown(index); // trickle it down
          return true;
          } // end change()
          // -------------------------------------------------------------
          public void displayHeap()
          {
          System.out.print("heapArray: "); // array format
          for(int m=0; m<currentSize; m++)
          if(heapArray[m] != null)
          System.out.print( heapArray[m].getKey() + " ");
          else
          System.out.print( "-- ");
          System.out.println();
          // heap format
          int nBlanks = 32;
          int itemsPerRow = 1;
          int column = 0;
          int j = 0; // current item
          String dots = "...............................";
          System.out.println(dots+dots); // dotted top line

          while(currentSize > 0) // for each heap item
          {
          if(column == 0) // first item in row?
          for(int k=0; k<nBlanks; k++) // preceding blanks
          System.out.print(' ');
          // display item
          System.out.print(heapArray[j].getKey());

          if(++j == currentSize) // done?
          break;

          if(++column==itemsPerRow) // end of row?
          {
          nBlanks /= 2; // half the blanks
          itemsPerRow *= 2; // twice the items
          column = 0; // start over on
          System.out.println(); // new row
          }
          else // next item on row
          for(int k=0; k<nBlanks*2-2; k++)
          System.out.print(' '); // interim blanks
          } // end for
          System.out.println("/n"+dots+dots); // dotted bottom line
          } // end displayHeap()
          // -------------------------------------------------------------
          } // end class Heap
          ////////////////////////////////////////////////////////////////
          class HeapApp
          {
          public static void main(String[] args) throws IOException
          {
          int value, value2;
          Heap theHeap = new Heap(31); // make a Heap; max size 31
          boolean success;

          theHeap.insert(70); // insert 10 items
          theHeap.insert(40);
          theHeap.insert(50);
          theHeap.insert(20);
          theHeap.insert(60);
          theHeap.insert(100);
          theHeap.insert(80);
          theHeap.insert(30);
          theHeap.insert(10);
          theHeap.insert(90);

          while(true) // until [Ctrl]-[C]
          {
          System.out.print("Enter first letter of ");
          System.out.print("show, insert, remove, change: ");
          int choice = getChar();
          switch(choice)
          {
          case 's': // show
          theHeap.displayHeap();
          break;
          case 'i': // insert
          System.out.print("Enter value to insert: ");
          value = getInt();
          success = theHeap.insert(value);
          if( !success )
          System.out.println("Can't insert; heap full");
          break;
          case 'r': // remove
          if( !theHeap.isEmpty() )
          theHeap.remove();
          else
          System.out.println("Can't remove; heap empty");
          break;
          case 'c': // change
          System.out.print("Enter current index of item: ");
          value = getInt();
          System.out.print("Enter new key: ");
          value2 = getInt();
          success = theHeap.change(value, value2);
          if( !success )
          System.out.println("Invalid index");
          break;
          default:
          System.out.println("Invalid entry/n");
          } // end switch
          } // end while
          } // end main()
          //-------------------------------------------------------------
          public static String getString() throws IOException
          {
          InputStreamReader isr = new InputStreamReader(System.in);
          BufferedReader br = new BufferedReader(isr);
          String s = br.readLine();
          return s;
          }
          //-------------------------------------------------------------
          public static char getChar() throws IOException
          {
          String s = getString();
          return s.charAt(0);
          }
          //-------------------------------------------------------------
          public static int getInt() throws IOException
          {
          String s = getString();
          return Integer.parseInt(s);
          }
          //-------------------------------------------------------------
          } // end class HeapApp
          ////////////////////////////////////////////////////////////////

          評(píng)論

          # re: 數(shù)據(jù)結(jié)構(gòu)之堆   回復(fù)  更多評(píng)論   

          2008-01-05 19:31 by geochenyj
          寫(xiě)得不錯(cuò)
          主站蜘蛛池模板: 浮山县| 郧西县| 务川| 灌阳县| 河曲县| 湘西| 从化市| 鄄城县| 望都县| 阿城市| 项城市| 军事| 天津市| 蓬莱市| 蒲江县| 贵州省| 宜宾县| 同仁县| 西青区| 双柏县| 庆城县| 南川市| 泸溪县| 漳平市| 马边| 马关县| 宁德市| 称多县| 商水县| 博客| 长沙县| 当阳市| 呼伦贝尔市| 江陵县| 富裕县| 长汀县| 天等县| 扶余县| 安阳县| 綦江县| 平凉市|