二叉树的三种遍历算法的实现
程序员文章站
2022-05-20 21:32:34
...
二叉树与一般树的区别
一般树的子树不分次序,而二叉树的子树有左右之分
二叉树的存贮:每个节点只需要两个指针域(左节点,右节点),有的为了操作方便也会 增加指向父级节点的指针,除了指针域以外,还会有一个数据域用来保存当前节点的信息
二叉树的特点:
性质1:在二叉树的第i层上至多有2^(i-1)个节点(i >= 1)
性质2:深度为k的二叉树至多有2^k-1个节点(k >=1)
性质3:对于任意一棵二叉树T而言,其叶子节点数目为N0,度为2的节点数目为N2,则有N0 = N2 + 1。
性质4:具有n个节点的完全二叉树的深度 。
二叉树的遍历
二叉树的遍历分为三种:前序遍历 中序遍历 后序遍历
前序遍历:按照“根左右”,先遍历根节点,再遍历左子树 ,再遍历右子树
中序遍历:按照“左根右“,先遍历左子树,再遍历根节点,最后遍历右子树
后续遍历:按照“左右根”,先遍历左子树,再遍历右子树,最后遍历根节点
其中前,后,中指的是每次遍历时候的根节点被遍历的顺序
二叉树遍历的java实现
package BinaryTree;
import java.util.ArrayList;
import java.util.List;
public class Tree {
private Node root;
private List<Node> list = new ArrayList<Node>();
public Tree(){
init();
}
//定义节点类,内部类
public class Node {
private String data;
private Node lchild;//定义指向左子树的指针
private Node rchild;//定义指向右子树的指针
public Node(String data, Node lchild,Node rchild){
this.data = data;
this.lchild = lchild;
this.rchild = rchild;
}
}
//树的初始化;先从叶子节点开始,由叶到根
public void init(){
Node x = new Node("X",null,null);
Node y = new Node("y",null,null);
Node d = new Node("d",x,y);
Node e = new Node("e",null,null);
Node f = new Node("f",null,null);
Node c = new Node("c",e,f);
Node b = new Node("b",d,null);
Node a = new Node("a",b,c);
root = a;
}
/*
* 对该二叉树进行前序遍历, 结果存储到list中,前序遍历:
* */
public void preOrder(Node node){
//存储根节点
list.add(node);
//如果左子树不为空继续往左找,在递归调用方法的时候一直会
//将子树的根存入list,这就做到了先遍历根节点
if(node.lchild !=null){
preOrder(node.lchild);
}
//无论走到哪一层,只要当前节点左子树为空,那么就可以在右子树
//上遍历,保证了根左右的遍历顺序
if(node.rchild!=null){
preOrder(node.rchild);
}
}
/*
* 对该二叉树进行中序遍历,结果存储到list中
* */
public void inOrder(Node node){
if(node.lchild !=null){
preOrder(node.lchild);
}
list.add(node);
if(node.rchild!=null){
preOrder(node.rchild);
}
}
/*
*对该二叉树进行后序遍历,结果存储到list中
* */
public void postOrder(Node node){
if(node.lchild!=null){
postOrder(node.lchild);
}
if(node.rchild!=null){
postOrder(node.rchild);
}
list.add(node);
}
/*
* 返回当前树的深度
* 说明:
* 1、如果一棵树只有一个结点,它的深度为1。
* 2、如果根结点只有左子树而没有右子树,那么树的深度是其左子树的深度加1;
* 3、如果根结点只有右子树而没有左子树,那么树的深度应该是其右子树的深度加1;
* 4、如果既有右子树又有左子树,那该树的深度就是其左、右子树深度的较大值再加1。
*
* */
public int getTreeDepth(Node node){
if(node.lchild ==null && node.rchild==null){
return 1;
}
int left=0, right=0;
if(node.lchild!=null){
left = getTreeDepth(node.lchild);
}
if(node.rchild!=null){
right = getTreeDepth(node.rchild);
}
return left>right?left+1:right+1;
}
//得到遍历结果
public List<Node> getResult(){
return list;
}
public static void main(String[] args){
Tree tree = new Tree();
System.out.println("根节点是:"+tree.root);
tree.preOrder(tree.root);
// tree.postOrder(tree.root);
for(Node node:tree.getResult()){
System.out.println(node.data);
}
System.out.println("树的深度是:"+tree.getTreeDepth(tree.root));
}
}
二叉树的堆遍历实现:
package BinaryTree;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import BinaryTree.Tree.Node;
public class Binarytrees {
//private Node root;
//private List<Node> list = new ArrayList<Node>();
public Binarytrees(){
init();
}
public class Node {
private String data;
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
public Node getLchild() {
return lchild;
}
public void setLchild(Node lchild) {
this.lchild = lchild;
}
public Node getRchild() {
return rchild;
}
public void setRchild(Node rchild) {
this.rchild = rchild;
}
private Node lchild;//定义指向左子树的指针
private Node rchild;//定义指向右子树的指针
public Node(String data, Node lchild,Node rchild){
this.data = data;
this.lchild = lchild;
this.rchild = rchild;
}
}
public Node init(){
Node a = new Node("8",null,null);
Node b = new Node("7",null,null);
Node c = new Node("6",null,null);
Node d = new Node("5",null,a);
Node e = new Node("4",b,null);
Node f = new Node("3",null,c);
Node g = new Node("2",d,e);
Node h = new Node("1",g,f);
root = h;
return h;
}
public void printNode(Node node){
System.out.println(node.getData());
}
public void theFirststack(Node root){
Stack<Node> stack = new Stack<Node>();
Node node = root;
while (node != null||stack.size()>0){
if(node!=null){
printNode(node);
stack.push(node);
node = node.getLchild();
}else{
node = stack.pop();
node = node.getRchild();
}
}
}
public void theInOrderStack(Node root){
Stack<Node> stack = new Stack<Node>();
Node node = root;
while (node != null||stack.size()>0){
if(node!=null){
stack.push(node);
node = node.getLchild();
}else{
node = stack.pop();
printNode(node);
node = node.getRchild();
}
}
}
public void thePostOrder(Node root){
Stack<Node> stack = new Stack<Node>();
Stack<Node> output = new Stack<Node>();
Node node = root;
while(node!=null || stack.size() >0){
if(node!=null){
output.push(node);
stack.push(node);
node = node.getRchild();
}else{
node = stack.pop();
node = node.getLchild();
}
}
//System.out.println(output.size());
while(output.size()>0){
printNode(output.pop());
}
}
public static void main(String[] args){
Binarytrees tree = new Binarytrees();
Node root = tree.init();
System.out.println("the first order");
tree.theFirststack(root);
System.out.println("the inorder");
tree.theInOrderStack(root);
System.out.println("the post order");
tree.thePostOrder(root);
}
}