设计一个没有扩容负担的堆结构
2017-11-04 23:20
330 查看
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; } }
相关文章推荐
- 其他题目---设计一个没有扩容负担的堆结构
- 微信公号“架构师之路”学习笔记(五)-数据库扩展性架构设计(水平切分,秒级扩容,平滑迁移,在线表结构变更,一个大数据量多属性高并发的数据库设计等)
- 如果字符串的一个子串(其长度大于 1)的各个字符均相同,则称之为等值子串。试设计一算法,求出串S中的最大等值子串 函数返回最大等值子串的长度,如果没有则返回1。 例如: 若S= “abc123abc1
- 简单分享一个轻量级自动化测试框架目录结构设计
- 一个开源的采集服务器体系结构设计
- 系统原型结构描述(概述)最近要设计一个框架,大家一起讨论下如何实现?
- 数据结构课程设计---用Dijkstra算法实现一个简易的最佳方案选择
- 一个开源的IoC采集服务器体系结构设计
- 一个开源的IoC采集服务器体系结构设计
- 一个开源的IoC采集服务器体系结构设计
- 微软100题40题-设计一个栈结构,满足一下条件:min,push,pop操作的时间复杂度为O(1)。
- 一个开源的IoC采集服务器体系结构设计
- 一个典型的采集服务器体系结构设计
- 一个开源的IoC采集服务器体系结构设计
- 一个典型的采集服务器体系结构设计
- 一个典型的采集服务器体系结构设计
- 一个典型的采集服务器体系结构设计
- Java 异常类层次结构及怎样设计一个高效合理的异常处理框架
- 两个小数相乘,小数点后面位数没有限制,设计一个高精度算法
- 创建一个表,设计表结构,填写表内容