树定义
树是n个结点的有限集。n等于零时为空树。在任意一颗非空树中,有且仅有一个特定的称为根的结点。当n>1时,其余结点可分为m个互不相交的有限集,其中每个集合又是一颗树,并且称为根子树。
二叉树
n个结点的集合,该集合或者为空集,或者由一个根结点和两颗互不相交的,分别称为根节点的左子树与右子树的二叉树组成。
public class TreeNode {
//节点的权
int value;
//左节点
TreeNode leftNode;
//右节点
TreeNode rightNode;
public TreeNode(int value) {
this.value=value;
}
//获得左节点
public TreeNode getLeftNode() {
return leftNode;
}
public void setLeftNode(TreeNode leftNode) {
this.leftNode = leftNode;
}
public TreeNode getRightNode() {
return rightNode;
}
public void setRightNode(TreeNode rightNode) {
this.rightNode = rightNode;
}
}
public class BinaryTree {
//二叉树的结点
TreeNode root;
//创建根节点
public TreeNode getRoot() {
return root;
}
public void setRoot(TreeNode root) {
this.root = root;
}
public void frontshow(){
if(root!=null) root.frontshow();
}
}
前序遍历算法
public void frontshow() {
// TODO Auto-generated method stub
//打印当前值
System.out.println(value);
if(leftNode!=null) {
leftNode.frontshow();
}
if(rightNode!=null) {
rightNode.frontshow();
}
}
顺序存储的二叉树的前序遍历
public class ArrayTree {
int [] data;
public ArrayTree(int[] data) {
this.data=data;
}
public void frontshow(int index) {
if(data==null||data.length==0) return;
//输出当前结点
System.out.println(data[index]);
//遍历左子树
if(2*index+1<data.length) frontshow(2*index+1);
//遍历右子树
if(2*index+2<data.length)frontshow(2*index+2);
}
public static void main(String[] args) {
int[] a=new int[] {1,2,3,4,5,6,7};
ArrayTree tree=new ArrayTree(a);
tree.frontshow(0);
}
}
N叉树的前序遍历迭代
/*
// Definition for a Node.
class Node {
public int val;
public List<Node> children;
public Node() {}
public Node(int _val) {
val = _val;
}
public Node(int _val, List<Node> _children) {
val = _val;
children = _children;
}
};
*/
//
class Solution {
public List<Integer> preorder(Node root) {
//
LinkedList<Node> list=new LinkedList<Node>();
LinkedList<Integer> i=new LinkedList<>();
list.add(root);
if(root==null) return i;
while(!list.isEmpty()){
Node t=list.pollLast();
i.add(t.val);
//逆序放入
for(int j=t.children.size()-1;j>=0;j--){
if(t.children.get(j)!=null)
list.add(t.children.get(j));
}
}
return i;
}
}
中序遍历
public void midfront() {
// TODO Auto-generated method stub
if(leftNode!=null) {
leftNode.midfront();
}
System.out.println(value);
if(rightNode!=null) {
rightNode.midfront();
}
}
后序遍历算法
public void aftershow() {
// TODO Auto-generated method stub
if(leftNode!=null) {
leftNode.aftershow();
}
if(rightNode!=null) {
rightNode.aftershow();
}
System.out.println(value);
}
N叉树的后序遍历迭代
/*
// Definition for a Node.
class Node {
public int val;
public List<Node> children;
public Node() {}
public Node(int _val) {
val = _val;
}
public Node(int _val, List<Node> _children) {
val = _val;
children = _children;
}
};
*/
//
class Solution {
public List<Integer> postorder(Node root) {
LinkedList<Node> stack = new LinkedList<>();
LinkedList<Integer> output = new LinkedList<>();
if (root == null) {
return output;
}
stack.add(root);
while (!stack.isEmpty()) {
Node node = stack.pollLast();
//结果要倒过来
output.addFirst(node.val);
for (Node item : node.children) {
if (item != null) {
stack.add(item);
}
}
}
return output;
}
}
完全二叉树层次遍历
public void bfs() {
// TODO Auto-generated method stub
LinkedList<TreeNode> queue=new LinkedList();
queue.add(this);
while(!queue.isEmpty()) {
TreeNode t=queue.poll();
System.out.println(t.value);
if(t.leftNode!=null) queue.add(t.leftNode);
if(t.rightNode!=null) queue.add(t.rightNode);
}
}
由中序遍历与后序遍历求先序遍历
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
//in为中序排列 after为后序排列
void beford(string in,string after){
if (in.size()>0){
//后序排列的第一个为根
char ch=after[after.size()-1];
cout<<ch;//找根输出
// 在中序排列中找到位置 递归调用左子树与右子树
int k=in.find(ch);
beford(in.substr(0,k),after.substr(0,k));
beford(in.substr(k+1),after.substr(k,in.size()-k-1));
}
}
int main(){
string inord,aftord;
cin>>inord;
cin>>aftord;//读入
beford(inord,aftord);cout<<endl;
return 0;
}
由先序遍历与后序遍历求中序遍历
#include<iostream>
#include<string>
using namespace std;
string str1,str2;
//先中序 后前序
void maketree(string s,string t){
//
if(!(int)t.size()) return;
//
char ch=t[0];
//前序排列的第一个为根
int k=s.find(ch);
maketree(s.substr(0,k),t.substr(1,k));//递归左子树
maketree(s.substr(k+1),t.substr(k+1));//递归右子树
//最后输出根
cout<<ch;
}
int main(){
cin>>str1>>str2;
maketree(str1,str2);
return 0;
}
输入一串二叉树,输出其前序遍历。
6
abc
bdi
cj*
d**
i**
j**
输出
abdicj
前序遍历是先输出结点,再输出左右子树。
#include<iostream>
#include<string>
#include<cstring>//不加会CE
using namespace std;
int n;
string s;
int main()
{
cin>>n;
cin>>s;
for(int i=2;i<=n;++i)//由于第一个为原串,所以单独输入
{
string ss;
cin>>ss;
int x=s.find(ss[0]);//找到这个子树的根节点在原串中的位置
s.erase(x,1);//清除根节点
s.insert(x,ss);//加入子树
}
for(int i=0;i<s.size();++i)
if(s[i]!='*') cout<<s[i];//不输出空节点
else continue;
}
二叉树最大深度求解
树的深度为max(左子树深度,右子树深度)+1;
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
//int depth=1;
public int maxDepth(TreeNode root) {
if(root==null) return 0;
else return Math.max(maxDepth(root.left),maxDepth(root.right))+1;
}
}
最小深度
如果没有左右结点,就是叶子结点,返回一
class Solution {
public int minDepth(TreeNode root) {
if(root==null) return 0;
if(root!=null&&root.left==null&&root.right==null) return 1;
int mind=Integer.MAX_VALUE;
if(root.left!=null) mind=Math.min(minDepth(root.left),mind);
if(root.right!=null) mind=Math.min(minDepth(root.right),mind);
return mind+1;
}
}
广度优先搜索加迭代
class Solution {
public int minDepth(TreeNode root) {
LinkedList<Pair<TreeNode, Integer>> stack = new LinkedList<>();
if (root == null) {
return 0;
}
else {
stack.add(new Pair(root, 1));
}
int current_depth = 0;
while (!stack.isEmpty()) {
//取出结点
Pair<TreeNode, Integer> current = stack.poll();
root = current.getKey();
current_depth = current.getValue();
//如果找到了叶子结点就退出
if ((root.left == null) && (root.right == null)) {
break;
}
if (root.left != null) {
stack.add(new Pair(root.left, current_depth + 1));
}
if (root.right != null) {
stack.add(new Pair(root.right, current_depth + 1));
}
}
return current_depth;
}
}
请完成一个函数,输入一个二叉树,该函数输出它的镜像。
class Solution {
public TreeNode mirrorTree(TreeNode root) {
if(root == null) return null;
Stack<TreeNode> stack = new Stack<>(); stack.add(root);
//如果栈为空则弹出
while(!stack.isEmpty()) {
TreeNode node = stack.pop();
if(node.left != null) stack.add(node.left);
if(node.right != null) stack.add(node.right);
//交换左右结点
TreeNode tmp = node.left;
node.left = node.right;
node.right = tmp;
}
return root;
}
}