标签:ges while 基础 学习 feed image 除了 两种 log
参考资料
二叉堆:一个堆有序的完全二叉树, 叫做二叉堆。
/** * @param a 表示堆的数组 * @param k 堆中的节点位置 */ private void swim (int [] a, int k) { while(k>1&&a[k]>a[k/2]){ // 当该结点存在父节点,且大于父节点的时候 exchange(a, k, k/2); // 交换它和它的父节点值 k = k/2; // 取得父节点的位置 } }
/** * @param a 表示堆的数组 * @param k 堆中的节点位置 * @param N 堆中节点总数 */ private void sink (int [] a, int k, int N) { while(2*k<=N) { // 当该节点存在至少一个子节点的时候 int j = 2*k; // 取得左儿子的位置 if(j<N&&a[j]<a[j+1]) { j++; } // 取得左儿子和右儿子中的较大者 if(a[k]<a[j]) { // 当该节点的值小于较大的左儿子的时候 exchange(a, k, j); // 交换它和该儿子节点的值 k = j; // 取得该儿子节点的位置 } else { break; } } }
/** * 向堆中插入值 * @param v 要插入的值 */ public void insert (int v) { a[N+1]= v; // 元素被放入堆的最末端成为新节点 N++; // 增加堆的大小 swim(N); // 对末端节点进行上浮操作使其有序 }
/** * 删除堆中的最大值, 并且将其返回 * @return 堆节点最大值 */ public int delMax () { if(isEmpty()) return 0; // 当堆为空时, 返回 int max = a[1]; // 取得堆中根节点(最大值) exchange(a, 1, N); // 交换根节点和末端节点(最后一个元素)的值 N--; // 减少堆的大小 (“删除”完毕) sink(1); // 下沉操作,让刚放上根节点的新元素下沉到合适的位置 return max; }
public class Heap { /** * N: 记录二叉堆中的节点总数 * a: 容纳二叉堆节点的数组,从a[0]开始存放 */ private int N = 0; private int [] a; /** * @param maxN 创建堆中节点的总数 */ public Heap (int maxN) { a = new int [maxN+1]; } private static void exchange(int [] a , int i, int j) { int temp = a[i]; a[i] = a[j]; a[j] = temp; } /** * 上浮操作 * @param k 堆中的节点位置 */ private void swim (int k) { while(k>1&&a[k]>a[k/2]){ // 当该结点存在父节点,且大于父节点的时候 exchange(a, k, k/2); // 交换它和它的父节点值 k = k/2; // 取得父节点的位置 } } /** * 下沉操作 * @param k 堆中的节点位置 */ private void sink ( int k ) { while(2*k<=N) { // 当该节点存在至少一个子节点的时候 int j = 2*k; // 取得左儿子的位置 if(j<N&&a[j]<a[j+1]) { j++; } // 取得左儿子和右儿子中的较大者 if(a[k]<a[j]) { // 当该节点的值小于较大的左儿子的时候 exchange(a, k, j); // 交换它和该儿子节点的值 k = j; // 取得该儿子节点的位置 } else { break; } } } /** * 向堆中插入值 * @param v 要插入的值 */ public void insert (int v) { a[N+1]= v; // 元素被放入堆的最末端成为新节点 N++; // 增加堆的大小 swim(N); // 对末端节点进行上浮操作使其有序 } /** * 删除堆中的最大值, 并且将其返回 * @return 堆节点最大值 */ public int delMax () { if(isEmpty()) return 0; // 当堆为空时, 返回 int max = a[1]; // 取得堆中根节点(最大值) exchange(a, 1, N); // 交换根节点和末端节点(最后一个元素)的值 N--; // 减少堆的大小 (“删除”完毕) sink(1); // 下沉操作,让刚放上根节点的新元素下沉到合适的位置 return max; } /** * 判断堆数组是否为空 */ public boolean isEmpty() { return N == 0; } }
public class Test { public static void main (String [] args) {
// 创建一个能容纳10个元素的堆 Heap heap = new Heap(10); int [] array = {2,6,3,9,1,5,4,3,0,2}; // 将数组元素依次放入堆中 for(int i =0; i<array.length;i++) { heap.insert(array[i]); } // 依次删除堆中的最大元素并输出 for(int i =0; i<array.length;i++) { System.out.println(heap.delMax()); } } }
9 6 5 4 3 3 2 2 1 0
int N = a.length; // 取得节点总数 for(int i=N/2;i>0; i--) { sink(a, i, N); // 对所有父节点,从最后一个父节点到根节点,依次下沉排序 }
把构造完毕(实现堆有序)之后,我们就要将“堆有序”的数组转化为“有序”的数组,这一阶段被称为下沉排序
while(N>1){ exchange(a, 1, N); // 将数组中最大的元素放到数组后端 N--; // 将最大的节点元素移出堆 sink(a, 1, N); // 下沉操作,再次实现堆有序 }
如图所示:
/** * 堆排序方法 * @param a 待排序数组 */ public static void sort(int [] a) { // 堆的构造阶段 int N = a.length; // 取得节点总数 for(int i=N/2;i>0; i--) { sink(a, i, N); // 对所有父节点,从最后一个父节点到根节点,依次下沉排序 } // 到这里数组已经完全堆有序
// 下沉排序阶段 while(N>1){ exchange(a, 1, N); // 将数组中最大的元素放到数组后端 N--; // 将最大的节点元素移出堆 sink(a, 1, N); // 下沉操作,再次实现堆有序 } }
/** * 交换两个数组元素的值 * 注意! 不同于一般的exchange, 这里的i和j要减1! */ private static void exchange(int [] a , int i, int j) { int temp = a[i-1]; a[i-1] = a[j-1]; a[j-1] = temp; } /** * 比较i和j下标的数组元素的大小 * 注意! 不同于一般的less, 这里的i和j要减1! */ private static boolean less (int [] a, int i, int j) { return a[i-1]-a[j-1]<0 ? true : false; }
public class HeapSort { /** * 交换两个数组元素的值 * 注意! 不同于一般的exchange, 这里的i和j要减1! */ private static void exchange(int [] a , int i, int j) { int temp = a[i-1]; a[i-1] = a[j-1]; a[j-1] = temp; } /** * 比较i和j下标的数组元素的大小 * 注意! 不同于一般的less, 这里的i和j要减1! */ private static boolean less (int [] a, int i, int j) { return a[i-1]-a[j-1]<0 ? true : false; } /** * 下沉操作 * @param a 待排序数组 * @param k 堆中的节点位置 * @param N 堆中的节点总数 */ private static void sink (int [] a, int k, int N) { while(2*k<=N) { // 当该节点存在至少一个子节点的时候 int j = 2*k; // 取得左儿子的位置 if(j<N&&less(a, j, j+1)) { j++; } // 取得左儿子和右儿子中的较大者 if(less(a, k, j)) { // 当该节点的值小于较大的左儿子的时候 exchange(a, k, j); // 交换它和该儿子节点的值 k = j; // 取得该儿子节点的位置 } else { break; } } } /** * 堆排序方法 * @param a 待排序数组 */ public static void sort(int [] a) { // 堆的构造阶段 int N = a.length; // 取得节点总数 for(int i=N/2;i>0; i--) { sink(a, i, N); // 对所有父节点,从最后一个父节点到根节点,依次下沉排序 } // 到这里数组已经完全堆有序 // 下沉排序阶段 while(N>1){ exchange(a, 1, N); // 将数组中最大的元素放到数组后端 N--; // 将最大的节点元素移出堆 sink(a, 1, N); // 下沉操作,再次实现堆有序 } } }
public class Test { public static void main (String [] args) { int [] array = {3,0,8,9,1,5,4,2,7,1,2}; HeapSort.sort(array); for(int i=0;i<array.length;i++) { System.out.println(array[i]); } } }
0 1 1 2 2 3 4 5 7 8 9
标签:ges while 基础 学习 feed image 除了 两种 log
原文地址:http://www.cnblogs.com/penghuwan/p/7894728.html