基于树的堆移除根节点实现排序
2015-10-23 17:05
411 查看
基于树的堆移除根节点也可以实现排序
package org.exam.ch12.sort; /** * Created by xin on 15.10.17. */ class Node{ private int key; public Node() { } public Node(int key) { this.key = key; } public int getKey() { return key; } public void setKey(int key) { this.key = key; } } class Heap{ private Node[] arr; private int currentSize; private int maxSize; public Heap(int maxSize) { this.maxSize = maxSize; arr=new Node[maxSize]; } public boolean isEmpty(){ return currentSize==0; } public void insert(int key){ arr[currentSize++]=new Node(key); } public void toBeHeap(){ for (int i = currentSize/2-1; i>=0 ; i--) { trickleDown(i); } } public void sort(){ for (int i = currentSize-1; i >=0 ; i--) { int key=remove().getKey(); arr[i]=new Node(key);//这里不要用arr[i].setKey(key).因为arr[i]可能会与其它数组元素(比如arr[0])共同引用同一个节点.所以改变节点时,arr[0]也是指同这个节点,这样看起来,它也变了. } } public Node remove(){//每次只删除根节点(根节点数据是最大的),并将根节点返回 Node root=arr[0]; arr[0]=arr[--currentSize];//将arr[0]指向最后一个节点,看起来就是将最后一个节点变成根节点. trickleDown(0); return root;//将删除的根节点返回 } private void trickleUp(int index) { Node bottom=arr[index];//先缓存此节点 int parent=(index-1)/2;//由子获取父索引 while (index>0&&arr[parent].getKey()<bottom.getKey()){ arr[index]=arr[parent];//将arr[index]指向arr[parent]的指向的节点 index=parent; parent=(parent-1)/2;//这两步为改为下次的arr[index]将准备 } arr[index]=bottom;//最后将arr[index]指向原先缓存的节点 } private void trickleDown(int index) { Node top=arr[index];//先缓存此节点 int largerChild;//将父节点,左右子节点三者比较,用于临时保存 while (index<currentSize/2){//当到达最后一层,当然不用交换 int leftChild=2*index+1; int rightChild=leftChild+1; if (rightChild<currentSize&&arr[leftChild].getKey()<arr[rightChild].getKey()){//先比较左右子节点 largerChild=rightChild; }else{ largerChild=leftChild; } if (top.getKey()>=arr[largerChild].getKey()){ break;//如果父节点不小于子节点,就退出循环. } arr[index]=arr[largerChild];//将arr[index]指向arr[largerChild]指向的节点 index=largerChild;//为下次交换做准备 } arr[index]=top; } public void displayArray(){ System.out.println("Heap Array:"); for (int i = 0; i < maxSize; i++) { if (arr[i]!=null){ System.out.print(arr[i].getKey() + " "); }else{ System.out.print("--"); } } System.out.println(); } public void displayHeap() { 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(arr[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 } } public class HeadSortApp { public static void main(String[] args) { int maxSize=15; Heap heap=new Heap(maxSize); for (int i = 0; i < maxSize; i++) { int key= (int) (Math.random()*100); heap.insert(key); } heap.displayHeap(); heap.toBeHeap(); heap.displayHeap(); heap.sort(); heap.displayArray(); } }
相关文章推荐
- 文件遍历排序函数
- C#选择排序法实例分析
- C#插入法排序算法实例分析
- C#实现Datatable排序的方法
- SQLSERVER的排序问题结果不是想要的
- Windows Powershell排序和分组管道结果
- C#通过IComparable实现ListT.sort()排序
- C#选择法排序实例分析
- SQL学习笔记四 聚合函数、排序方法
- C#对list列表进行随机排序的方法
- 一根网线内的8根线哪4根是传输数据的,哪四根是防干扰的
- C#折半插入排序算法实现方法
- SQL进行排序、分组、统计的10个新技巧分享
- C++实现位图排序实例
- 基于C++实现的各种内部排序算法汇总
- C++线性时间的排序算法分析
- SQL行号排序和分页(SQL查询中插入行号 自定义分页的另类实现)
- PHP下对数组进行排序的函数
- PHP数组排序之sort、asort与ksort用法实例
- php通过asort()给关联数组按照值排序的方法