博客作业04--树

Posted Longjingrap

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了博客作业04--树相关的知识,希望对你有一定的参考价值。

1.学习总结(2分)

1.1树结构思维导图

1.2 树结构学习体会

  • 相当于栈和队列,树是比较难的。
  • 还有很多知识点还没掌握,理解起原理来比较慢。
  • 建树用递归快很多,之前用队列建树真是亏大了。
  • 需要花时间去认真复习其中较难的知识点

2.PTA实验作业(4分)

题目1:6-4 jmu-ds-表达式树

1.设计思路

Q1栈存储数字
Q2栈存储运算符 
while 字符串不为空  
  如果str[i]数字 创建树节点并进栈
  否则 {
  如果Q2栈顶元素优先级小于str[i]   运算符进栈
  如果Q2栈顶元素优先级大于str[i]   创建新的根节点并赋予Q2栈顶元素,右左孩子分别取Q1栈顶元素后再次进Q1栈
  否则 运算符出栈 
  } 
  计算表达式
  如果为叶子节点
  返回将字符转化为数字
  X,Y分别存储树节点的左右子树 
  根据运算符进行相应运算 

2.代码截图



3.PTA提交列表

题目2:7-1 还原二叉树

1.设计思路

输入先序遍历序列和中序遍历序列
调用函数BTNode *CreateBT1(char *pre,char*in,int n)
BTNode *CreateBT1(char *pre,char*in,int n):
     创建二叉树节点b
       利用循环找到中序序列中根节点的位置
         定义k确定根节点在中序序列的具体位置
          递归构造左子树=CreateBT1(pre+1,in,k)
          递归构造右子树=CreateBT1(pre+k+-1,in+k+1,n-k-1)
对还原好的二叉树进行int length(BTNode *node)调用,计算二叉树高度
int length(BTNode *node):
         如果node为空 则返回NULL
        定义l计算左子树的高度l=length(node->left)
        定义r计算右子树的高度r=length(node->right)
         比较l和r的大小 
            l大则返回l+1
            r大则返回r+1

2.代码截图

3.PTA提交列表


主要代码书上有,错了就翻书看下自己哪里错了.所以这题比较好做

题目3:7-1 还原二叉树

1.设计思路

输入中序和后序遍历
调用BTNode * Build(int n, int *mid, int *last)
BTNode * Build:
   如果n为0,则返回NULL
      创建二叉树节点rt
      rt的data指向后序中的最后一个字符,即根节点
      for i to n   
           在中序中找到根节点的位置,结束循环
                     创建rt的左子树= Build(i, mid, last)
                     创建rt的右子树=Build(n-i-1,mid+i+1,last+i)
      返回rt

2.代码截图

3.PTA提交列表


刚开始一直是对部分,错误原因我也不懂,后面去网上找了下,发现把中序和后序的类型改为int形就对了,具体原因还不是怎么懂。

3.截图本周题目集的PTA最后排名

3.1 PTA排名

3.2 我的得分:

205:PTA总分在180--230分:2分

4. 阅读代码

#include <stdio.h>  
#include <stdlib.h>  
  
#define TRUE  1  
#define FALSE 0  
  
// 定义平衡二叉树的结点结构  
typedef struct BiTNode  
{  
    int data;  
    int bf;             // 平衡因子  
    BiTNode *lchild, *rchild;  
}BiTNode, *BiTree;  
  
typedef int Status;  
  
// 右旋处理,即LL调整  
void R_Rotate( BiTree *p )  
{  
    BiTree L;  
    L = (*p)->lchild;  
    (*p)->lchild = L->rchild;  
    L->rchild = *p;  
    *p = L;  
}  
  
// 左旋处理,即RR调整  
void L_Rotate( BiTree *p )  
{  
    BiTree R;  
    R = (*p)->rchild;  
    (*p)->rchild = R->lchild;  
    R->lchild = *p;  
    *p = R;  
}  
  
// 左平衡旋转处理,包括 LL 和 LR 调整  
void LeftBalance( BiTree *T )  
{  
    BiTree L, Lr;  
    L = (*T)->lchild;  
    switch( L->bf )  
    {  
    case 1:        // 新结点插入在T的左孩子的左子树上,为LL型,作右旋处理即LL调整  
        (*T)->bf = L->bf = 0;  
        R_Rotate( T );  
        break;  
    case -1:        // 新结点插入在T的左孩子的右子树上,为LR型,作双旋处理  
        Lr = L->rchild;  
        switch( Lr->bf )  
        {  
        case 1:  
            (*T)->bf = -1;  
            L->bf = 0;  
            break;  
        case 0:  
            (*T)->bf = L->bf = 0;  
            break;  
        case -1:  
            (*T)->bf = 0;  
            L->bf = 1;  
            break;  
        }  
        Lr->bf = 0;  
        L_Rotate( &(*T)->lchild );      // 先对T的左子树进行左旋处理即RR调整  
        R_Rotate( T );                  // 再对T进行右旋处理即LL调整  
    }  
}  
  
// 右平衡旋转处理,包括 RR 和 RL 调整  
void RightBalance( BiTree *T )  
{  
    BiTree R, Rl;  
    R = (*T)->rchild;  
    switch( R->bf )  
    {  
    case -1:        // 新结点插入在T的右孩子的右子树上,为RR型,作左旋处理即RR调整  
        (*T)->bf = R->bf = 0;  
        L_Rotate( T );  
        break;  
    case 1:        // 新结点插入在T的右孩子的左子树上,为RL型,作双旋处理  
        Rl = R->lchild;  
        switch( Rl->bf )  
        {  
        case 1:  
            (*T)->bf = 0;  
            R->bf = -1;  
            break;  
        case 0:  
            (*T)->bf = R->bf = 0;  
            break;  
        case -1:  
            (*T)->bf = 1;  
            R->bf = 0;  
            break;  
        }  
        Rl->bf = 0;  
        R_Rotate( &(*T)->rchild );      // 先对T的左子树进行左旋即RR调整  
        L_Rotate( T );                  // 再对T进行右旋即LL调整  
    }  
}  
  
// 若在平衡二叉树T中不存在和 e 具有相同数据的结点,则插入数据元素为 e 的新结点,  
// 若因插入使二叉排序树失去平衡,则要作平衡调整,  
// 布尔变量taller表示 T 的深度是否增加,TRUE表示增加,FALSE表示没有增加  
  
Status InsertAVL( BiTree *T, int e, Status *taller )  
{  
    if( !*T )  
    {  
        *T = (BiTree)malloc(sizeof(BiTNode));  
        (*T)->data = e;  
        (*T)->lchild = (*T)->rchild = NULL;  
        (*T)->bf = 0;  
        *taller = TRUE;  
    }  
    else  
    {  
        // 树中已有和e具有相同数据的结点,则不再插入  
        if( e == (*T)->data )  
        {  
            *taller = FALSE;  
            return FALSE;  
        }  
  
        if( e < (*T)->data )    // 继续在T的左子树进行搜索  
        {  
            if( !InsertAVL( &(*T)->lchild, e, taller ) ) // InsertAVL( &(*T)->lchild, e, taller )得到的是T的左孩子结点(*T)->lchild的 data,bf 等相关信息  
            {  
                return FALSE;  
            }  
  
            // 如果e已插入到T的左子树中,且左子树深度增加  
            if( *taller )  
            {  
                switch( (*T)->bf )      // 检查T的平衡因子  
                {  
                case 1:                // 原本左子树比右子树高,再加上此结点,导致不平衡,需要作LL或LR调整  
                    LeftBalance( T );  
                    *taller = FALSE;  
                    break;  
                case 0:                // 原本左右子树等高,再加上此结点,左子树增高  
                    (*T)->bf = 1;  
                    *taller = TRUE;  
                    break;  
                case -1:                // 原本右子树比左子树高,再加上此结点,左右子树变为等高  
                    (*T)->bf = 0;  
                    *taller = FALSE;  
                    break;  
                }  
            }  
        }  
        else        // 在T的右子树进行搜索  
        {  
            if( !InsertAVL( &(*T)->rchlid, e, taller ) )  
            {  
                return FALSE;  
            }  
  
            if( *taller )  
            {  
                switch( (*T)->bf )  
                {  
                case 1:                // 原先左子树比右子树高,现在左右子树等高  
                    (*T)->bf = 0;  
                    *taller = FALSE;  
                    break;  
                case 0:                // 原先左右子树等高,现在右子树增高  
                    (*T)->bf = -1;  
                    *taller = TRUE;  
                    break;  
                case -1:                // 原先右子树比左子树高,现在再加上此结点,导致不平衡,需要作 RR 或 RL 调整  
                    RightBalance( T );  
                    *taller = FALSE;  
                    break;  
                }  
            }  
        }  
    }  
  
    return TRUE;  
}  
  
// 对于实例,我们可以这样创建平衡二叉树  
void CreateAVL()  
{  
    int i;  
    int a[10] = {2,1,0,3,4,5,6,9,8,7};  
    BiTree T = NULL;  
    Status taller;  
  
    for( i=0; i<10; i++ )  
    {  
        InsertAVL( &T, a[i], &taller );  
    }  
}  
  • 分享一个创建平衡二叉树的代码。平衡二叉搜索树(Balanced Binary Tree)具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。常用算法有红黑树、AVL、Treap、伸展树等。在平衡二叉搜索树中,我们可以看到,其高度一般都良好地维持在O(log(n)),大大降低了操作的时间复杂度。
  • 给出代码相关地址https://www.cnblogs.com/zhangbaochong/p/5164994.html

5. 代码Git提交记录截图

以上是关于博客作业04--树的主要内容,如果未能解决你的问题,请参考以下文章

博客作业04--树

博客作业04--树

博客作业04--树

博客作业04--树

博客作业04--树

博客作业04--树