二叉树(二)

将二叉查找树变为有序的双向链表(不能创建新节点,只调整指针)

递归

public TreeNode convertBST2DLLRec(TreeNode root) {
    root = convertBST2DLLSubRec(root);
    // 递归完,root会在链表的中间位置,要把root移到链表头
    while (root.left != null) {
        root = root.left;
    }
    return root;
}
private TreeNode convertBST2DLLSubRec(TreeNode root) {
    if (root == null || (root.left == null && root.right == null)) {
        return root;
    }

    TreeNode tmp = null;
    if (root.left != null) { // 处理左子树
        tmp = convertBST2DLLSubRec(root.left);
        while (tmp.right != null) { // 寻找最右节点
            tmp = tmp.right;
        }
        tmp.right = root; // 把左子树最右节点和root连接
        root.left = tmp;
    }
    if (root.right != null) { // 处理右子树
        tmp = convertBST2DLLSubRec(root.right);
        while (tmp.left != null) { // 寻找最左节点
            tmp = tmp.left;
        }
        tmp.left = root; // 把右子树最左节点和root连接
        root.right = tmp;
    }
    return root;
}

非递归

// 类似inorder traversal
public TreeNode convertBST2DLL(TreeNode root) {
    if (root == null) {
        return null;
    }

    Stack<TreeNode> stack = new Stack<TreeNode>();
    TreeNode cur = root; // 指向当前处理节点
    TreeNode old = null; // 指向前一个处理的节点
    TreeNode head = null; // 链表头

    while (true) {
        while (cur != null) {
            stack.push(cur);
            cur = cur.left;
        }

        if (stack.isEmpty()) {
            break;
        }

        cur = stack.pop();

        if (old != null) {
            old.right = cur;
        }
        if (head == null) {
            head = cur;
        }
        old = cur; // 更新old
        cur = cur.right;
    }
    return head;
}

判断二叉树是不是平衡二叉树

递归

public boolean isAVLRec(TreeNode root) {
    if (root == null) {
        return true;
    }

    // 如果左子树和右子树高度相差大于1,则非平衡二叉树, getDepthRec()是前面实现过的求树高度的方法
    if (Math.abs(getDepthRec(root.left) - getDepthRec(root.right)) > 1) {
        return false;
    }

    return isAVLRec(root.left) && isAVLRec(root.right);
}

二叉树中两个节点的最低公共祖先节点

递归

/**
 *  求二叉树中两个节点的最低公共祖先节点 递归解法:
 * (1)如果两个节点分别在根节点的左子树和右子树,则返回根节点
 * (2)如果两个节点都在左子树,则递归处理左子树;如果两个节点都在右子树,则递归处理右子树
 */
public TreeNode getLastCommonParentRec(TreeNode root, TreeNode n1, TreeNode n2) {
    if (findNodeRec(root.left, n1)) { // 如果n1在树的左子树
        if (findNodeRec(root.right, n2)) { // 如果n2在树的右子树
            return root; // 返回根节点
        } else { // 如果n2也在树的左子树
            return getLastCommonParentRec(root.left, n1, n2);
        }
    } else { // 如果n1在树的右子树
        if (findNodeRec(root.left, n2)) { // 如果n2在左子树
            return root;
        } else { // 如果n2在右子树
            return getLastCommonParentRec(root.right, n1, n2);
        }
    }
}

// 帮助方法,递归判断一个节点是否在树里
private static boolean findNodeRec(TreeNode root, TreeNode node) {
    if (root == null || node == null) {
        return false;
    }
    if (root == node) {
        return true;
    }
    boolean found = findNodeRec(root.left, node);
    if (!found) {
        found = findNodeRec(root.right, node);
    }
    return found;
}

非递归

时间: 2024-07-30 07:57:04

二叉树(二)的相关文章

SDUT 3341 数据结构实验之二叉树二:遍历二叉树

数据结构实验之二叉树二:遍历二叉树 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Problem Description 已知二叉树的一个按先序遍历输入的字符序列,如abc,,de,g,,f,,, (其中,表示空结点).请建立二叉树并按中序和后序的方式遍历该二叉树. Input 连续输入多组数据,每组数据输入一个长度小于50个字符的字符串. Output 每组输入数据对应输出2行:第1行输出中序遍历序列:第2行输出后序遍历序列

纸上谈兵: 树, 二叉树, 二叉搜索树

树的特征和定义 树(Tree)是元素的集合.我们先以比较直观的方式介绍树.下面的数据结构是一个树: 树有多个节点(node),用以储存元素.某些节点之间存在一定的关系,用连线表示,连线称为边(edge).边的上端节点称为父节点,下端称为子节点.树像是一个不断分叉的树根. 每个节点可以有多个子节点(children),而该节点是相应子节点的父节点(parent).比如说,3,5是6的子节点,6是3,5的父节点:1,8,7是3的子节点, 3是1,8,7的父节点.树有一个没有父节点的节点,称为根节点(

SDUT-3441_数据结构实验之二叉树二:遍历二叉树

数据结构实验之二叉树二:遍历二叉树 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 已知二叉树的一个按先序遍历输入的字符序列,如abc,,de,g,,f,,, (其中,表示空结点).请建立二叉树并按中序和后序的方式遍历该二叉树. Input 连续输入多组数据,每组数据输入一个长度小于50个字符的字符串. Output 每组输入数据对应输出2行: 第1行输出中序遍历序列: 第2行输出后序遍历序列. Sample Inp

C#实现二叉树 二叉链表结构

二叉链表存储结构: 二叉树的链式存储结构是指,用链表来表示一棵二叉树,即用链来指示元素的逻辑关系. 通常的方法是链表中每个结点由三个域组成,数据域和左右指针域,左右指针分别用来给出该结点左孩子和右孩子所在的链结点的存储地址.其结点结构为: 其中,data域存放某结点的数据信息:lchild与rchild分别存放指向左孩子和右孩子的指针,当左孩子或右孩子不存在时,相应指针域值为空(用符号∧或NULL表示).利用这样的结点结构表示的二叉树的链式存储结构被称为二叉链表,如图5-8所示. C#实现代码

树, 二叉树, 二叉搜索树

转载:Vamei   出处:http://www.cnblogs.com/vamei 树的特征和定义 树(Tree)是元素的集合.我们先以比较直观的方式介绍树.下面的数据结构是一个树: 树有多个节点(node),用以储存元素.某些节点之间存在一定的关系,用连线表示,连线称为边(edge).边的上端节点称为父节点,下端称为子节点.树像是一个不断分叉的树根. 每个节点可以有多个子节点(children),而该节点是相应子节点的父节点(parent).比如说,3,5是6的子节点,6是3,5的父节点:1

二叉树--二叉平衡树

二叉平衡树是二叉树中最为最要的概念之一,也是在语言库或者项目中应用比较广泛的一种特殊的树形结构. 二叉平衡树 AVL树是高度平衡的而二叉树.它的特点是:AVL树中任何节点的两个子树的高度最大差别为1. 通常AVL树是在二叉搜索树上,经过局部调整而建立的,因此,它还是一棵排序树. 上面的两张图片,左边的是AVL树,它的任何节点的两个子树的高度差别都<=1:而右边的不是AVL树,因为7的两颗子树的高度相差为2(以2为根节点的树的高度是3,而以8为根节点的树的高度是1). 性质 左右子树相差不超过1.

二叉树--二叉搜索树

一直对AVL这个英文缩写比较困惑,原来一直以为是平衡二叉树的首字母缩写,但是又想不明白,哈!前段时间才明白原来是种这课树的三个人的名字的首字母的,哎,生活处处有惊喜,无知不可怕,现在我也知道了.废话不多说,下面我们说说,树形结构中的那些平衡二叉树. 二叉排序树 树的遍历顺序有3种,二叉排序树,顾名思义,就是一颗有序的二叉树,是一种按照中序遍历树中节点,而输出有序队列的一种树形结构,一种特殊的树形结构. 定义 对于二叉树,假设x为二叉树中的任意一个结点,x节点包含关键字key,节点x的key值记为

二叉树-二叉搜索树(中序)

题型: (1)验证 (2)修复(排列不正确,修复) (3)构造(给排列求树-平衡的:种类) (4)利用性质求第n个结点 二叉搜索树的思路:中序输出+相关操作 如果要求空间复杂度O(1),考虑莫里斯遍历 98. 验证二叉搜索树    面试题 04.05. 合法二叉搜索树 (1) 思路:中序排列,看次序 1 class Solution { 2 public boolean isValidBST(TreeNode root) { 3 // if(root==null){ // 题目空树是true 4

二叉树-------二叉链表实现

1 #include <stdio.h> 2 #include <stdlib.h> 3 typedef char TelemType; 4 5 typedef struct BinTree{ 6 TelemType data; 7 struct BinTree *LChild; 8 struct BinTree *RChild; 9 }BinaryTree; 10 11 // 12 13 14 BinaryTree* create_BinaryTree(BinaryTree *T

javascript数据结构与算法--二叉树(插入节点、生成二叉树)

javascript数据结构与算法-- 插入节点.生成二叉树 二叉树中,相对较小的值保存在左节点上,较大的值保存在右节点中 /* *二叉树中,相对较小的值保存在左节点上,较大的值保存在右节点中 * * * */ /*用来生成一个节点*/ function Node(data, left, right) { this.data = data;//节点存储的数据 this.left = left; this.right = right; this.show = show; } function sh