一、 二叉树的构建及其遍历.
编一个程序,读入用户输入的一串先序遍历字符串,根据此字符串建立一个二叉树(以指针方式存储)。 例如如下的先序遍历字符串: ABC##DE#G##F### 其中“#”表示的是空格,空格字符代表空树。建立起此二叉树以后,再对二叉树进行中序遍历,输出遍历结果。
输入
abc##de#g##f###
输出
c b e g d f a
通过遍历字符串中的字符来创建节点,遇到#就向后移动,直到返回null结束。
import java.util.*;
class Node {
public char val;
public Node left;
public Node right;
public Node(char ch){
this.val = ch;
}
}
public class Main{
static int i = 0;
public static void main(String [] args){
Scanner in = new Scanner(System.in);
String str = in.nextLine();
Node root= CreateTree(str);
inorder(root);
}
static Node CreateTree(String str){
if(str == null) return null ;
Node node =null;
if(str.charAt(i) != '#'){
node = new Node(str.charAt(i));
i++;
node.left = CreateTree(str);
node.right = CreateTree(str);
}else
i++;
return node;
}
static void inorder(Node root){
if(root == null)
return ;
inorder(root.left);
System.out.print(root.val+" ");
inorder(root.right);
}
}
二、二叉树的层次遍历
用队列记录上层节点,通过for循环来遍历上层节点,若左孩子不为空将左孩子加入队列,后孩子不为空,将右孩子加入队列。当for循环结束结束本层打印,进行下层,直到队列中元素为空。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> list = new ArrayList<>();
if(root == null)
return list;
Queue<TreeNode> q = new LinkedList<>();
q.offer(root);
//将根先加入队列
while(!q.isEmpty()){
int size = q.size();
List<Integer> a = new ArrayList<>();
//循环每层的的结点个数
for(int i = 0;i<size;i++){
TreeNode cur = q.poll();
a.add(cur.val);
if(cur.left != null) q.offer(cur.left);
if(cur.right != null) q.offer(cur.right);
}
list.add(a);
}
return list;
}
}
三、 二叉树的最近公共祖先.
若根节点=p或q则输出根节点
若左子树为空,右子树不为空则输出右子树中的结点,反之输出左子树
若p在左子树,q在右子树中同样输出根节点,反义同样
若 pq不在同一棵树中返空
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root == null) return null;
if(root == p || root == q){
return root;
}
TreeNode left = lowestCommonAncestor(root.left,p,q);
TreeNode right = lowestCommonAncestor(root.right,p,q);
if(left != null && right != null){
return root;
}else if(left == null && right !=null) return right;
else if (left != null && right ==null) return left;
else return null;
}
}
四、二叉搜索树与双向链表.
二叉搜索树可通过中序遍历得到一条递增的序列,将二叉搜索树转变为排序的双向链表即可通过中序遍历修改节点的先后顺序即可得到结果
/**
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public TreeNode prev = null;
//通过修改left 和right 使之成为双向链表
//left代表前驱,right代表后继
public void inorder(TreeNode root){
if(root == null) return ;
inorder(root.left);
//遍历到左孩子为空,将次节点的前序置为空
root.left = prev;
if(prev !=null)
prev.right = root;
prev = root;//进行回指
inorder(root.right);
}
public TreeNode Convert(TreeNode pRootOfTree) {
if(pRootOfTree == null) return null;
inorder(pRootOfTree);
TreeNode head = pRootOfTree;
//树种的最左节点即为链表的开始位置
while(head.left !=null)
head = head.left;
return head;
}
}
五、前序和中序创建二叉树.
结合前序遍历和中序遍历的顺序找到根的位置和左右子树的位置,通过前序遍历顺序,从中序遍历序列中寻找根节点,依次递归处理左子树和右子树,直到begin > end 返回 null
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public int i = 0;
public TreeNode buildTree(int[] preorder, int[] inorder) {
if(preorder.length == 0 || inorder.length == 0)
return null;
return createInorder(preorder,inorder,0,inorder.length -1);
}
public TreeNode createInorder(int pre [],int [] post,int begin,int end){
if(begin > end) return null;
TreeNode root = new TreeNode(pre[i]);
int idx = find(post,begin,end,pre[i]);
i++;
root.left = createInorder(pre,post,begin,idx-1);
root.right = createInorder(pre,post,idx+1,end);
return root;
}
public int find (int post[], int begin ,int end ,int val){
for(int i= begin; i<= end;i++){
if(post[i] == val){
return i;
}
}
return -1;
}
}
六、中序和后序创建二叉树.
和上一题基本一样在后序遍历的序列中找到根节点,在中序遍历中找到根节点递归先遍历右子树再遍历左子树,依次执行即可。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public int idx = 0;
public TreeNode buildTree(int[] inorder, int[] postorder) {
if(inorder == null || postorder == null) return null;
if(inorder.length == 0 || postorder.length == 0) return null;
idx = postorder.length-1;
return createTree(inorder,postorder,0,postorder.length - 1);
}
public TreeNode createTree(int[] inorder,int postorder[],int beign,int end){
if(beign > end) return null;
TreeNode root = new TreeNode(postorder[idx]);
int mid = find(inorder,beign,end,postorder[idx]);
idx--;
root.right = createTree(inorder,postorder,mid + 1, end);
root.left = createTree(inorder,postorder,beign,mid - 1);
return root;
}
public int find(int[] inorder,int begin,int end,int val){
for( ;begin <= end;begin ++){
if(inorder[begin] == val)
return begin;
}
return -1;
}
}
七、二叉树与字符串.
此题需要结合用例分析,但看题目并不知道再讲什么。
经过分析可得
可分为1、左孩子为空 右孩子不为空 添加 ( )
2、左孩子为空右孩子不为空 返回
3、左孩子不为空 添加“(”,递归左子树
4、右孩子不为空 添加 “(”递归右子树
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
StringBuilder sb =new StringBuilder();
public String tree2str(TreeNode t) {
if(t== null) return "";
preorder(t);
return sb.toString();
}
public void preorder(TreeNode t){
if(t == null) sb.append(")");
if(t != null){
sb.append(t.val+"");
}
if(t.left == null){
if(t.right == null)
return;
else
sb.append("()");
}else{
sb.append("(");
preorder(t.left);
sb.append(")");
}
if(t.right != null){
sb.append("(");
preorder(t.right);
sb.append(")");
}
}
}