堆的插入删除实现和优化
来源:互联网 发布:淘宝商品怎么分类 编辑:程序博客网 时间:2024/05/16 08:51
堆的插入的时候实在树的最下面插入。例如
97 / \ 95 69 / \ / \ 65 67 26 26 / \ / \ / \ / \ 10 65 67
在该树中,插入一个新的数据的时候,是要在第四层67的右边插入假如插入的数据是96.那么此时不满足最大堆(最小堆)那么96比67大,所以96和67交换位置。96也比95大,所以96再次和95交换。此时96不必它的父节点97大,所以当前就是它应该存在的位置,最后得到新树
97 / \ 96 69 / \ / \ 65 95 26 26 / \ / \ / \ / \ 10 65 67 67
import java.util.*;import java.lang.*;// 在堆的有关操作中,需要比较堆中元素的大小,所以Item需要extends Comparablepublic class MaxHeap<Item extends Comparable> { protected Item[] data; protected int count; protected int capacity; // 构造函数, 构造一个空堆, 可容纳capacity个元素 public MaxHeap(int capacity){ data = (Item[])new Comparable[capacity+1]; count = 0; this.capacity = capacity; } // 返回堆中的元素个数 public int size(){ return count; } // 返回一个布尔值, 表示堆中是否为空 public boolean isEmpty(){ return count == 0; } // 像最大堆中插入一个新的元素 item public void insert(Item item){ assert count + 1 <= capacity; data[count+1] = item; count ++; shiftUp(count); } // 交换堆中索引为i和j的两个元素 private void swap(int i, int j){ Item t = data[i]; data[i] = data[j]; data[j] = t; } //******************** //* 最大堆核心辅助函数 //******************** private void shiftUp(int k){ while( k > 1 && data[k/2].compareTo(data[k]) < 0 ){ swap(k, k/2); k /= 2; } } // 测试 MaxHeap public static void main(String[] args) { MaxHeap<Integer> maxHeap = new MaxHeap<Integer>(100); int N = 50; // 堆中元素个数 int M = 100; // 堆中元素取值范围[0, M) for( int i = 0 ; i < N ; i ++ ) maxHeap.insert( new Integer((int)(Math.random() * M)) ); System.out.println(maxHeap.size()); }}
辅助类,用于打印出树的样子
也就是这样
The max heap size is: 31Data in the max heap: 98 81 97 74 78 80 53 50 63 68 61 56 71 37 47 1 45 33 56 6 62 48 17 9 51 1 31 0 2 12 44 98 / \ 81 97 / \ / \ 74 78 80 53 / \ / \ / \ / \ 50 63 68 61 56 71 37 47 / \ / \ / \ / \ / \ / \ / \ / \ 1 45 33 56 6 62 48 17 9 51 1 31 0 2 12 44
// 我们的PrintableMaxHeap只能处理整数信息,所以继承的是MaxHeap<Comparable<Integer>>public class PrintableMaxHeap extends MaxHeap<Comparable<Integer>>{ public PrintableMaxHeap(int capacity){ super(capacity); } // 以树状打印整个堆结构 public void treePrint(){ if( size() >= 100 ){ System.out.println("This print function can only work for less than 100 integer"); return; } System.out.println("The max heap size is: " + size()); System.out.println("Data in the max heap: "); for( int i = 1 ; i <= size() ; i ++ ){ // 我们的print函数要求堆中的所有整数在[0, 100)的范围内 assert (Integer)data[i] >= 0 && (Integer)data[i] < 100; System.out.print(data[i] + " "); } System.out.println(); System.out.println(); int n = size(); int maxLevel = 0; int numberPerLevel = 1; while( n > 0 ){ maxLevel += 1; n -= numberPerLevel; numberPerLevel *= 2; } int maxLevelNumber = (int)Math.pow(2, maxLevel-1); int curTreeMaxLevelNumber = maxLevelNumber; int index = 1; for( int level = 0 ; level < maxLevel ; level ++ ){ String line1 = new String(new char[maxLevelNumber*3-1]).replace('\0', ' '); int curLevelNumber = Math.min(count-(int)Math.pow(2,level)+1,(int)Math.pow(2,level)); boolean isLeft = true; for( int indexCurLevel = 0 ; indexCurLevel < curLevelNumber ; index ++ , indexCurLevel ++ ){ line1 = putNumberInLine( (Integer)data[index] , line1 , indexCurLevel , curTreeMaxLevelNumber*3-1 , isLeft ); isLeft = !isLeft; } System.out.println(line1); if( level == maxLevel - 1 ) break; String line2 = new String(new char[maxLevelNumber*3-1]).replace('\0', ' '); for( int indexCurLevel = 0 ; indexCurLevel < curLevelNumber ; indexCurLevel ++ ) line2 = putBranchInLine( line2 , indexCurLevel , curTreeMaxLevelNumber*3-1 ); System.out.println(line2); curTreeMaxLevelNumber /= 2; } } private String putNumberInLine( Integer num, String line, int indexCurLevel, int curTreeWidth, boolean isLeft){ int subTreeWidth = (curTreeWidth - 1) / 2; int offset = indexCurLevel * (curTreeWidth+1) + subTreeWidth; assert offset + 1 < line.length(); if( num >= 10 ) line = line.substring(0, offset+0) + num.toString() + line.substring(offset+2); else{ if( isLeft) line = line.substring(0, offset+0) + num.toString() + line.substring(offset+1); else line = line.substring(0, offset+1) + num.toString() + line.substring(offset+2); } return line; } private String putBranchInLine( String line, int indexCurLevel, int curTreeWidth){ int subTreeWidth = (curTreeWidth - 1) / 2; int subSubTreeWidth = (subTreeWidth - 1) / 2; int offsetLeft = indexCurLevel * (curTreeWidth+1) + subSubTreeWidth; assert offsetLeft + 1 < line.length(); int offsetRight = indexCurLevel * (curTreeWidth+1) + subTreeWidth + 1 + subSubTreeWidth; assert offsetRight < line.length(); line = line.substring(0, offsetLeft+1) + "/" + line.substring(offsetLeft+2); line = line.substring(0, offsetRight) + "\\" + line.substring(offsetRight+1); return line; } // 测试 PrintableMaxHeap public static void main(String[] args) { PrintableMaxHeap maxHeap = new PrintableMaxHeap(100); int N = 31; // 堆中元素个数 int M = 100; // 堆中元素取值范围[0, M) for( int i = 0 ; i < N ; i ++ ) maxHeap.insert( new Integer((int)(Math.random() * M)) ); maxHeap.treePrint(); }}
删除
import java.util.*;import java.lang.*;// 在堆的有关操作中,需要比较堆中元素的大小,所以Item需要extends Comparablepublic class MaxHeap<Item extends Comparable> { protected Item[] data; protected int count; protected int capacity; // 构造函数, 构造一个空堆, 可容纳capacity个元素 public MaxHeap(int capacity){ data = (Item[])new Comparable[capacity+1]; count = 0; this.capacity = capacity; } // 返回堆中的元素个数 public int size(){ return count; } // 返回一个布尔值, 表示堆中是否为空 public boolean isEmpty(){ return count == 0; } // 像最大堆中插入一个新的元素 item public void insert(Item item){ assert count + 1 <= capacity; data[count+1] = item; count ++; shiftUp(count); } // 从最大堆中取出堆顶元素, 即堆中所存储的最大数据 public Item extractMax(){ assert count > 0; Item ret = data[1]; swap( 1 , count ); count --; shiftDown(1); return ret; } // 获取最大堆中的堆顶元素 public Item getMax(){ assert( count > 0 ); return data[1]; } // 交换堆中索引为i和j的两个元素 private void swap(int i, int j){ Item t = data[i]; data[i] = data[j]; data[j] = t; } //******************** //* 最大堆核心辅助函数 //******************** private void shiftUp(int k){ while( k > 1 && data[k/2].compareTo(data[k]) < 0 ){ swap(k, k/2); k /= 2; } } private void shiftDown(int k){ while( 2*k <= count ){ int j = 2*k; // 在此轮循环中,data[k]和data[j]交换位置 if( j+1 <= count && data[j+1].compareTo(data[j]) > 0 ) j ++; // data[j] 是 data[2*k]和data[2*k+1]中的最大值 if( data[k].compareTo(data[j]) >= 0 ) break; swap(k, j); k = j; } } // 测试 MaxHeap public static void main(String[] args) { MaxHeap<Integer> maxHeap = new MaxHeap<Integer>(100); int N = 100; // 堆中元素个数 int M = 100; // 堆中元素取值范围[0, M) for( int i = 0 ; i < N ; i ++ ) maxHeap.insert( new Integer((int)(Math.random() * M)) ); Integer[] arr = new Integer[N]; // 将maxheap中的数据逐渐使用extractMax取出来 // 取出来的顺序应该是按照从大到小的顺序取出来的 for( int i = 0 ; i < N ; i ++ ){ arr[i] = maxHeap.extractMax(); System.out.print(arr[i] + " "); } System.out.println(); // 确保arr数组是从大到小排列的 for( int i = 1 ; i < N ; i ++ ) assert arr[i-1] >= arr[i]; }}
阅读全文
0 0
- 堆的插入删除实现和优化
- 堆插入和删除的简单实现
- 实现最大堆的插入和删除!
- 最小堆的调整、插入和删除
- 最大堆的插入,删除和初始化
- 最大堆的创建、插入和删除
- 堆的创建 插入和删除
- 最大堆的插入和删除
- 最大堆的插入和删除
- 最大堆的初始化、插入和删除
- java实现堆的操作(建堆,插入,删除)
- 堆的插入、删除和建立操作,堆排序
- 堆的插入、删除和建立操作,堆排序
- 最小堆的插入、删除和创建的C语言实现
- C++数据结构--用向量数组实现大(小)根堆的插入和删除
- 堆的创建、插入、删除,模板参数实现堆以及模板的模板参数实现堆
- 堆的建立, 元素插入, 删除的实现...
- 二叉堆的插入删除等操作C++实现
- 阿里成立达摩院预计3年投千亿,马云称它要活的比阿里更久
- 比较两个日期时间差
- Debian系统下安装Aria2
- 一、JSP九大内置对象
- imageloader
- 堆的插入删除实现和优化
- 2017年10月编程语言排行榜:Java持续下滑仍稳居第一,Swift正过时?
- 线性表练习(单链表)
- 程序员专属菜单
- Mybatis学习笔记-解决字段名与实体类属性名不相同的冲突
- 程序员,你的强迫症是几级?请对号入座!
- 京东全球首个全流程无人仓曝光:看完给跪了!
- 互联网公司Android面试题汇总
- 从 0 到 300,Instagram 创始人 CTO 分享工程团队成长的经验