二叉树
概念:树(tree)是由n(n>=0)个结点组成的有限集合(树中元素通常称为结点)。n=0的树称为空树,n>0的树T由以下两个条件约定构成:
-
有一个特殊结点称为根(root)结点,他只有后继结点,没有前驱结点
-
除根结点外的其他结点分为m个互不相交的集合Tn…其中每个集合Ti也具有树结构,称为根的子树(Subtree)
下列代码中对于二叉树的非递归遍历和层次遍历分别用到栈和队列
//栈的实现 public class LinkedStack<T>implements stackInterface<T> { class Node{ T data; Node pre; Node(T t){ this.data = t; } @Override public String toString() { return "["+this.data+"]"; } } //作为指针,指向栈顶元素 Node root,pointer; public LinkedStack(){ root =new Node(null); pointer = root; } @Override public Object Pop() { if (root.pre==null){ throw new IndexOutOfBoundsException("stack overflow"); } Object temp = pointer; pointer = pointer.pre; return temp; } @Override public void Push(T t) { if(root.pre==null){ Node newNode = new Node(t); root.pre =newNode; pointer = newNode; } Node newNode = new Node(t); newNode.pre = pointer; pointer = newNode; } @Override public Object Peek() { if (root.pre==null){ throw new IndexOutOfBoundsException("stack overflow"); } return pointer; } @Override public boolean IsEmpty() { return root.pre==null; } //通过递归获取倒数第二个结点 }
//树结点的实现 public class BinaryNode<T>{ T data;//数据 BinaryNode<T> left,right;//左 右孩子结点 public BinaryNode(T data,BinaryNode<T> left,BinaryNode<T> right){//构造结点 this.data= data; this.left = left; this.right = right; } public BinaryNode(T data){//构造叶子节点 this(data,null,null); } public String toString(){//返回数据域的字符串描述 return this.data.toString(); } public boolean isLeaf(){//判断当前结点是否为叶子节点 return this.left==null&&this.right==null; } }
//队列的实现 package day03.queue.LinkedQueue; import day03.queue.queueInterface.queue; /** * @author:sncot * @date:7:59 2022/7/27 */ public class LinkedQueue<T> implements queue<T> { class Node{ T data; Node pre; Node (T t){ this.data = t; } @Override public String toString() { return "["+this.data+"]"; } } int num; Node rear,front; @Override public void Add(T t) { if (num==0){ Node newNode = new Node(t); rear = front=newNode; num++; return; } Node newNode = new Node(t); rear.pre= newNode; num++; } @Override public Object Poll() { if (num==0){ System.out.println("queue is empty"); return null; } Object temp = front; front = front.pre; num--; return temp; } @Override public Object Peek() { if(num==0){ System.out.println("queue is null"); return null; } return front; } @Override public boolean IsEmpty() { return num==0; } }
//树的相关操作方法的实现 package day04.tree.binaryTree; import day03.queue.LinkedQueue.LinkedQueue; import day03.stack.linkedStack.LinkedStack; /** * @author:sncot * @date:10:27 2022/8/1 */ public class BinaryTree <T>{ BinaryNode<T> root;//根节点 public BinaryNode<T> insert(T t){//插入x作为根节点,原根节点作为x的左孩子结点,返回插入节点 return this.root = new BinaryNode<>(t,this.root,null); } //插入结点为指定节点parent的左/右孩子结点 public BinaryNode<T> insert(BinaryNode<T> parent,T t,boolean leftChild){ if (t == null) { return null; } if(leftChild){ return parent.left = new BinaryNode<>(t,parent.left,null); }else{ return parent.right = new BinaryNode<>(t,null,parent.right); } } //删除指定节点parent的左/右子树 public void remove(BinaryNode<T> parent,boolean leftChild){ if (leftChild){ parent.left=null; }else{ parent.right=null; } } //删除二叉树的所有结点 public void clear(){ this.root = null; } //二叉树的先根次序遍历 public void preOrder(){//递归遍历 preOrder(this.root); } private void preOrder(BinaryNode<T> node){ if (node!=null){ System.out.println(node.data.toString()+""); preOrder(node.left); preOrder(node.right); } } //非递归 借助栈实现先根次序遍历 public void PreOrderTraverse(){//非递归 System.out.println("先根遍历 非递归:"); LinkedStack<BinaryNode<T>> stack = new LinkedStack<>(); BinaryNode<T> p = this.root; while(p!=null|| !stack.IsEmpty()){//当栈非空或者当前结点不为空时 if(p!=null){ System.out.println(p.data+""); stack.Push(p); p=p.left;//进入左子树 }else{//p为空栈非空时 System.out.println("null"); p = (BinaryNode<T>) stack.Pop();//p指向出栈结点 p = p.right;//进入右子树 } System.out.println(); } } public void postOrder(){ postOrder(this.root); } private void postOrder(BinaryNode<T> node){ if(node!=null){ postOrder(node.left); postOrder(node.right); System.out.println(node.data.toString()+""); } } public void inOrder(){ inOrder(this.root); } private void inOrder(BinaryNode<T> node){ if (node!=null){ inOrder(node.left); System.out.println(node.data.toString()+""); inOrder(node.right); } } //借助队列实现层次遍历二叉树 public void levelOrder(){ System.out.println("层次遍历二叉树:"); LinkedQueue<BinaryNode<T>> queue = new LinkedQueue<>();//创建一个空队列 BinaryNode<T> p = this.root;//根节点没有入队 while(p!=null){ System.out.println(p.data+"");//访问p结点 if (p.left!=null){ queue.Add(p.left); } if (p.right!=null){ queue.Add(p.right); } p = (BinaryNode<T>) queue.Poll();//p指向出队结点,若队列为空返回null } System.out.println(); } }
public class main { public static void main(String[] args) { BinaryTree<String> tree = new BinaryTree<>(); tree.insert("A"); tree.insert("B"); tree.insert("C"); tree.insert("D"); tree.insert("E"); tree.insert("F"); tree.insert("G"); tree.postOrder(); System.out.println("--------------------"); tree.preOrder(); System.out.println("=========================="); tree.inOrder(); tree.PreOrderTraverse(); System.out.println("===++++++++++++++++++"); tree.levelOrder(); } }