AVL树

来源:互联网 发布:阿里云域名隐私保护 编辑:程序博客网 时间:2024/06/18 17:58
public class AVLTree {public static class AVLTreeNode {AVLTreeNode mLeftNode;AVLTreeNode mRightNode;AVLTreeNode mParent;public int mHeight;int mValue;public AVLTreeNode() {mLeftNode = null;mRightNode = null;mParent = null;mHeight = 0;}public AVLTreeNode(int value) {this();mValue = value;}}public static int getNodeHeight(AVLTreeNode node) {return node == null ? -1 : node.mHeight;}private AVLTreeNode mHeader;public AVLTreeNode find(int value) {AVLTreeNode node = mHeader;return findNode(node, value);}private AVLTreeNode findNode(AVLTreeNode startNode, int value) {AVLTreeNode node = startNode;while (null != node) {if (node.mValue == value) {return node;} else if (value > node.mValue) {node = node.mRightNode;} else {node = node.mLeftNode;}}return null;}public void printLevel() {System.out.println("=======================================");printLevelNode(mHeader, 0);System.out.println("=======================================");}private void printLevelNode(AVLTreeNode node, int level) {if (null != node) {for (int i = 0; i < level; i++) {System.out.print("    ");}System.out.println(String.valueOf(node.mValue));printLevelNode(node.mLeftNode, level + 1);printLevelNode(node.mRightNode, level + 1);}}public void print() {printNode(mHeader);}private void printNode(AVLTreeNode node) {if (null != node) {printNode(node.mLeftNode);System.out.print("     " + node.mValue);printNode(node.mRightNode);}}public int findMin() {if (null == mHeader) {throw new IllegalStateException("树为空");}AVLTreeNode node = findMinNode(mHeader);return node.mValue;}private AVLTreeNode findMinNode(AVLTreeNode startNode) {AVLTreeNode node = startNode;while (null != node.mLeftNode) node = node.mLeftNode;return node;}public int findMax() {if (null == mHeader) {throw new IllegalStateException("树为空");}AVLTreeNode node = findMaxNode(mHeader);return node.mValue;}private AVLTreeNode findMaxNode(AVLTreeNode startNode) {AVLTreeNode node = startNode;while (null != node.mRightNode) node = node.mRightNode;return node;}// 插入:public void insert(int value) {insert(mHeader, mHeader, value);}private void insert(AVLTreeNode targetParent, AVLTreeNode target, int value) {if (target == null) { // 当前节点已经是空节点了,也就是必须在这里插入了target = new AVLTreeNode();target.mValue = value;if (null == targetParent) {// 这才说明是空树mHeader = target;} else {target.mParent = targetParent;if (targetParent.mValue > value) {targetParent.mLeftNode = target;} else {targetParent.mRightNode = target;}}return;} else if (target.mValue > value) {// 递归插入:在左边插入,只会改变左子树的高度insert(target, target.mLeftNode, value);// 向左侧插入,只能左侧比右侧大if (getNodeHeight(target.mLeftNode) - getNodeHeight(target.mRightNode) >= 2) {if (target.mLeftNode.mValue > value) { // LLrightRotate(target);} else {// LRleftRightRotate(target);}}} else if (target.mValue < value) {insert(target, target.mRightNode, value);if (getNodeHeight(target.mRightNode) - getNodeHeight(target.mLeftNode) >= 2) {if (target.mRightNode.mValue < value) {  // RRleftRotate(target);} else {// RLrightLeftRotate(target);}}} else { // 已经存在了return;}// 重新计算高度:int leftHeight = getNodeHeight(target.mLeftNode);int rightHeight = getNodeHeight(target.mRightNode);target.mHeight = Math.max(leftHeight, rightHeight) + 1;}public void deleteNode(int value) {AVLTreeNode delNode = findNode(mHeader, value);if (null != delNode) {deleteNode(mHeader, value);} else {System.out.println("can not find node");}}public void deleteNode(AVLTreeNode target, int value) {if (target.mValue > value) {deleteNode(target.mLeftNode, value);} else if (target.mValue < value) {deleteNode(target.mRightNode, value);} else if (null != target.mLeftNode) {// 就是本尊:从左边替换// 替换target.mValue = findMaxNode(target.mLeftNode).mValue;deleteNode(target.mLeftNode, target.mValue);} else if (null != target.mRightNode) {// 就是本尊:从右边替换target.mValue = findMinNode(target.mRightNode).mValue;deleteNode(target.mRightNode, target.mValue);} else {// 没有孩子:直接删除if (target.mParent.mLeftNode == target) { // 做孩子target.mParent.mLeftNode = null;} else {target.mParent.mRightNode = null;}return;}int leftHeight = getNodeHeight(target.mLeftNode);int rightHeight = getNodeHeight(target.mRightNode);target.mHeight = Math.max(leftHeight, rightHeight) + 1;if (rightHeight - leftHeight >= 2) {if (target.mRightNode.mRightNode == null) {rightLeftRotate(target);} else {leftRotate(target);}} else if (leftHeight - rightHeight >= 2) {if (null == target.mLeftNode.mLeftNode) {leftRightRotate(target);} else {rightRotate(target);}}}/** * 左旋转 * @param target 目标 */private void leftRotate(AVLTreeNode target) {AVLTreeNode rightChild = target.mRightNode;// 处理右子树的左节点target.mRightNode = rightChild.mLeftNode;if (null != rightChild.mLeftNode) {rightChild.mLeftNode.mParent = target;}// 处理父节点if (target.mParent == null) { // 没有父节点mHeader = rightChild;rightChild.mParent = null;} else if (target.mParent.mLeftNode == target) { // 该子树在父节点的左子树上target.mParent.mLeftNode = rightChild;rightChild.mParent = target.mParent;} else { // 该子树在父节点的右子树上target.mParent.mRightNode = rightChild;rightChild.mParent = target.mParent;}// 颠倒父子关系rightChild.mLeftNode = target;target.mParent = rightChild;// 计算高度:int leftHeight = getNodeHeight(target.mLeftNode);int rightHeight = getNodeHeight(target.mRightNode);target.mHeight = Math.max(leftHeight, rightHeight) + 1;// rightChild已经是父节点了leftHeight = getNodeHeight(rightChild.mLeftNode);rightHeight = getNodeHeight(rightChild.mRightNode);rightChild.mHeight = Math.max(leftHeight, rightHeight) + 1;}private void rightRotate(AVLTreeNode target) {AVLTreeNode leftChild = target.mLeftNode;// 处理左子树的右节点target.mLeftNode = leftChild.mRightNode;if (null != leftChild.mRightNode) {leftChild.mRightNode.mParent = target;}// 处理父节点:if (null == target.mParent) {// 本身就是根mHeader = leftChild;leftChild.mParent = null;} else if (target.mParent.mLeftNode == target) {target.mParent.mLeftNode = leftChild;leftChild.mParent = target.mParent;} else {target.mParent.mRightNode = leftChild;leftChild.mParent = target.mParent;}// 颠倒父子关系:leftChild.mRightNode = target;target.mParent = leftChild;// 计算target的高度int leftHeight = getNodeHeight(target.mLeftNode);int rightHeight = getNodeHeight(target.mRightNode);target.mHeight = Math.max(leftHeight, rightHeight) + 1;// 计算leftChild(现在的父节点)leftHeight = getNodeHeight(leftChild.mLeftNode);rightHeight = getNodeHeight(leftChild.mRightNode);leftChild.mHeight = Math.max(leftHeight, rightHeight) + 1;}private void leftRightRotate(AVLTreeNode target) {leftRotate(target.mLeftNode);rightRotate(target);}private void rightLeftRotate(AVLTreeNode target) {rightRotate(target.mRightNode);leftRotate(target);}public static void main(String[] args) {AVLTree tree = new AVLTree();Random r = new Random(10);int length = 10;int value = 0;for (int i = 0; i < length; i++) {value = r.nextInt(1000);tree.insert(value);}tree.print();AVLTreeNode node = tree.find(value);if (null != node) {System.out.println("\nFind Value: " + node.mValue);// 把value到跟依次打印出来:System.out.println("从node到根的路径:");while (node != null) {System.out.print("     " + node.mValue);node = node.mParent;}} else {System.out.println("\nCANNOT Find Value: " + value);}int maxValue = tree.findMax();int minValue = tree.findMin();System.out.println("\n最大值:" + maxValue + ", 最小值:" + minValue);tree.printLevel();tree.deleteNode(293);tree.printLevel();}}

1 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 我的律师骗我怎么办 没婆婆生了小孩怎么办 没人帮你带孩子怎么办 亲戚在家里不走怎么办 穷人家的孩子该怎么办 空腹吃李子胃疼怎么办 情侣空间农场谷仓空间不够怎么办 王者荣耀情侣解除对方不同意怎么办 oppo手机进了水怎么办 淘宝卖号被骗了怎么办 淘宝买号被骗了怎么办 后脑偏头疼怎么办最快最有效 脸两边的骨头大怎么办 做b超胎儿老盘腿怎么办 裤子白边染色了怎么办 异地恋要分手了怎么办 异地恋没话题了怎么办 陪婆婆聊天心情超级郁闷怎么办? 他不想理你了怎么办 陌陌看到信息不回怎么办 qq的文档看不了怎么办 怀孕了分手了怎么办啊 qq节日祝福关了怎么办 微信欠款不还怎么办 qq文件记录删除了怎么办 qq漫游记录删了怎么办 换了新手机微信怎么办 新手机了微信怎么办 微信收藏空间已满怎么办 微信收藏空间满了怎么办 qq步数上传不了怎么办 qq发送的文件失效了怎么办 苹果手机微信数据损坏怎么办 微信文件被清理怎么办 老婆与别人聊暧昧话题怎么办 微信不小心删了聊天记录怎么办 当聊天没话题了怎么办 老婆和别人频繁聊天老公怎么办 qq上把人屏蔽了怎么办 注册微信验证码发不出去怎么办 两个人在一起没有话题怎么办