二叉排序(查找、搜索)树

电脑杂谈  发布时间:2019-07-14 10:14:50  来源:网络整理

二叉排序树 数据结构_二叉排序树的遍历_树和二叉树的转换代码

二叉排序树就既有链表的好处,也有数组的好处。在处理的动态的数据是比较有用。

若左子树不空,则左子树上所有结点的值均小于它的根结点的值;

若右子树不空,则右子树上所有结点的值均大于或等于它的根结点的值;

左、右子树也分别为二叉排序树。

数列的顺序不同创建出来的二叉排序树是会不一样的!

(65 ,32,87, 46,71,98, 39)

每一层数字的顺序是可以换的,32和87是可以换的。 (32,39,46,65,71,87,89)

二叉排序树的遍历_树和二叉树的转换代码_二叉排序树 数据结构

注意:结构体里给了left,right默认值NULL。

非递归算法:

typedef struct BinarySortTreeNode{
    int data;
    struct BinarySortTreeNode *Left = NULL;
    struct BinarySortTreeNode *Right = NULL;
}*BinarySortTree;
BinarySortTree CreatBStree(int *a,int length) {
    BinarySortTree BST = new BinarySortTreeNode;
    BST->data = *a++;    
    for (int i = 1; i < length; i++) {
        BinarySortTreeNode *pre = NULL, *p = BST, *Node=new BinarySortTreeNode;
        while (p) {
            pre = p;
            p = *a < p->data ? p->Left : p->Right;
        }
        Node->data = *a;
        *a < pre->data ? pre->Left = Node : pre->Right = Node;
        a++;
    }
    return BST;
}

1.3 二叉排序树的插入与删除

(1)插入节点

这个算法加个循环就可以作为 " 建立二叉排序树 " 的算法,上面说的递归算法在这里 - _ - !

BinarySortTree InsertBStree(BinarySortTree BST, int x){
    if (BST == NULL){
        BST = new BinarySortTreeNode;
        BST->data = x;
        return BST;
    }    
        if (x < BST->data)
            BST->Left = InsertBStree(BST->Left, x);
        else
            BST->Right = InsertBStree(BST->Right, x);
        return BST;
}
BinarySortTree CreatBStByRecursion(int *a,int length) {
    BinarySortTree BST = NULL;
    for (int i = 0; i < length; i++)
        BST = InsertBStree(BST, a[i]);
    return BST;
}

(2)查找节点

二叉排序树 数据结构_二叉排序树的遍历_树和二叉树的转换代码

找不到返回NULL,找到返回该节点。

BinarySortTreeNode* BSTreeFind(BinarySortTree BST,int x) {
    BinarySortTree p = BST;
    while (p) {
        if (x == p->data) break;
        p = x > p->data ? p->Right : p->Left;
    }
    return p;
}

(3)删除节点

1. 被删除的结点是叶子,将父节点的 left 或 right 指针域设置为NULL。

所有结点只有左子树叫左斜树,只有右结点叫右斜树。一个很简单的解释是:如果将b的左子节点d拿到a的左子节点,那么b右旋后右子节点指向a,b原来的右子节点e就成为了一个游离的节点,游离于整个数据结构之外。 供选择的答案: a:①是特殊的树②不是树的特殊形式③是两棵树的总称④是只有二个根结点的树形结构 b:①左子结点②右子结点③左子结点或者没有右子结点 ④兄弟 c~d: ①最左子结点②最右子结点③最邻近的右兄弟④最邻近的左兄弟⑤最左的兄弟⑥最右的兄弟e:①o(n)②o(n)③o(log2n)④o(log2n) 15、每一棵树都能唯一地转换为它所对应的二叉树,树的这种二叉树表示对树的运算带来很大的好处。

(第一种情况,写的时候 可以和第二种合并起来)

所有结点只有左子树叫左斜树,只有右结点叫右斜树。 供选择的答案: a:①是特殊的树②不是树的特殊形式③是两棵树的总称④是只有二个根结点的树形结构 b:①左子结点②右子结点③左子结点或者没有右子结点 ④兄弟 c~d: ①最左子结点②最右子结点③最邻近的右兄弟④最邻近的左兄弟⑤最左的兄弟⑥最右的兄弟e:①o(n)②o(n)③o(log2n)④o(log2n) 15、每一棵树都能唯一地转换为它所对应的二叉树,树的这种二叉树表示对树的运算带来很大的好处。这时,会添加两个左子节点和右子节点,然后把自身的croutingbin中的联系人信息按照它们的前缀特点分别复制往左节点和右节点二叉排序树 数据结构,最后把自身的croutingbin废除掉,这样这个分裂过程就完了。

二叉排序树的遍历_二叉排序树 数据结构_树和二叉树的转换代码

如果从左子树中选,就应该选择左子树中最右边的那个叶子节点(这里肯定是叶子,如果不是叶子,那么就不是最右边的节点)

如果从右子树中选二叉排序树 数据结构,就应该选择有子树中最左边的那个叶子节点。

写法1 :

这个写法更适合JAVA之类,有垃圾回收的语言,还可以把那些delete省去,但是必须要注意的是:

必须这样调用Tree = BSTDel ( Tree , delNum) ;就像函数里面的递归一样形式,否则删除只有一个子树的根节点的时候,会出错。

//获得子树中的最大值
int GetMax(BSTree root) {
    if (root->Right == NULL) return root->data;
    return GetMax(root->Right);
}
//删除子树中的最大值
BSTree DelMax(BSTree root) {
    if (root->Right == NULL) {
        BSTNode *t= root->Left;
        delete root;
        return t;
    }
    root->Right = DelMax(root->Right);
    return root;
}
BSTree BSTDel(BSTree root,int x) {
    if (root == NULL) return NULL;
    if (root->data == x) {
        if (! root->Right || !root->Left) {
            BSTNode *t = !root->Right ? root->Left : root->Right;
            delete root;
            return t;
        }
        root->data = GetMax(root->Left);
        root->Left = DelMax(root->Left);
    }
    else if (x > root->data) root->Right = BSTDel(root->Right, x);
    else  root->Left = BSTDel(root->Left, x);
    return root;
}

写法2:

二叉排序树 数据结构_树和二叉树的转换代码_二叉排序树的遍历

指针很强大,传进 BSTree *root,可以直接修改 *root 的值。(指针也很讨厌,上面的写法,如果是JAVA,完全不用考虑delete的问题,代码量可以更短。)

删除含两个子树的节点那部分,可以用这种思想写,但我偏要复杂写,没错,我就是杠精。

void BSTDel(BSTree *root, int x){
    if (!*root) {
        cout << "FUCK, 找不到." << endl;
        return;
    }
    BSTree p = *root;
    if (p->data == x) {
        if (!p->Right || !p->Left)
        *root = !p->Right ? p->Left : p->Right;
        else{
                BSTNode *parent = p->Left, *q = p->Left;
                if (!q->Right)    q->Right = p->Right;
                else {
                    while (q->Right) {
                        parent = q;
                        q = q->Right;
                    }
                    parent->Right = q->Left;
                    q->Left = p->Left;
                    q->Right = p->Right;
                }
                *root = q;
        }
        delete p;
    }
    else if (x > p->data) //向右找
        BSTDel(&(p->Right), x);
    else if (x < p->data) //向左找
        BSTDel(&(p->Left), x);
}

7-2as 开始岛屿第一个高挂位置桔子下方右侧约1人处有蛋.a2 第一个小猪.注意碰撞位置.a3 第一个草莓下方右侧约1人处有蛋.ag牌岸边处有蛋.7-3as 中途短崖处有蛋.a2第三个平台上天.a4 第一个连续平台可以在第二个平台等蝙蝠飞过之后再跳过去.在第三个平台先打死乌鸦再跳.落地之后马上消灭青蛙.a4 第二个连续平台的第一个平台蝙蝠的行进会碰到名人.之后在平台上不要急于前进.先站稳打掉蝙蝠.7-4a3牌前火堆前的蛋是饿鬼.a3中第三只小猪a4三堆火右侧有蛋.第八关8-1 荒野as 第二只青蛙右侧约1人处有蛋.a2连续下降阶段最后下陷部分有蛋.a3牌右侧台阶左侧约3人处有蛋.a3连续下降凸凹阶段部分有两个连续碎石第二个碎石.同样注意碰撞的方向.a3连续下降阶段中途可上天.a3区第二个可见蛋是饿鬼.a4第一个可见蛋是奶瓶.第二个可见蛋是饿鬼.8-2 岛屿a3前树左侧约距3人处有蛋.a3 第二个岛屿右侧离岸边距约3人处有蛋.a4 第一树右侧约距5人处有蛋.8-3 洞窟as 第二颗蛋是饿鬼.a3 连续平台上岸边处有蛋.a4 上升阶段要注意滚石.后面连续坠落平台要加足速度,尽量在空中发弹打掉蝙蝠.在第六个平台要提前发弹.打掉蝙蝠.a4 连续坠落平台对岸的一堆火.前面不远就是ag牌.8-4as 第一个蜘蛛左约1人处有蛋.a2 第一个碎石左侧约3人处有蛋.a3 第一个可见蛋是饿鬼.a3 第一个高挂香蕉左侧约2人处有蛋.a4 第一堆火是奖杯boss打法:八个关的boss样子大同小异。6.根据权利要求3所述的钢筋拉直装置夹持机构,其特征在于,在左侧上方压板、左侧斜向导轨、左侧下方压板、右侧上方压板、右侧斜向导轨和右侧下方压板的后方设置一个固定板,左侧上方压板、左侧斜向导轨、左侧下方压板、右侧上方压板、右侧斜向导轨和右侧下方压板的后侧面分别连接到固定板上。[0010]进一步,在左侧上方压板、左侧斜向导轨、左侧下方压板、右侧上方压板、右侧斜向导轨和右侧下方压板的后方设置一个固定板,左侧上方压板、左侧斜向导轨、左侧下方压板、右侧上方压板、右侧斜向导轨和右侧下方压板的后侧面分别连接到固定板上。


本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/jisuanjixue/article-112892-1.html

相关阅读
    发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

    热点图片
    拼命载入中...