数据结构 二叉树的建立和递归遍历

一、二叉树的建立

1.1 概念

每一个节点最多有两个节点的树

1.2 二叉树的建立

普通节点
节点的权值: int value
左子节点 : node Lnode;
右子节点 : node rnode;

package imitate_tree;

public class node {
	int value;
	node Lnode;
	node Rnode;

	public int getValue() {
		return value;
	}

	public void setValue(int value) {
		this.value = value;
	}

	public node getLnode() {
		return Lnode;
	}

	public void setLnode(node Lnode) {
		this.Lnode = Lnode;
	}

	public node getRnode() {
		return Rnode;
	}

	public void setRnode(node Rnode) {
		this.Rnode = Rnode;
	}

	public node(int value) {
		this.value = value;
	}

}

  • 二叉树的建立是递归建立
    在这里插入图片描述
public static TreeNode reConstructBinaryTree (int[] preOrder, int[] vinOrder) {
        // write code here
        if (preOrder.length == 0 || vinOrder.length == 0) {
            return null;
        }
        int num = preOrder[0];
        TreeNode treeNode = new TreeNode(num);
        int index = 0;
        for (int i = 0; i < vinOrder.length; i++) {
            if (vinOrder[i] == num) {
                index = i;
                break;
            }
        }
        treeNode.left = reConstructBinaryTree(Arrays.copyOfRange(preOrder, 1,
                index + 1), Arrays.copyOfRange(vinOrder, 0, index));
        treeNode.right = reConstructBinaryTree(Arrays.copyOfRange(preOrder, index + 1,
                preOrder.length), Arrays.copyOfRange(vinOrder, index + 1, vinOrder.length));
        return treeNode;
    }

二、二叉树的遍历

2.1先序遍历

遍历顺序
根节点 左子节点 右子节点

public static void font_sort(node root){
		if(root != null){
			System.out.print(root.value + " ");
		}
		if(root.Lnode != null){
			font_sort(root.Lnode);
		}
		if(root.Rnode != null){
			font_sort(root.Rnode);
		}
	}

2.2 中序遍历

遍历顺序
左子节点 根节点 右子节点

public static void middle_sort(node root){
		if(root.Lnode != null){
			middle_sort(root.Lnode);
		}
		System.out.print(root.value + " ");
		if(root.Rnode != null){
			middle_sort(root.Rnode);
		}
	}

2.3 后序遍历

遍历顺序
左子节点 右子节点 根节点

public static void after_sort(node root){
		if(root.Lnode != null){
			after_sort(root.Lnode);
	    }
		if(root.Rnode != null){
			after_sort(root.Rnode);
		}
		System.out.print(root.value + " ");
  }

2.4 测试

public static void main(String[] args) {
		 node root = new node(1);
		  root root1 = new root();
		  root1.setRoot(root);
		  node node = new node(3);
		  node node1 = new node(2);
		  node node2 = new node(4);
		  node node3 = new node(5);
		  node node4 = new node(6);
		  root.setLnode(node1);
		  root.setRnode(node);
		  node.setLnode(node2);
		  node1.setLnode(node3);
		  node1.setRnode(node4);
		  System.out.println("先序遍历结果:");
		  font_sort(root);
		  System.out.println();
		  System.out.println("中序遍历结果");
		  middle_sort(root);
		  System.out.println();
		  System.out.println("后序遍历结果");
		  after_sort(root);
	}
结果:
先序遍历结果:
1 2 5 6 3 4 
中序遍历结果
5 2 6 1 4 3 
后序遍历结果
5 6 2 4 3 1 

2.5 结论

二叉树的递归遍历比较难理解,先序遍历比较容易理解,中序和后续比较难理解,中序和后续遍历可以看成对叶子结点的操作,比如:中序遍历,先遍历该节点的左子节点,左子节点为空,输出该节点的值,再遍历右子节点。

三、二叉树的查找

3.1 难点

用递归查找,需要有递归出口。

3.2 先序查找

public node fontReserch(int i){
        node flag = null;
        //falg标志,默认值为null,表示未查到。
		if(this.value == i){
			return this;
		}
		//根节点的值符合要求就返回。
		else{
			if(Lnode != null){
				flag = Lnode.fontReserch(i);
			}
			if(flag != null){
				return flag;
				//左子节点的值符合要求,返回
			}
			//再查看右子节点
			if(Rnode != null){
				flag = Rnode.fontReserch(i);
			}
		}
		return flag;		  
    }

示例:

 System.out.println(root.fontReserch(3));
 System.out.println(root.fontReserch(7));
 
 结果:
	imitate_tree.node@15db9742
	null

3.3 中序查找

public node middleSearch(int value){
		node flag = null;
		if(this.Lnode != null){
			//flag是判断的结果
          flag = Lnode.middleSearch(value);
		}
		if(flag != null){
			return flag;
		}
		else{
			//this不是判断的结果,需要用值取比较
			if(this.value == value){
				return this;
			}
			if(Rnode != null){
				//拿到判断的结果
				flag = Rnode.middleSearch(value);
			}
		}
		return flag;			
	}

测试:

System.out.println(root.middleSearch(3));
System.out.println(root.middleSearch(9));

结果:
imitate_tree.node@15db9742
null

3.4 后序查找

public node afterSearch(int value){
		node flag = null;
	if(this.Lnode != null){
		flag = Lnode.afterSearch(value);
	}
	if(flag != null){
		return flag;
	}
	else{
		if(this.Rnode != null){
			flag = Rnode.afterSearch(value);
		}
		if(flag != null){
			return flag;
		}
		if(this.value == value){
			return this;
		}
	}
	return flag;
  }

测试:

System.out.println(root.afterSearch(6));
System.out.println(root.afterSearch(7));

解果:
imitate_tree.node@6d06d69c
null

3.5 总结

设置一个标志,用来记录查找的结果,找到就返回找到的节点,未找见就返回空。
二叉树的查找还是用根节点来判断,其他的就是去拿根节点的返回值。

四、节点的删除

4.1 注意

节点的删除主要是在普通节点的方法里实现,由根节点去调用节点的删除方法,然后加上根节点的判空方法。
节点的删除和正常思路一样,判断左子节点,右子节点,判断左子树,判断右子树。
不用递归遍历的方法去做删除的原因是this 不能指向空。因为赋值式的左边必须是一个变量。

普通节点实现删除方法:

public void deleteNode(int value) {
		node root = this;
		// 判断左子树
				if (root.Lnode != null && Lnode.value == value) {
					Lnode = null;
					return;
				}
				// 判断右子树
				if (root.Rnode != null && Rnode.value == value) {
					Rnode = null;
					return;
				}
				// 递归判断左子树
				root = Lnode;
				if (Lnode != null) {
					Lnode.deleteNode(value);
				}
				root = Rnode;
				if (Rnode != null) {	
					Rnode.deleteNode(value);
				}
			}
	    }

根节点调用delete方法:

 public void delete(int value){
	   if(root.value == value){
		   root = null;
		   return;
	   }
	   else 
	   {
		   root.deleteNode(value);
	   }
   }

4.2 测试

root1.delete(2);
root1.fontSort();

结果

1
3
4
二叉树是一种广泛应用于计算机科学中的数据结构,用于存储有层次关系的数据。下面介绍两种建立二叉树的方法。 1. 递归建树 递归建树是一种比较简单的方法,其基本思路是: - 如果当前节点为空,则创建一个新节点并将数据赋值给它; - 如果当前节点不为空,则比较待插入数据和当前节点的大小,如果待插入数据比当前节点小,则递归调用左子树,否则递归调用右子树。 下面是递归建树的示例代码: ```python class TreeNode: def __init__(self, val): self.val = val self.left = None self.right = None def insert(root, val): if root is None: return TreeNode(val) if val < root.val: root.left = insert(root.left, val) else: root.right = insert(root.right, val) return root ``` 2. 迭代建树 迭代建树是一种较为复杂的方法,需要利用栈来辅助建立二叉树。其基本思路是: - 创建一个空根节点,将待插入数据赋值给根节点; - 从第二个数据开始遍历,对于每个数据,依次与根节点比较大小,如果比根节点小,则作为左子树的根节点,否则作为右子树的根节点; - 使用一个栈来保存访问过的节点,每次访问节点时将其入栈; - 如果当前节点为空,则从栈中弹出一个节点作为当前节点。 下面是迭代建树的示例代码: ```python class TreeNode: def __init__(self, val): self.val = val self.left = None self.right = None def insert(root, val): if root is None: return TreeNode(val) stack = [root] while stack: node = stack.pop() if val < node.val: if node.left is None: node.left = TreeNode(val) break else: stack.append(node.left) else: if node.right is None: node.right = TreeNode(val) break else: stack.append(node.right) return root ``` 以上两种方法都可以用于建立二叉搜索树,其中递归建树是更为常见的方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值