什么是二叉树:
二叉树是每个结点最多有两个结点的树结构。如下就是一颗树结构。
二叉树可以做什么:
用的最多的是二叉平衡树,有种特殊的二叉平衡树就是红黑树,Java集合中的TreeSet和TreeMap,C++STL中的set,map以及LInux虚拟内存的管理,都是通过红黑树去实现的,还有哈弗曼树编码方面的应用,以及B-Tree,B+-Tree在文件系统中的应用。当然二叉查找树可以用来查找和排序。
二叉树的分类:
满二叉树: 从高到低,除了叶子结点外,所有结点左右子节点都在。
完全二叉树: 比满二叉树少几个叶结点,从左往右放
平衡二叉树: 空树或者它的左右两个子树的高度差绝对值不超过1,左右两个子树也是平衡树
二叉搜索树: 又叫二叉排序树,定义是空树或者二叉树的所有结点比他的左子结点大,比他右子结点小
红黑树: 具有二叉搜索树,平衡树的属性,有序且子树高度差不超过1。颜色规则:根节点和特殊节点是黑色,红结点的左右节点是黑色,对于每个节点,从该节点到子孙叶节点所有路径包含相同数目的黑节点。五分钟搞懂什么事红黑树
二叉树优势:
二叉树也是一种常用的数据结构。有序数组的优势在于二分查找,链表的优势在于数据项的插入和数据项的删除。但是在有序数组中插入数据就会很慢,同样在链表中查找数据项效率就很低。而二叉树合并有序数组和链表的优势。有序二叉树具有对数查找效率;二叉树有链表特征。
二叉树的遍历
前序遍历(根-左-右):ABDGHECKFIJ
中序遍历(左-根-右):GDHBEAKCIJF
后序便利(左-右-根):GHDEBKJIFCA
二叉树遍历代码实现:
递归:
class Node {
int value;
Node left;
Node right;
public Node(int value){
this.value = value;
}
}
public void preTraversal(Node head){ //前序遍历
if(head == null){
return;
}
System.out.print(head.value + " ");
preTraversal(head.left);
preTraversal(head.right);
}
public void inTraversal(Node head){ //中序遍历
if(head == null){
return;
}
inTraversal(head.left);
System.out.print(head.value + " ");
inTraversal(head.right);
}
public void postTraversal(Node head){ //后序遍历
if(head == null){
return;
}
postTraversal(head.left);
postTraversal(head.right);
System.out.print(head.value + " ");
}
非递归版:后序遍历两种非递归实现
public void preTraversalUnRecur(Node head){ //前序遍历
if(head != null){
Stack<Node> s = new Stack<Node>();
s.push(head);
while(!s.isEmpty()){
Node n = s.pop();
System.out.print(p.value + " ");
if(n.right!= null){
s.push(n.right);
}
if(n.left!=null){
s.push(n.left);
}
}
}
}
public void inTraversalUnRecur(Node head){ //中序遍历
if(head != null){
Stack<Node> s = new Stack<Node>();
while(!s.isEmpty() || head != null){
if(head!= null){
s.push(head);
head = head.left;
}else{
head = s.pop();
System.out.print(head.value + " ");
head = head.right;
}
}
}
}
public void postTraversalUnRecur1(Node head){ //后序遍历1
if(head != null){
Stack<Node> s1 = new Stack<Node>();
Stack<Node> s2 = new Stack<Node>(); //创建两个堆栈,s2保存后序遍历顺序的节点
s1.push(head);
while(!s1.isEmpty()){
Node n = s1.pop();
s2.push(n);
if(n.left != null){
s1.push(n.left);
}
if(n.right !=null){
s1.push(n.right);
}
}
while(!s2.isEmpty()){
System.out.print(s2.pop().value + " ");
}
}
}
public void postTraversalUnRecur2(Node head){ //后序遍历2
if(head != null){
Stack<Node> s1 = new Stack<Node>();
s1.push(head);
Node c = null;
while(!s1.isEmpty() ){
c = s1.peek();
if( c.left != null && head != c.left && head != c.right){
s1.push(c.left); //没有遍历过,才加入到堆栈中
} else if(c.right != null && head != c.right){
s1.push(c.right);//没有遍历过,才加入到堆栈中
} else { //没有子节点,才打印出来
System.out.print(s1.pop().value + " ");
head = c; //head做为子节点
}
}
}
}