树的主要算法有插入,查找,显示,遍历,删除,其中显示和删除略微复杂。

package chap08.tree;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Stack;class Node {public int iData;public double dData;public Node leftChild;public Node rightChild;public void displayNode() {System.out.print("{" + iData + ", " + dData + "}");}
}class Tree {// first node of treeprivate Node root; public Tree() {root = null;} /** 查找*/public Node find(int key) { // (assumes non-empty tree)Node current = root; // start at rootwhile (current.iData != key) // while no match,
        {if (key < current.iData) { current = current.leftChild;}else {current = current.rightChild;}if (current == null) {return null; }}return current; // found it
    } /** 插入*/public void insert(int id, double dd) {Node newNode = new Node(); // make new nodenewNode.iData = id; // insert datanewNode.dData = dd;if (root == null) { // no node in rootroot = newNode;}else // root occupied
        {Node current = root; // start at root
            Node parent;while (true) // (exits internally)
            {parent = current;if (id < current.iData) {current = current.leftChild;if (current == null) { // insert on leftparent.leftChild = newNode;return;}} else {current = current.rightChild;if (current == null) { // insert on rightparent.rightChild = newNode;return;}} } } } /** 删除*/public boolean delete(int key) { // (assumes non-empty list)Node current = root;Node parent = root;boolean isLeftChild = true;// search for nodewhile (current.iData != key) {parent = current;if (key < current.iData) // go left?
            {isLeftChild = true;current = current.leftChild;} else {isLeftChild = false;current = current.rightChild;}if (current == null) // end of the line,return false; // didn't find it
        } // if no children, simply delete itif (current.leftChild == null && current.rightChild == null) {if (current == root) {root = null; }else if (isLeftChild) {parent.leftChild = null; // disconnect
            }else {// from parentparent.rightChild = null;}}// if no right child, replace with left subtreeelse if (current.rightChild == null) {if (current == root) {root = current.leftChild;}else if (isLeftChild) {parent.leftChild = current.leftChild;}else {parent.rightChild = current.leftChild;}}// if no left child, replace with right subtreeelse if (current.leftChild == null)if (current == root)root = current.rightChild;else if (isLeftChild)parent.leftChild = current.rightChild;elseparent.rightChild = current.rightChild;// 有两个孩子,则用中序后继替代else {// get successor of node to delete (current)Node successor = getSuccessor(current);// connect parent of current to successor insteadif (current == root) {root = successor;}else if (isLeftChild) {parent.leftChild = successor;}else {parent.rightChild = successor;}// connect successor to current's left childsuccessor.leftChild = current.leftChild;} return true; } /** 获取后继* 返回具有倒数第二高的值的节点* 找到右孩子,然后右孩子的左子孙*/private Node getSuccessor(Node delNode) {Node successorParent = delNode;Node successor = delNode;// go to right childNode current = delNode.rightChild; while (current != null) { successorParent = successor;successor = current;// go to left childcurrent = current.leftChild; }// if successor not right childif (successor != delNode.rightChild) { // make connectionssuccessorParent.leftChild = successor.rightChild;successor.rightChild = delNode.rightChild;}return successor;}public void traverse(int traverseType) {switch (traverseType) {case 1:System.out.print("\nPreorder traversal: ");preOrder(root);break;case 2:System.out.print("\nInorder traversal:  ");inOrder(root);break;case 3:System.out.print("\nPostorder traversal: ");postOrder(root);break;}System.out.println();}/** 先序遍历*/private void preOrder(Node localRoot) {if (localRoot != null) {System.out.print(localRoot.iData + " ");preOrder(localRoot.leftChild);preOrder(localRoot.rightChild);}}/** 中序遍历*/private void inOrder(Node localRoot) {if (localRoot != null) {inOrder(localRoot.leftChild);System.out.print(localRoot.iData + " ");inOrder(localRoot.rightChild);}}/** 后序遍历*/private void postOrder(Node localRoot) {if (localRoot != null) {postOrder(localRoot.leftChild);postOrder(localRoot.rightChild);System.out.print(localRoot.iData + " ");}}/** 在控制台打印显示树 * */public void displayTree() {// 全局栈,初始放入树的根节点Stack globalStack = new Stack();globalStack.push(root);// 打印空格的数量int nBlanks = 32;// 是否为空的标识boolean isRowEmpty = false;while (isRowEmpty == false) {// 本地栈Stack localStack = new Stack();// 设置标识为空,后边再根据实际情况判断其是否不为空isRowEmpty = true;// 打印一定数量的空格,为了将节点 放置在适当的位置以满足视觉效果上树的形状for (int j = 0; j < nBlanks; j++) {System.out.print(' ');}while (globalStack.isEmpty() == false) {// 当标识不为空时,从全局栈弹出栈顶节点Node temp = (Node) globalStack.pop();if (temp != null) {// 如果当前从全局栈弹出的栈顶元素 不为空,则打印当前节点数值,同时将其左右孩子节点放入本地栈
                    System.out.print(temp.iData);// 先放左孩子,后方右孩子,后边转移到全局栈后,可以反序,从而保证左孩子在右孩子顶端
                    localStack.push(temp.leftChild);localStack.push(temp.rightChild);// 如果当前全局栈弹出的节点有左孩子或右孩子if (temp.leftChild != null || temp.rightChild != null) {// 设置标识不为空isRowEmpty = false;}} else {// 如果当前从全局栈弹出的栈顶元素 为空,则打印"--"替代节点数值,同时将两个空值放入本地栈System.out.print("-");localStack.push(null);localStack.push(null);}for (int j = 0; j < nBlanks * 2 - 1; j++) {System.out.print(' ');}} System.out.println();System.out.println();nBlanks /= 2;while (localStack.isEmpty() == false) {// 将本地栈的节点放入全局栈,进行反序,从而保证先处理左孩子
                globalStack.push(localStack.pop());}} }
} class TreeApp {public static void main(String[] args) throws IOException {int value;Tree theTree = new Tree();theTree.insert(50, 1.5);theTree.insert(25, 1.2);theTree.insert(75, 1.7);theTree.insert(12, 1.5);theTree.insert(37, 1.2);theTree.insert(43, 1.7);theTree.insert(30, 1.5);theTree.insert(33, 1.2);theTree.insert(87, 1.7);theTree.insert(93, 1.5);while (true) {System.out.print("Enter first letter of show, insert, find, delete, or traverse: ");int choice = getChar();switch (choice) {case 's':theTree.displayTree();break;case 'i':System.out.print("Enter value to insert: ");value = getInt();theTree.insert(value, value + 0.9);break;case 'f':System.out.print("Enter value to find: ");value = getInt();Node found = theTree.find(value);if (found != null) {System.out.print("Found: ");found.displayNode();System.out.print("\n");} else {System.out.print("Could not find ");}System.out.print(value + '\n');break;case 'd':System.out.print("Enter value to delete: ");value = getInt();boolean didDelete = theTree.delete(value);if (didDelete) {System.out.print("Deleted " + value + '\n');}else {System.out.print("Could not delete ");}System.out.print(value + '\n');break;case 't':System.out.print("Enter type 1, 2 or 3: ");value = getInt();theTree.traverse(value);break;default:System.out.print("Invalid entry\n");} } } /** 获取输入 */public static String getString() throws IOException {InputStreamReader isr = new InputStreamReader(System.in);BufferedReader br = new BufferedReader(isr);String s = br.readLine();return s;}public static char getChar() throws IOException {String s = getString();return s.charAt(0);}public static int getInt() throws IOException {String s = getString();return Integer.parseInt(s);}
} 

转载于:https://www.cnblogs.com/thlzhf/p/4088972.html

Java数据结构与算法(20) - ch08树相关推荐

  1. 数据结构及算法 | Java数据结构——回溯算法之子集树

    1.介绍一下子集树,什么是子集树? 当所给问题是从n个元素的集合S中找出满足某些条件或者性质的子集时,解空间是子集树: 比如典型的0-1背包问题-----and-----轮船装载问题: 解空间 就是指 ...

  2. Java数据结构和算法:234树和外部存储

    234树 有一个数据项的节点总是有两个子节点 有两个数据项的节点总是有三个子节点 有三个数据项的节点总是有四个子节点 多叉树,四叉树 外部存储 主存RAM,随机访问存储器,断电后数据会丢失 磁盘文件存 ...

  3. Java数据结构与算法——树(基本概念,很重要)

    声明:码字不易,转载请注明出处,欢迎文章下方讨论交流. 有网友私信我,期待我的下一篇数据结构.非常荣幸文章被认可,也非常感谢你们的监督. 前言:Java数据结构与算法专题会不定时更新,欢迎各位读者监督 ...

  4. java数据结构与算法之双链表设计与实现

    转载请注明出处(万分感谢!): http://blog.csdn.net/javazejian/article/details/53047590 出自[zejian的博客] 关联文章: java数据结 ...

  5. Java 数据结构和算法(十五):无权无向图

    Java数据结构和算法(十五)--无权无向图 前面我们介绍了树这种数据结构,树是由n(n>0)个有限节点通过连接它们的边组成一个具有层次关系的集合,把它叫做"树"是因为它看起 ...

  6. Java数据结构和算法 - 递归

    三角数字 Q: 什么是三角数字? A: 据说一群在毕达哥拉斯领导下工作的古希腊的数学家,发现了在数学序列1,3,6,10,15,21,--中有一种奇特的联系.这个数列中的第N项是由第N-1项加N得到的 ...

  7. java数据结构与算法之(Queue)队列设计与实现

    [版权申明]转载请注明出处(请尊重原创,博主保留追究权) http://blog.csdn.net/javazejian/article/details/53375004 出自[zejian的博客] ...

  8. Java 数据结构和算法 - 递归

    Java 数据结构和算法 - 递归 什么是递归 背景:数学归纳法证明 基本递归 printing numbers in any base 它为什么有效 如何工作 递归太多是危险的 树 数值应用 模幂运 ...

  9. 数据结构 - Java -韩顺平 图解Java数据结构和算法

    数据结构 Lesson 1 数据结构的知识总结 1. 几个经典的算法面试题 2. 线性结构与非线性结构 2.1 稀疏数组 sparsearray 2.2 队列 2.2.1 顺序队列: 2.2.2 环形 ...

最新文章

  1. SQL SERVER 2008查看sql执行的时间
  2. opensuse download
  3. FreeMarkerConfigurer使用TemplateDirectiveModel时获取request、session
  4. 调焦后焦实现不同距离成像_如何用手机拍出单反的效果,系列学习(一)AF参数“自动调焦”...
  5. 牛牛和牛可乐的赌约2
  6. 会议交流 | 如何将图谱实体与关系更好的向量化,并基于推理扩充知识边界?——DataFun Summit2022知识图谱在线峰会...
  7. mysql支持表情输入_让MySQL支持Emoji表情 mysql 5.6
  8. [NOI2015]寿司晚宴(状压dp)
  9. 使用SQL Server 2005作业设置定时任务
  10. FD.io VPP基本介绍:理解向量包处理(VPP)
  11. webAppbuilder微件使用教程3 地理处理微件
  12. Android项目目录结构中各个文件夹的作用
  13. 基于http 构建 yum 网络源
  14. 计算机vb题库程序代码编写,计算机二级考试.题库-vb程序题
  15. 数据分析师面试简历怎么做?
  16. poweramp最完美设置_powerAMP音效设置
  17. 基本农田卫星地图查询_中国北斗已启用全球服务,如何使用手机北斗卫星导航?...
  18. 线下餐饮实体店线上精准引流方案!你想看的都在这儿!这篇文章教你转化!
  19. Ubuntu(护眼设置)安装屏幕色温调节软件F.lux
  20. LinearLayout布局添加下划线

热门文章

  1. HDU 1536 求解SG函数
  2. 连接相机无法识别_车牌识别一体机在汽修门店安装中要注意的事项
  3. SpringSecurity OAuth2四种模式说明
  4. Nginx server_name正则表达式匹配配置
  5. 轻量级锁的加锁和解锁逻辑-自旋锁
  6. 什么是Spring inner beans?
  7. Spring 的设计初衷
  8. 微信支付 - 提供支付中心商户订单查询
  9. 大数据神器Kafka入门
  10. mybatis简介-什么是Mybatis