二叉树节点结构
class Node<V>{
V value;
Node left;
Node right;
}
最顶上的节点叫根节点,没有子节点的叫叶子节点
为递归序加工所得,即递归遍历时第一次来到该节点时打印,其余两次什么也不做。
为递归序加工所得,即递归遍历时第二次来到该节点时打印,其余两次什么也不做。
为递归序加工所得,即递归遍历时第三次来到该节点时打印,其余两次什么也不做。
public static class Node{
public int value;
public Node left;
public Node right;
public Node(int data){this.value = data;}
}
//递归先序遍历
public static void preOrderRecur(Node head){
if (head == null){
return;
}
System.out.println(head.value + " ");
preOrderRecur(head.left);
preOrderRecur(head.right);
}
//递归中序遍历
public static void inOrderRecur(Node head){
if (head == null){
return;
}
inOrderRecur(head.left);
System.out.println(head.value + " ");
inOrderRecur(head.right);
}
//递归后序遍历
public static void posOrderRecur(Node head){
if (head == null){
return;
}
posOrderRecur(head.left);
posOrderRecur(head.right);
System.out.println(head.value + " ");
}
任何递归都可以改成非递归,
//非递归先序遍历
public static void preOrderUnRecur(Node head){
if (head != null){
Stack<Node> stack = new Stack<>();
stack.push(head);
while (!stack.isEmpty()){
head = stack.pop();
System.out.println(head.value);
if (head.right != null){
stack.push(head.right);
}
if (head.left != null){
stack.push(head.left);
}
}
}
}
public static void posOrderUnRecur1(Node head){
if (head != null){
Stack<Node> stack1 = new Stack<>();//放入的栈
Stack<Node> stack2 = new Stack<>();//收集的栈
stack1.add(head);
while (!stack1.isEmpty()){
head =stack1.pop();
stack2.add(head);
if (head.left != null){
stack1.add(head.left);
}
if (head.right != null){
stack1.add(head.right);
}
}
while (!stack2.empty()){
System.out.print(stack2.pop().value + " ");
}
}
System.out.println();
}
public static void inOrderUnRecur(Node head){
Stack<Node> stack1 = new Stack<>();
if (head != null){
while (!stack1.isEmpty() || head != null) {//只要左边界上的数不为null则全部放入栈中
if (head != null) {
stack1.add(head);
head = head.left;
}else {//否则就弹出,并去找右边再去找对应的右边界
head = stack1.pop();
System.out.print(head.value + " ");
head = head.right;
}
}
}
System.out.println();
}
老师给的福利函数,直接可以打印二叉树结构,旋转90度即可
public static class Node {
public int value;
public Node left;
public Node right;
public Node(int data) {
this.value = data;
}
}
public static void printTree(Node head) {
System.out.println("Binary Tree:");
printInOrder(head, 0, "H", 17);
System.out.println();
}
public static void printInOrder(Node head, int height, String to, int len) {
if (head == null) {
return;
}
printInOrder(head.right, height + 1, "v", len);
String val = to + head.value + to;
int lenM = val.length();
int lenL = (len - lenM) / 2;
int lenR = len - lenM - lenL;
val = getSpace(lenL) + val + getSpace(lenR);
System.out.println(getSpace(height * len) + val);
printInOrder(head.left, height + 1, "^", len);
}
public static String getSpace(int num) {
String space = " ";
StringBuffer buf = new StringBuffer("");
for (int i = 0; i < num; i++) {
buf.append(space);
}
return buf.toString();
}
深度优先遍历即先序遍历
宽度优先遍历:需要准备一个队列,先把头节点放入,之后取出后,再把其左节点放进去,之后再把其右节点放进去,重复此过程。
public static void widthOrder(Node head){
Queue<Node> queue = new LinkedList<>();
if (head == null){
return;
}
queue.add(head);
while (!queue.isEmpty()){
Node cur = queue.poll();
System.out.println(cur.value);
if (cur.left != null){
queue.add(cur.left);
}
if (cur.right != null){
queue.add(cur.right);
}
}
在宽度优先遍历的基础上设定三个变量最大宽度,当前层宽度,当前层。利用hash表,先将头节点及其层1放入,然后开始利用队列进行宽度优先遍历,利用头节点在HashMap中放入其左节点和层数,其右节点和层数,对每个遍历到的节点判断其层数与当前层是否相同,不同则是当前层宽度置为0,相同则当前层宽度++。更新最大宽度,最后返回最大宽度。
public static int getBigWidth(Node head){
if (head == null){
return 0;
}
HashMap<Node , Integer> hashMap = new HashMap<>();
Queue<Node> queue = new LinkedList<>();
hashMap.put(head,1);
queue.add(head);
int maxWidth = 0;
int curLevel = 0;
int curWidth = 0;
while (!queue.isEmpty()){
head = queue.poll();
if (head.left != null){
queue.add(head.left);
hashMap.put(head.left,hashMap.get(head) + 1);
}
if (head.right != null){
queue.add(head.right);
hashMap.put(head.right,hashMap.get(head) + 1);
}
if (curLevel <= hashMap.get(head)){
curWidth = 0;
curLevel = hashMap.get(head);
}else {
curWidth ++;
}
maxWidth = Math.max(curWidth,maxWidth);
}
return maxWidth;
}