算法之:树和二叉树常见算法
2023-04-12
背景:在一些大公司,包括面试过程中,对一些常见的算法要求还是比较多的。书、二叉树、红黑树,被问比较多的一些,接下来,我将整理一些常见的算法,以供大家参考。
第一题:遍历二叉树的高度
解释:二叉树是一种有规则的树,所以在遍历的时候,递归使用的比较多。(关于递归,不太了解的可以百度一下递归算法)
public class TreeNode {
public TreeNode left;
public TreeNode right;
int val;
}
public int getTreeMaxHeight(TreeeNode node) {
if(node==null)
return 0;
//遍历左边和右边的子节点高度,求max,然后加上root(1),
return 1+Math.max(getTreeMaxHeight(node.left),getTreeMaxHeight(node.righte));
}
第二题:二叉树中的最大路径和
public class TreeNode {
public TreeNode left;
public TreeNode right;
int val;
}
public class Solution {
int maxnum=0;
public static void main() {
Solution action=new Solution ();
action.DFS();
System.out.printf(maxnum);
}
//遍历
public int DFS(TreeNode node)
{
if(node==null)
retrun 0;
int left=Math.max(node.left,0);
int right=Math.max(node.right,0);
maxnum=Math.max(maxnum,node.val+left+right);
return node.val+Math.max(left,right);
}
第三题:求某个节点以双亲子节点的最大和。(满树)
int max=0;
public int dfs(TreeNode node) {
if(node==null) {
return 0;
}
if(node.left!=null&&node.right!=null)
{
int sum=node.val+node.left.val+node.right.val;
max= Math.max(max,sum);
}
dfs(node.left);
dfs(node.right);
return 0;
}
第三题:二叉树的遍历
1.采用递归方式
前序、后序、中序遍历,只是输出位置不同
public void dfs(Tree tree)
{
if(tree==null)
return;
system.out.printf(tree.val);//前序遍历的结果
dfs(tree.left)
system.out.printf(tree.val);//中序遍历的结果
dfs(tree.right);
system.out.printf(tree.val);//后序遍历的结果
}
2.前序遍历:非递归
public void logTreeFront(TreeNode root) {
Stack stack = new Stack<>();//用一个栈来存放树中的节点
while (root != null || !stack.isEmpty()) {
访问完毕)或者栈中还有节点(还有节点没有访问)
while (root != null) {//一直往左走
stack.push(root);//根节点入栈
System.out.println(root.val);//前序点
root = root.left;//访问左子树
}
root = stack.pop();//取出根节点
root = root.right;//访问右子树
}
}
3.中序遍历:非递归
public void logTreeCenter(TreeNode root){
Stack stack = new Stack<>();
while(root != null || !stack.isEmpty()){//只要当前节点不为空(即当前节点的左右子树没有访 问完毕)或者栈中还有节点(还有节点没有访问)
while(root != null){
stack.push(root);//根节点入栈
root = root.left;//访问左子树
}
root = stack.pop();//取出左子树的根节点
System.out.println(root.val);//输出中序
root = root.right;//访问右子树
}
}
4.后序遍历:非递归
private void endLogTree(TreeNode tree) {
if (tree == null)
return;
Stack stack = new Stack();
TreeNode node = tree;
TreeNode prev = null;
while (node!=null||!stack.isEmpty()) {
//处理左子树
while (node != null) {
stack.push(node);
//这边继续遍历
node = node.left;
}
node = stack.peek();
//处理右子树
if (node.right == null || node.right == prev) {
//将顶部的出栈
stack.pop();
//打印节点
System.out.println(node.val);
prev = node;//下一个节点指向
node = null;//当前节点遍历完,需要释放
} else {
node = node.right;
}
}
}
第四题:创建二叉树,完整树
public TreeNode createTree(int[] objs) {
List datas = new ArrayList();
for (Integer object : objs) {
datas.add(new TreeNode(object));
}
TreeNode root = datas.get(0);//将第一个作为根节点
for (int i = 0; i < objs.length / 2; i++) {
//树是对称图像,只需要计算左边
//左子树的位置2*1+1
datas.get(i).left = datas.get(i * 2 + 1);
//右子树:i*2+2
if (i * 2 + 2 < datas.size()) {
datas.get(i).right = datas.get(i * 2 + 2);
}
}
return root;
}
第五题:二叉树的层遍历
public void logLevel(TreeNode treeNode) {
if (treeNode == null)
return;
Queue queue = new LinkedList<>();//层序遍历时保存结点的队列
queue.offer(treeNode);//初始化
while(!queue.isEmpty()){
TreeNode node = queue.poll();
System.out.print(node.val + " ");//访问节点
if(node.left != null)
queue.offer(node.left);
if(node.right != null)
queue.offer(node.right);
}
}
备注:关于Queue的add和offer,一个会引起异常,一个不会。所以不了解队列的,可以自己看下API。
本文仅代表作者观点,版权归原创者所有,如需转载请在文中注明来源及作者名字。
免责声明:本文系转载编辑文章,仅作分享之用。如分享内容、图片侵犯到您的版权或非授权发布,请及时与我们联系进行审核处理或删除,您可以发送材料至邮箱:service@tojoy.com



