【二叉树基本概念】
二叉树基本概念:
1) 节点的度。节点所拥有子树的个数称为该节点的度。
2) 叶节点。度为0的节点。
3) 分支节点。度不为0的节点。
4) 节点的层数。规定树的根节点层数为1,其余节点的层数为其双亲节点的层数+1。
5) 树的深度。树中所有节点的最大层数为树的深度。
6) 树的度。树中各节点度的最大值为该树的度。
7) 满二叉树。在一棵二叉树中,所有分支节点都有左子树和右子树,且所有叶节点在同一层上。
8) 完全二叉树。一个深度为k有n个节点的二叉树,对树中的节点从上到下从左到右的顺序进行编号,若编号i
的节点与满二叉树中编号为i的节点位置相同,那么这棵二叉树被称为完全二叉树。
1) 一棵非空二叉树的第i层上最多有2^(i-1)个节点。(i>=1)
2) 一棵深度为k的二叉树中,最多具有2^k-1个节点,最少有k个节点。
3) 对于一棵非空二叉树,叶节点数n0(度为0的节点),总比度为2的节点n2数多一个。即n0=n2+1;
(二叉树总的节点数n,叶节点数为n0,度为1的节点数n1,度为2的节点数n2) n=n0+n1+n2;
二叉树性质:n=所有节点读书之和+1,即n=n1+2*n2+1 由上两式得:n0 = n2 + 1
4) 具有n个节点的完全二叉树的深度为[log2 n] + 1
5) 对于具有n个节点的完全二叉树,若编号从1开始,则对于任一的序号为i的节点:
若i>1,那么序号i的双亲节点为i/2(整除);若i=1,则此节点为根节点,无双亲节点。
序号为i的节点的 左孩子序号为2*i(2*i<=n), 右孩子的序号为2*+1(2*i+1<=n)
若编号从0开始,则对于任一的序号为i的节点:那么,序号i的双亲节点为(i-1)/2,左孩子的编号为2*i+1,
右孩子的编号为2*i+2.
排序二叉树:
1) 若左子树不为空,那么左子树上所有节点的值均小于它根节点的值。
2) 若右子树不为空,那么右子树上所有节点的值均大于它根节点的值。
【树】
运用:递归、非递归实现先中后序遍历
代码:
// 递归实现--先序遍历
public void preOrderrecur(Node head) {
if(head == null) { return ;}
System.out.print(head.value+" ");
preOrderrecur(head.left);
preOrderrecur(head.right);
}
// 非递归实现--先序遍历
public void preOrderUnrecur(Node head) {
System.out.print("pre--Order"+" ");
if(head != null) {
Stack<Node> stack = new Stack<Node>(); // 申请一个栈
stack.push(head); // 将根节点压入栈中
while(!stack.isEmpty()) { // 条件-栈不为空
head = stack.pop(); // 抛出栈顶节点
System.out.print(head.value+" "); // 打印该节点
// 注意顺序不可变
if(head.right != null) { stack.push(head.right); } // 若有右节点,先存右节点
if(head.left != null) { stack.push(head.left); }
}
}
System.out.println();
}
// 递归实现--中序遍历
public void inOrderrecur(Node head) {
if(head == null) {return ;}
inOrderrecur(head.left);
System.out.print(head.value+" ");
inOrderrecur(head.right);
}
// 非递归实现--中序遍历
public void inOrderUnrecur(Node head){
System.out.print("in -- Order"+" ");
if(head != null) {
Stack<Node> stack = new Stack<Node>(); // 申请栈
while(!stack.isEmpty() || head != null) {
if(head != null) { // head 不为空时,将head存储到栈中,继续往左走。
stack.push(head);
head = head.left;
}else{ // head 为空时, 从栈中弹出一个元素,并打印,往右走。
head = stack.pop();
System.out.print(head.value+" ");
head = head.right;
}
}
}
System.out.println();
}
// 递归实现--后序遍历
public void posOrderrecur(Node head) {
if(head == null) {return ;}
posOrderrecur(head.left);
posOrderrecur(head.right);
System.out.print(head.value+" ");
}
// 非递归实现--后序遍历
public void posOrderUnrecur(Node head) {
System.out.print("pos-order: "+" ");
if(head == null) { return; }
if(head != null) {
Stack<Node> stack = new Stack<Node>();
Stack<Node> stack1 = new Stack<Node>();
stack.push(head);
while(!stack.isEmpty()) {
head = stack.pop();
stack1.push(head);
if( head.left != null) {
stack.push(head.left);
}
if(head.right != null) {
stack.push(head.right);
}
}
while(!stack1.isEmpty()) {
System.out.print(stack1.pop().value+" ");
}
}
System.out.println();
}
// 层序遍历 使用队列来实现 先将 根节点 放入队列中,然后每次从队列中取出一个节点打印该节点,若该节点有子节点,
// 将子节点放入队尾,直到队列为空。
public void layerTranverse(Node root) {
if(root == null) { return; }
Queue<Node> queue = new LinkedList<Node>(); // 申请一个队列
queue.add(root); // 先将根节点放入队列
while(!queue.isEmpty()) {
Node node = queue.poll(); // 出队列
System.out.print(node.value+" ");
if(node.left != null) { // node左子树不为空,入队
queue.add(node.left);
}
if(node.right != null) { // node右子树不为空,入队
queue.add(node.right);
}
}
}