设计一个没有扩容负担的堆结构
来源:互联网 发布:dns 默认端口 编辑:程序博客网 时间:2024/06/08 19:54
import java.util.Comparator;/** * Created by lxw, liwei4939@126.com on 2017/11/4. * 设计一个没有扩容负担的堆结构 */class Node{ public int value; public Node left; public Node right; public Node parent; public Node(int data){ this.value = data; }}public class myHeap { private Node head; // 堆头结点 private Node last; // 堆尾结点 private long size; // 堆的大小 private Comparator<Integer> comp; // 大根堆或小根堆 public myHeap(Comparator<Integer> compare){ head = null; last = null; size = 0; comp = compare; } public int getHead(){ return head == null ? null : head.value; } public long getSize(){ return size; } public boolean isEmpty(){ return size == 0 ? true : false; } // 添加一个新节点到堆中 public void add(int value){ Node newNode = new Node(value); if(size ==0){ head = newNode; last = newNode; size++; return; } Node node = last; Node parent = node.parent; // 找到正确的位置,插入到新节点 while (parent != null && node != parent.left){ node = parent; parent = node.parent; } Node nodeToAdd = null; if(parent == null){ nodeToAdd =mostLeft(head); nodeToAdd.left = newNode; newNode.parent = nodeToAdd; } else if(parent.right == null){ parent.right = newNode; newNode.parent = parent; } else { nodeToAdd = mostLeft(parent.right); nodeToAdd.left = newNode; newNode.parent = nodeToAdd; } last = newNode; // 建堆及其调整 heapInsertModify(); size++; } // 建堆和调整的过程 private void heapInsertModify(){ Node node = last; Node parent = node.parent; if(parent != null && comp.compare(node.value, parent.value) < 0){ last = parent; } while (parent != null && comp.compare(node.value, parent.value) < 0){ swapClosedTwoNodes(node, parent); parent = node.parent; } if(head.parent != null){ head = head.parent; } } // 堆heapify过程 private void heapify(Node node){ Node left = node.left; Node right = node.right; Node most = node; while (left != null){ if(left != null && comp.compare(left.value, most.value) < 0){ most = left; } if(right != null && comp.compare(right.value, most.value) < 0){ most = right; } if(most != node){ swapClosedTwoNodes(most, node); } else { break; } left = node.left; right = node.right; most = node; } if(node.parent == last){ last = node; } while (node.parent != null){ node = node.parent; } head = node; } //交换两个相近的结点 private void swapClosedTwoNodes(Node node, Node parent){ if(node == null || parent == null){ return; } Node parentparent = parent.parent; Node parentLeft = parent.left; Node parentRight = parent.right; Node nodeLeft = node.left; Node nodeRight = node.right; node.parent =parentparent; if(parentparent != null){ if(parent == parentparent.left){ parentparent.left = node; } else { parentparent.right = node; } } if(nodeLeft != null){ nodeLeft.parent = parent; } if(nodeRight != null){ nodeRight.parent = parent; } parent.parent = node; parent.left = nodeLeft; parent.right = nodeRight; if(node == parent.left){ node.left = parent; node.right = parentRight; if(parentRight != null){ parentRight.parent = node; } } else { node.left = parentLeft; node.right = parent; if(parentLeft != null){ parentLeft.parent = parent; } } } // 找到以node为头的子树中,最左的结点 private Node mostLeft(Node node){ while (node.left !=null){ node = node.left; } return node; } public int popHead(){ if(size == 0){ return 0; } Node res = head; if(size == 1){ head = null; last = null; size--; return res.value; } Node oldLast = popLastAndSetPrevoiusLast(); // 若弹出堆尾结点后,堆大小为1 if(size ==1){ head = oldLast; last = oldLast; return res.value; } // 若弹出堆结点后,堆大小大于1 Node headLeft = res.left; Node headRight = res.right; oldLast.left = headLeft; if(headLeft != null){ headLeft.parent = oldLast; } oldLast.right = headRight; if(headRight != null){ headRight.parent = oldLast; } res.left = null; res.right = null; head = oldLast; // 堆heapify过程 heapify(oldLast); return res.value; } // 在树中弹出堆尾结点,找到倒数第二个结点设置为新的堆尾结点 private Node popLastAndSetPrevoiusLast(){ Node node = last; Node parent =node.parent; while (parent != null && node != parent.right){ node = parent; parent = node.parent; } if(parent == null){ node = last; parent = node.parent; node.parent = null; if(node == parent.left){ parent.left = null; } else { parent.right = null; } last = mostRight(head); } else { Node newlast = mostRight(parent.left); node =last; parent = node.parent; node.parent = null; if(node == parent.left){ parent.left = null; } else { parent.right = null; } last = newlast; } size--; return node; } // 找到以node为头的子树中,最右的节点 private Node mostRight(Node node){ while (node.right != null){ node = node.right; } return node; } }
阅读全文
0 0
- 设计一个没有扩容负担的堆结构
- 其他题目---设计一个没有扩容负担的堆结构
- 机器语言才是最简单,最没有心理负担的语言
- 微信公号“架构师之路”学习笔记(五)-数据库扩展性架构设计(水平切分,秒级扩容,平滑迁移,在线表结构变更,一个大数据量多属性高并发的数据库设计等)
- 数据结构之队列(设计并实现一个自己的队列:循环数组+扩容策略)
- 微信已成马化腾甜蜜的负担
- 椭圆的负担
- 堆结构的实现
- 堆结构的运用
- 【模板】堆的结构
- 设计模式六大原则: 老板是如何减轻负担的 -- 依赖倒置原则
- 第六篇: 设计模式六大原则: 老板是如何减轻负担的 -- 依赖倒置原则
- MYSQL 匿名帐号的负担
- 【转】卸下“完美”的负担
- 建立一个堆结构heap-build
- 自己实现的堆结构
- Heap---堆的基本结构
- 用数组实现一个简单的heap(最大堆)结构
- java作业
- 内存取证——volatility
- Android手机动态获取权限
- 译OpenCms-10.5.3—— 1. 背景话题【Background topics】
- 实验四 队列的基本操作
- 设计一个没有扩容负担的堆结构
- P5-C开发笔试题三道
- List集合删除元素的时候删除不掉
- HTTP表单怎么理解
- jsp的exception对象
- ES6之对象字面量扩展语法(Enhanced Object Literals)
- PS入门基础<3>
- DNS服务器配置实验--正向解析、反向解析、主从解析、子域授权和bindview
- NameNode启动过程