最近找实习,觉得需要记录一下自己学习的内容。第一次写博客,但愿有个好的开始。
前天去华为面试,面了50分钟,最后败倒在一棵树下(当时遍历反了,从root往子节点遍历,其实是从子节点向上遍历),好傻,都怪自己平时写代码比较少,代码这种东西,还是得多练。
二叉树:如果只有一个节点,那么这个节点就是根节点;如果不只一个节点,那么它的左子树和右子树都是一棵二叉树。这是二叉树的递归定义。
二叉树的建立,从根开始,先来看看普通的二叉树的建立(非排序),用for循环即可。如下(这个方法参考自http://ocaicai.iteye.com/blog/1047397,此博主写的很详细)。
<span style="white-space:pre"> </span>/**
* for循环遍历建树,此方法建的不是排序树
* @param array
* @return
*/
public Node creatBinaryTreeFor(int[] array){
List<Node> nodeList = new LinkedList<Node>();
//将数组中的数字转换为node.
for (int i = 0; i < array.length; i++) {
nodeList.add(new Node(array[i]));
}
for (int parentIndex = 0; parentIndex < nodeList.size()/2 - 1; parentIndex++) {
nodeList.get(parentIndex).leftChild = nodeList.get(parentIndex*2 +1);
nodeList.get(parentIndex).rightChild = nodeList.get(parentIndex*2 +2);
}
int lastParentNode = nodeList.size()/2 -1;
nodeList.get(lastParentNode).leftChild = nodeList.get(lastParentNode*2 + 1);
if (nodeList.size()%2 == 1) {
nodeList.get(lastParentNode).rightChild = nodeList.get(lastParentNode*2 + 2);
}
return nodeList.get(0);
}
然后看看二叉排序树的建立,虽然采用递归,但是一次只能建一个节点,可以在main函数里循环调用这个递归函数。
递归方法如下(此方法参考自http://blog.csdn.net/yhhazr/article/details/7944089,哎呀,现在这种方法基本都定型了,我仅引用我参考的这个,至于这个方法原创是谁,不去追究)。
<span style="white-space:pre"> </span>/**
* 递归构建二叉排序树
* @param node
* @param data
*/
public void creatBinaryTree(Node node, int data){
if (node == null) {
node = new Node(data);
}else {
if (data < node.data) {
if (node.leftChild == null) {
node.leftChild = new Node(data);
}else {
creatBinaryTree(node.leftChild, data);
}
}else {
if (node.rightChild == null) {
node.rightChild = new Node(data);
}else {
creatBinaryTree(node.rightChild, data);
}
}
}
}
然后看看遍历,包括前序遍历,中序遍历和后序遍历。
中序遍历:先遍历左子树,再访问根节点,最后遍历右节点。看代码:
<span style="white-space:pre"> </span>/**
* 中序遍历
* @param node
*/
public List inOrderTranverse(Node node){
List<Integer> list = new ArrayList<Integer>();
if (node != null) {
list.addAll(inOrderTranverse(node.leftChild));
list.add(node.data);
list.addAll(inOrderTranverse(node.rightChild));
}
return list;
}
上面这个方法返回的是中序遍历的序列,如果是二叉排序树,那么这个序列刚好是有序的,也就是利用二叉树实现排序的就是它了。
再看前序和后序遍历:
<span style="white-space:pre"> </span>/**
* 前序遍历
* @param node
*/
public void preOderTranverse(Node node){
if (node != null) {
System.out.println(node.data);
preOderTranverse(node.leftChild);
preOderTranverse(node.rightChild);
}
}
/**
* 后序遍历
* @param node
*/
public void postOrderTranverse(Node node){
if (node != null) {
postOrderTranverse(node.leftChild);
postOrderTranverse(node.rightChild);
System.out.println(node.data);
}
}
前序和后序没有返回值,但是在遍历的时候把遍历的值打印了出来。
然后是main方法:
public static void main(String[] args) {
int[] a = {1,2,3,4,5,6,3,7,8,9,12,0,10};
BinaryTree bt = new BinaryTree();
// Node root = bt.creatBinaryTreeFor(a);
// bt.preOderTranverse(root);
// bt.inOrderTranverse(root);
Node root = bt.new Node(a[0]);
for (int i = 1; i < a.length; i++) {
bt.creatBinaryTree(root, a[i]);
}
List list = bt.inOrderTranverse(root);
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
}
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class BinaryTree {
/**
* 内部类,表示树的一个节点的数据结构
* 左孩子,右孩子,data.
* @author mzdong
*
*/
private class Node{
private Node leftChild;
private Node rightChild;
private int data;
public Node(int data){
this.leftChild = null;
this.rightChild = null;
this.data = data;
}
}
/**
* for循环遍历建树,此方法建的不是排序树
* @param array
* @return
*/
public Node creatBinaryTreeFor(int[] array){
List<Node> nodeList = new LinkedList<Node>();
//将数组中的数字转换为node.
for (int i = 0; i < array.length; i++) {
nodeList.add(new Node(array[i]));
}
for (int parentIndex = 0; parentIndex < nodeList.size()/2 - 1; parentIndex++) {
nodeList.get(parentIndex).leftChild = nodeList.get(parentIndex*2 +1);
nodeList.get(parentIndex).rightChild = nodeList.get(parentIndex*2 +2);
}
int lastParentNode = nodeList.size()/2 -1;
nodeList.get(lastParentNode).leftChild = nodeList.get(lastParentNode*2 + 1);
if (nodeList.size()%2 == 1) {
nodeList.get(lastParentNode).rightChild = nodeList.get(lastParentNode*2 + 2);
}
return nodeList.get(0);
}
/**
* 递归构建二叉排序树
* @param node
* @param data
*/
public void creatBinaryTree(Node node, int data){
if (node == null) {
node = new Node(data);
}else {
if (data < node.data) {
if (node.leftChild == null) {
node.leftChild = new Node(data);
}else {
creatBinaryTree(node.leftChild, data);
}
}else {
if (node.rightChild == null) {
node.rightChild = new Node(data);
}else {
creatBinaryTree(node.rightChild, data);
}
}
}
}
/**
* 前序遍历
* @param node
*/
public void preOderTranverse(Node node){
if (node != null) {
// System.out.println(node.data);
preOderTranverse(node.leftChild);
preOderTranverse(node.rightChild);
}
}
/**
* 后序遍历
* @param node
*/
public void postOrderTranverse(Node node){
if (node != null) {
postOrderTranverse(node.leftChild);
postOrderTranverse(node.rightChild);
System.out.println(node.data);
}
}
/**
* 中序遍历
* @param node
*/
public List inOrderTranverse(Node node){
List<Integer> list = new ArrayList<Integer>();
if (node != null) {
list.addAll(inOrderTranverse(node.leftChild));
list.add(node.data);
list.addAll(inOrderTranverse(node.rightChild));
}
return list;
}
public static void main(String[] args) {
int[] a = {1,2,3,4,5,6,3,7,8,9,12,0,10};
BinaryTree bt = new BinaryTree();
// Node root = bt.creatBinaryTreeFor(a);
// bt.preOderTranverse(root);
// bt.inOrderTranverse(root);
Node root = bt.new Node(a[0]);
for (int i = 1; i < a.length; i++) {
bt.creatBinaryTree(root, a[i]);
}
List list = bt.inOrderTranverse(root);
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
}
}