首页

文章

二叉排序树。用二叉链表作存储结构。(8

发布网友 发布时间:2022-03-22 15:44

我来回答

1个回答

懂视网 时间:2022-03-22 20:05

二叉链表存储结构是二叉树的一种存储方式。链表中结点的两个链域分别指向该结点的第一个孩子结点和第二个孩子结点。

  二叉链表是树的二叉链表实现方式。二叉树是逻辑结构,二叉链表是二叉树的物理实现,两者之间的关系属于概念和实现,抽象和具体的关系。二叉树的顺序存储结构由一组连续的存储单元依次从上到下,从左到右存储完全二叉树的结点元素。对于一般二叉树,应将其与完全二叉树对应,然后给每个结点从1到i编上号,依次存储在大小为i到1的数组中。

  

热心网友 时间:2022-03-22 17:13

这是我前几天写的,看了下应该可以满足要求,由于测试还不够,不知道有没有bug。

第一点你自己改改,2、3都达到了,至于第四,不用说肯定是平衡了的二叉树相对查找效率要高一些,平衡,随机插入,打乱插入等操作都是为了防止最差情况的线性树的出现。测试的话用rand()生成随机数外加time.h里的几个函数,配合使用下就出来了。

#include <stdio.h>
#include <stdlib.h>

// binary search tree
typedef struct BST
{
    int data;
    struct BST* lhs;
    struct BST* rhs;
}BST;

// 插入一个节点
BST* BSTInsertNode(BST* root, int elem)
{
    BST* node;
    node = (BST*)malloc(sizeof(BST));
    node->data = elem;
    node->lhs = node->rhs = 0;
    
    if(!root)
        return node;
    
    while(1)
    {
        if(node->data < root->data)
        {
            if(root->lhs)
                root = root->lhs;
            else
            {
                root->lhs = node;
                return root->lhs;
            }
        }
        else  
        {
            if(root->rhs)
                root = root->rhs;
            else
            {
                root->rhs = node;
                return root->rhs;
            }
        }
    }
}

// 获得父节点
BST* BSTGetParentNode(BST* root, BST* node)
{
    if(root == node)
        return 0;
    
    if(root->lhs && node->data < root->lhs->data)
        return BSTGetParentNode(root->lhs, node);
    else if(root->rhs && node->data > root->rhs->data)
        return BSTGetParentNode(root->rhs, node);
    else
        return root;
}

// 删除一个节点
BST* BSTDeleteNode(BST* root, BST* node)
{
    BST* parent;
    BST** whichNode;
    BST* temp;
    
    if(root != node)
    {
        
        parent = BSTGetParentNode(root, node);
        whichNode = parent->lhs == node ? &parent->lhs : &parent->rhs;
    }
    else
        whichNode = &root;
    if(!node->lhs && !node->rhs)
        *whichNode = 0;
    else if(!((node->lhs ? 1 : 0) ^ (node->rhs ? 1 : 0)))
        *whichNode = node->lhs ? node->lhs : node->rhs;
    else
    {
        temp = node->rhs;
        while(temp->lhs)
            temp = temp->lhs;
        temp->lhs = node->lhs;
        *whichNode = node->rhs;
    }
    free(node);
    return *whichNode;
}

// 删除树
void BSTDeleteTree(BST* node)
{
    if(node)
    {
        BSTDeleteTree(node->lhs);
        BSTDeleteTree(node->rhs);
        free(node);
    }
}

// 建造树,从数组构造
BST* BSTBuildTree(int* beg, int* end)
{
    BST* root;
    
    if(beg >= end)
        return 0;
    
    root = (BST*)malloc(sizeof(BST));
    root->data = *beg++;
    root->lhs = root->rhs = 0;
    
    while(beg != end)
        BSTInsertNode(root, *beg++);
    
    return root;
}

// 查找节点
BST* BSTSearchNode(BST* root, int elem)
{
    if(root)
    {
        if(elem < root->data)
            return BSTSearchNode(root->lhs, elem);
        else if(elem > root->data)
            return BSTSearchNode(root->rhs, elem);
        else
            return root;
    }
    else
        return 0;
}

// 获得最小值
BST* BSTGetMinimumNode(BST* root)
{
    while(root->lhs)
        root = root->lhs;
    return root;
}

// 获得最大值
BST* BSTGetMaximumNode(BST* root)
{
    while(root->rhs)
        root = root->rhs;
    return root;
}

// 前序遍历
void BSTPreorderTraverse(BST* node)
{
    if(node)
    {
        printf("%d ", node->data);
        BSTPreorderTraverse(node->lhs);
        BSTPreorderTraverse(node->rhs);
    }
}

// 中序遍历
void BSTInorderTraverse(BST* node)
{
    if(node)
    {
        BSTInorderTraverse(node->lhs);
        printf("%d ", node->data);
        BSTInorderTraverse(node->rhs);
    }
}

// 后序遍历
void BSTPostorderTraverse(BST* node)
{
    if(node)
    {
        BSTPostorderTraverse(node->lhs);
        BSTPostorderTraverse(node->rhs);
        printf("%d ", node->data);
    }
}

// 获得前继值
BST* BSTGetPredecessor(BST* root, BST* node)
{
    BST* predecessor;
    BST* rightCld;
    
    if(node->lhs)
        return BSTGetMaximumNode(node->lhs);
    
    predecessor = rightCld = node;
    while((predecessor = BSTGetParentNode(root, predecessor)))
        if(predecessor->rhs == rightCld)
            return predecessor;
        else
            rightCld = predecessor;
    return 0;
}

// 获得后继值
BST* BSTGetSuccessor(BST* root, BST* node)
{
    BST* successor;
    BST* leftCld;
    
    if(node->rhs)
        return BSTGetMinimumNode(node->rhs);
    
    successor = leftCld = node;
    while((successor = BSTGetParentNode(root, successor)))
        if(successor->lhs == leftCld)
            return successor;
        else
            leftCld = successor;
    return 0;
}

// 获得树高
int BSTGetTreeHeight(BST* root)
{
    int l;
    int r;
    if(root)
    {
        l = BSTGetTreeHeight(root->lhs);
        r = BSTGetTreeHeight(root->rhs);
        return 1 + (l > r ? l : r);
    }
    else
        return -1;
}

// 计算子节点数
int BSTGetSubtreeNodeNum(BST* node)
{
    if(node)
        return BSTGetSubtreeNodeNum(node->lhs)
             + BSTGetSubtreeNodeNum(node->rhs)
             + 1;
    else
        return 0;
}

// 用于打乱数组,交换
inline void Swap(int* a, int* b)
{
    int temp;
    temp = *a;
    *a = *b;
    *b = temp;
}

// 用于打乱数组,qsort的比较用过程
inline int CMP(const void* lhs, const void* rhs)
{
    return *(const int*)lhs - *(const int*)rhs;
}

// 数组有序?
int IsOrdered(int* beg, int* end)
{
    int attri;
    int cmpVal;
    if(beg >= end)
        return 0;
    if(end - beg <= 2)
        return 1;
    
    if(*beg < *(beg + 1))
        attri = 1;
    else
        attri = 0;
    
    cmpVal = *beg++;
    while(++beg != end)
    {
        if(attri)
        {
            if(cmpVal > *beg)
                return 0;
        }else
        {
            if(cmpVal < *beg)
                return 0;
        }
    }
    return 1;
}

// 高层次打乱数组
void HighlyUnorderArray(int* beg, int* end)
{
    
    int* mid = beg + (end - beg)/2;
    int* folk;
    if(!IsOrdered(beg, end))
        qsort(beg, end - beg, sizeof(int), CMP);
    
    if((mid - beg) & 1)
        Swap(beg++, mid);
    folk = beg + 2;
    while(folk < mid)
    {
        Swap(beg++, folk++);
        Swap(beg++, folk++);
    }
        
    folk = mid + 2;
    while(folk < end)
    {
        Swap(folk, folk - 1);
        folk += 2;
    }
}

// 中序遍历结果输出到数组
void BSTInorderWalkToArray(BST* root, int** p)
{
    if(root)
    {
        BSTInorderWalkToArray(root->lhs, p);
        **p = root->data;
        (*p)++;
        BSTInorderWalkToArray(root->rhs, p);
    }
}

// 平衡树,返回平衡好的新树
BST* BSTBalanceTree(BST* root)
{
    int size = BSTGetSubtreeNodeNum(root);
    int* a = (int*)malloc(sizeof(int) * size);
    int* end = a;
    BST* balancedTree;
    
    BSTInorderWalkToArray(root, &end);
    HighlyUnorderArray(a, end);
    balancedTree = BSTBuildTree(a, end);
    free(a);
    return balancedTree;
}

int main()
{
    int a[] = ;
    int c[] = ;
    BST* bstTree = BSTBuildTree(a, a + sizeof(a)/sizeof(a[0]));
    
    BSTPreorderTraverse(bstTree);
    putchar('\n');
    BSTInorderTraverse(bstTree);
    putchar('\n');
    BSTPostorderTraverse(bstTree);
    printf("\n\n");
    
    BST* balancedTree = BSTBalanceTree(bstTree);
    printf("%d %d\n", BSTGetTreeHeight(bstTree), BSTGetTreeHeight(balancedTree));
    BSTDeleteTree(bstTree);
    BSTDeleteTree(balancedTree);
}
逆水寒手游庄园怎么邀请好友同住 逆水寒手游 逆水寒不同区可以一起组队吗? 逆水寒手游 逆水寒怎么进入好友世界? 逆水寒手游 逆水寒怎么去别人的庄园? 使用puppeteer实现将htmll转成pdf 内卷时代下的前端技术-使用JavaScript在浏览器中生成PDF文档 【译】将HTML转为PDF的几种实现方案 变形金刚08动画怎么样 变形金刚08动画的问题 变形金刚08动画日语版剧情介绍 高分!换显卡nvidia控制面板被我卸了,重新安装显卡驱动后没了nvidia控... 我的nvidia控制面板被卸载了 怎么找回啊 卸载后 这个画面看着很奇怪_百 ... 李卓彬工作简历 林少明工作简历 广东工业职业技术学院怎么样 郑德涛任职简历 唐新桂个人简历 土地入股的定义 ups快递客服电话24小时 贷款记录在征信保留几年? 安徽徽商城有限公司公司简介 安徽省徽商集团新能源股份有限公司基本情况 安徽省徽商集团有限公司经营理念 2019哈尔滨煤气费怎么有税? 快手删除的作品如何恢复 体育理念体育理念 有关体育的格言和理念 什么是体育理念 万里挑一算彩礼还是见面礼 绿萝扦插多少天后发芽 绿萝扦插多久发芽 扦插绿萝多久发芽 炖牛排骨的做法和配料 网络诈骗定罪标准揭秘 “流水不争先”是什么意思? mc中钻石装备怎么做 为什么我的MC里的钻石块是这样的?我想要那种。是不是版本的问题?如果是... 带“偷儿”的诗句 “君不见巴丘古城如培塿”的出处是哪里 带“奈何”的诗句大全(229句) 里翁行()拼音版、注音及读音 带“不虑”的诗句 “鲁肃当年万人守”的出处是哪里 无尘防尘棚 进出口报关流程,越详细越好。谢谢大家指教。 双线桥不是看化合价升多少就标多少的吗?为什么CL2+2KI=2KCL+I2中I失... 出师表高锰酸钾有画面了吗 2021年幼儿园新学期致家长一封信 电脑屏幕一条黑线怎么办? 销售代理商销售代理商的特点 三叉链表与二叉链表储存结构比较,有何区别?有何优缺点? 二叉链表作存储结构 二叉树的二叉链表存储结构如何实现 以二叉链表为存储结构, 二叉链表是二叉树的存储结构吗 您好,我的电话被标记骚扰电话了,怎么取消 电话号码被标注骚扰电话怎么解除 怎样取消号码诈骗电话标记 手机被标注骚扰电话,怎么解除? 手机被标注骚扰电话怎么取消? 手机被标记骚扰电话怎么取消 怎么取消标记电话 我的手机号不知道为什么被标记成诈骗电话了,怎么取消掉? 我的号码被标记为广告推销,骚扰电话,怎么取消标记 手机号码被标注为骚扰电话了,怎么解除掉 二叉树总的节点数为n,为啥空指针个数为n+1 二叉树指针问题。。Bitree 是什么? CreateBiTree为什么用BiTree *T, 是什么意思? 利用二叉链表存储树,则根结点的右指针是? 为什么答案不是右孩子是空? 在有n个结点的二叉链表中共有多少个指针域? 链表,二叉树为什么要给函数传入的头参数为指针的指针 二叉树的存储结构是怎样的?有哪些类型的存储结构?对应的c语言描述是? 数据结构中,怎样以二叉链表为存储结构,分别写出求二叉树结点总数及叶子总数的算法? 用顺序和二叉链表作存储结构 数据结构的两道题,以二叉链表为存储结构 设二叉排序树采用二叉链表存储结构 采用二叉链表作为存储结构,完成二叉树的建立,前序、中序和后序遍历的操作,求所有叶子及结点总数的操作 以二叉链表作为二叉树的储存结构,在具有n个结点的二叉链表中n(n>0),空链域的个数为() 若二叉树采用二叉链表存储结构,要交换其所有分支结点左、右子树的位置,利用( )遍历方法最合适。 分别写出线性表的链式存储结构、二叉树的二叉链表存储机构的类C语言描述 以二叉链表为存储结构,写出求二叉树高度和宽度的算法 以二叉链表作存储结构,带虚节点的先序遍历序列为输入,构造二叉链表。 网络安全需要学什么 学习网络安全需要什么基础 如何学习网络安全知识? 网络安全怎么学? 网络安全需要学习哪些知识? 学习网络安全要学哪些知识? 学网络安全的基本知识有哪些? 网络安全工程师需要学习的必备技术有哪些? 如何学习网络安全,应该从何学起
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com