数据结构之树小结

树定义

树是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;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值