package Exercise;
public class ThreadBinaryTreeDemo {
public static void main(String[] args) {
Node root = new Node(1,"tom");
Node node1 = new Node(3,"smith");
Node node2 = new Node(6,"LiHua");
Node node3 = new Node(8,"king");
Node node4 = new Node(10,"queen");
Node node5 = new Node(14,"dim");
//手动构造一个二叉树,实际我们需要使用递归创建二叉树
root.setLeft(node1);
root.setRight(node2);
root.setParent(root);
node1.setParent(root);
node2.setParent(root);
node1.setLeft(node3);
node1.setRight(node4);
node3.setParent(node1);
node4.setParent(node1);
node2.setLeft(node5);
node5.setParent(node2);
//遍历中序线索化二叉树
BinaryTree binaryTree = new BinaryTree(root);
//binaryTree.threadInfixBinaryTree();
//binaryTree.threadInfixOrder();
//测试前序线索化二叉树及其线索化遍历
// binaryTree.threadPreOrderTree();
//System.out.println(node4.getRight());
//binaryTree.threadPreOrderList();
//测试后序线索化二叉树
binaryTree.threadPostOrderTree();
//测试索引化是否正确
//System.out.println(node3.getRight());
//System.out.println(node5.getLeft());
//System.out.println(node5.getLeft());
//测试遍历后序索引化
binaryTree.threadPostOrderList();
}
}
class BinaryTree{
private Node root;//默认为null
private Node pre = null;//辅助结点,指向当前结点的上一个结点
public BinaryTree(Node root){
this.root = root;
}
public void threadPostOrderTree(){
this.threadPostOrderTree(root);
}
//遍历后序线索化二叉树
public void threadPostOrderList(){
Node node = root;
while (node != null && node.getLeftType() == 0){
node = node.getLeft();//从最左结点开始遍历
}
//退出循环,得到最左结点
//从最左结点,开始遍历
while (node != null){
//输出全部 后缀结点
if(node.getRightType() == 1){
System.out.println(node);
pre = node;
node = node.getRight();
} else{//上一次的后缀结点输出完毕,在此开始判断是否输出 前驱结点
if(node.getRight() == pre){
//上个处理的节点是当前结点的右节点,即当前结点是 父结点
System.out.println(node);
if(node == root){//如果父结点是根节点,则遍历结束
return;
}
pre = node;
node = node.getParent();// 此时本父结点的左右子树已经遍历完毕,回到上一层(可参考根节点进行思考)
} else {//相当于回到了root节点,开始遍历右子树,从右子树的最左结点开始往上
node = node.getRight();
while (node != null && node.getLeftType() == 0){
node = node.getLeft();
}
}
}
}
}
//线索化后序二叉树
public void threadPostOrderTree(Node node){
if(node == null){
return;
}
//线索化左子树
threadPostOrderTree(node.getLeft());
//线索化右子树
threadPostOrderTree(node.getRight());
//线索化当前结点
if(node.getLeft() == null){
node.setLeft(pre);
node.setLeftType(1);
}
if(pre != null && pre.getRight() == null){
pre.setRight(node);
pre.setRightType(1);
}
//!!!!!
pre = node;
}
//线索化前序二叉树
public void threadPreOrderTree(Node node){
if(node == null){
return ;
}
//线索化当前结点
if(node.getLeft() == null){
node.setLeft(pre);
node.setLeftType(1);
}
if(pre != null && pre.getRight() == null){
pre.setRight(node);
pre.setRightType(1);
}
//!!!!!
pre = node;
//线索化左子树
if(node.getLeftType() == 0){
threadPreOrderTree(node.getLeft());
}
//线索化右子树
if(node.getRightType() == 0){
threadPreOrderTree(node.getRight());
}
}
public void threadPreOrderTree(){
threadPreOrderTree(root);
}
//遍历前序线索化二叉树
public void threadPreOrderList(){
Node node = root;
while (node != null){
//循环找到leftType == 1 的结点才开始向右
while (node.getLeftType() == 0){
System.out.println(node);
node = node.getLeft();
}
//退出循环之后,不断的向右
System.out.println(node);
node = node.getRight();
}
}
//线索化中序二叉树
public void threadInfixBinaryTree(){
this.threadInfixBinaryTree(root);
}
//线索化中序二叉树
public void threadInfixBinaryTree(Node node){
if(node == null){
return;
}
//线索化左子树
threadInfixBinaryTree(node.getLeft());
//线索化当前结点
//先处理当前结点的前驱结点
if(node.getLeft() == null){
//让当前结点的左指针指向前驱结点
node.setLeft(pre);
node.setLeftType(1);
}
//线索化当前结点的后缀结点
if(pre != null && pre.getRight() == null){
pre.setRight(node);
pre.setRightType(1);
}
//注意:没处理一个结点后,让当前结点是下一个结点的前驱结点
pre = node;
//线索化右子树
threadInfixBinaryTree(node.getRight());
}
//遍历中序线索化二叉树
public void threadInfixOrder(){
Node node = root;
while (node != null){
//循环找到leftType == 1 的结点才开始遍历
while (node.getLeftType() == 0){
node = node.getLeft();
}
//退出循环之后
System.out.println(node);
//如果rightType == 1则一直输出,即后继节点
while (node.getRightType() == 1){
node = node.getRight();
System.out.println(node);
}
//否则,替换这个遍历的结点
node = node.getRight();
}
}
//前序
public void preOrder(){
if(root != null){
root.preOrder();
} else{
System.out.println("二叉树为空");
}
}
//前序
public void infixOrder(){
if(root != null){
root.infixOrder();
} else{
System.out.println("二叉树为空");
}
}
//前序
public void postOrder(){
if(root != null){
root.postOrder();
} else{
System.out.println("二叉树为空");
}
}
//删除一个结点,如果是叶子结点,则删除,非叶子节点则删除子树
public void delete(int no){
if(root == null){
System.out.println("数为空");
}else {
if(root.getNo() == no){
root = null;
return;
}else {
root.delete(no);
}
}
}
}
//二叉树的结构
class Node{
private int no;
private String name;
//0 表示左子树,1表示前驱节点
private int leftType;
//0 表示右子树,1表示后缀节点
private int rightType;
private Node left;
private Node right;
private Node parent;//为了后序线索化增加的父结点
public Node getParent() {
return parent;
}
public void setParent(Node parent) {
this.parent = parent;
}
public int getLeftType() {
return leftType;
}
public void setLeftType(int leftType) {
this.leftType = leftType;
}
public int getRightType() {
return rightType;
}
public void setRightType(int rightType) {
this.rightType = rightType;
}
public int getNo() {
return no;
}
public String getName() {
return name;
}
public Node(int no, String name){
this.no = no;
this.name = name;
}
public Node getLeft(){
return this.left;
}
public void setLeft(Node node){
this.left = node;
}
public Node getRight(){
return this.right;
}
public void setRight(Node node){
this.right = node;
}
@Override
public String toString() {
return "Node{" +
"no=" + no +
", name='" + name + '\'' +
'}';
}
//一些节点的方法,前序遍历
public void preOrder(){
System.out.println(this);
if(this.left != null){
this.left.preOrder();
}
if(this.right != null){
this.right.preOrder();
}
}
//中序遍历
public void infixOrder(){
if(this.left != null){
this.left.infixOrder();
}
System.out.println(this);
if(this.right != null){
this.right.infixOrder();
}
}
//后序遍历
public void postOrder(){
if(this.left != null){
this.left.postOrder();
}
if(this.right != null){
this.right.postOrder();
}
System.out.println(this);
}
//前序查找,根据no查找,找到返回该节点,否则返回null
public Node preOrderSearch(int no){
if(this.no == no){
return this;
}
//否则
Node resNode = null;
if(this.left != null){
resNode = this.left.preOrderSearch(no);
}
if(resNode != null){
return resNode;
}
if(this.right != null){
resNode = this.right.preOrderSearch(no);
}
//不管找没找到
return resNode;
}
//中序遍历查找
public Node infixOrderSearch(int no){
Node resNode = null;
if(this.left != null){
resNode = this.left.infixOrderSearch(no);
}
if(resNode != null){
return resNode;
}
if(this.no == no){
return this;
}
if(this.right != null){
resNode = this.right.infixOrderSearch(no);
}
return resNode;
}
//后续遍历查找
public Node postOrderSearch(int no){
Node resNode = null;
if(this.left != null){
resNode = this.left.postOrderSearch(no);
}
if(resNode != null){
return resNode;
}
if(this.right != null){
resNode = this.right.postOrderSearch(no);
}
if(resNode != null){
return resNode;
}
if(this.no == no){
return this;
}
return resNode;
}
//删除
public void delete(int no){
if(this.left != null && this.left.no == no){
this.left = null;
}
if(this.right != null && this.right.no == no){
this.right = null;
}
}
}
JAVA二叉树的前序、中序、后序遍历及其前序、中序、后序索引化和遍历
最新推荐文章于 2022-07-02 14:51:28 发布