博客作业04--树

Posted hahaha233

tags:

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

1.学习总结(2分)

1.1树结构思维导图

1.2 树结构学习体会

  • 树是由n(n>=0)个结点组成的有限集合
  • 树的运用灵活,很多时候可以有效的降低运行的时间,大多数的时间复杂度较低
  • 树结构的应用有并查集的问题,表达式转换的问题,哈夫曼编码的推广……
  • 自己在学习树比较云里雾里,很多代码不能很好的理解,编写起来容易出现各种bug,在建树时对栈或队列的调用的应用不熟练
  • 感觉自己还是要多练习,理解课本的代码啊

2.PTA实验作业(4分)

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

2.2 设计思路(伪代码或流程图)

void InitExpTree(BTree &T,string str)  //建表达式的二叉树
{
  创建栈S与op栈
  最低操作符‘#’入栈
  while(str[i]){
      当str[i]不为运算符时
          创建新的左右空孩子的树,并入栈S
      否则(为运算符)
          判断运算符与op栈顶运算符优先关系
          运算符较大时直接入op栈,否则op栈内元素较小时,生成新树读入op,右左孩子取S栈顶元素,再将该树入栈 S      
      }
   while(op栈内还有运算符){
          生成新子树读入op,右左孩子取S栈顶元素,再将该树入栈S
    }
  T=S栈顶元素
    
}

double EvaluateExTree(BTree T)//计算表达式树
{
    当树不空且有左右孩子时,返回对应值
    count1=递归遍历左子树
    count2=递归遍历右子树
    根据T->data运算符进行相应计算返回相应值(注意除数为0时不符合)
  
}


2.3 代码截图(注意,截图、截图、截图。代码不要粘贴博客上。不用用···语法去渲染)


2.4 PTA提交列表说明。

编译错误

自己一开始从devc++复制过去忘记去掉多余函数

答案错误

左右孩子问题,要先录入右孩子再录入左孩子

部分正确

自己修改后0为除数与无括号的测试点正确

自己在devc++运行认为正确

后知道是自己的计算函数元素的定义问题,应为double

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

2.6 设计思路(伪代码或流程图)

BTNode *CreateBTree(char *pre,char *in,int n)//建树 
{
	若n<=0;返回空
	创建根结点b
	b->data=*pre;
	利用循环查找根结点在中序序列的位置k
        创建左子树:
	b->lchild=CreateBTree(pre+1,in,k);
        创建右子树:
	b->rchild=CreateBTree(pre+k+1,p+1,n-k-1);

}

int GetHeight( BTree BT )//计算高度 
{
        空树返回0
        递归求左子树的高度为lheight
        递归求右子树的高度为rheight
        比较两者大小,返回较大的数并加一

    }  
}

2.7 代码截图(注意,截图、截图、截图。代码不要粘贴博客上。不用用···语法去渲染)


2.8 PTA提交列表说明。


自己在devc++调试时出现较多问题


感觉自己的定义没出错,调节,查询后发现是 * 问题,该函数要加一个 *

编译错误

自己在打完后的语言选择出错

段错误

自己打代码时的错误

2.9 题目3:7-3 jmu-ds-二叉树层次遍历

2.10 设计思路(伪代码或流程图)

BTNode *trans(string str,int i,int maxsize)//顺序转二叉链表 
{
   若i>maxsize-1或i<0  返回空
   若str[i]==\'#\'  返回空
   创建根结点b
   b->data=str[i];
   创建左子树
   b->lchild=trans(str,2*i,maxsize);
   创建右子树
   b->rchild=trans(str,2*i+1,maxsize);
   return b;
}
void  levelorder(BTree b)//层次遍历 
{
	定义变量flag=0,树指针T
	若b==NULL输出NULL
	否则:
	  初始化队列,根结点入队列
	while(队列不空){
		访问对头结点
		若flag==0   输出T->data并把flag=1
		否则:
		输出空格和T->data;
		当左右孩子不为空时,左右孩子入队
	}
}

2.11 代码截图(注意,截图、截图、截图。代码不要粘贴博客上。不用用···语法去渲染)

2.12 PTA提交列表说明。


树空

自己题目没读好以为树空时输入为 # # 其实是 # 才对

格式错误

自己在devc+调节时的格式是正确的

所以自己找这个错误点找了很久,后来才知道是一个判断条件的问题

正确应该是if(i>maxsize-1||i<0) return NULL

3.1 PTA排名

3.2 我的得分:

180 2分

4. 阅读代码(必做,1分)

#include <stdio.h>
#include<stdlib.h>
#include<string.h>
/* 评测结果 时间  结果  得分  题目  编译器     用时(ms)  内存(MB)  用户
2016-08-30 10:31    全部正确    25  5-27    gcc     1   1   569985011
测试点结果 测试点   结果  得分/满分   用时(ms)  内存(MB)
测试点1    答案正确    18/18   1   1
测试点2    答案正确    2/2     1   1
测试点3    答案正确    5/5     1   1
测试点4    答案正确    5/5     1   1
查看代码*/
typedef struct node *Node;
struct node {
    char Name[11];
    int space;
    int  Parant;
};

Node Tree;
int n;

int Scan(char*);
int Trace(int);
int judgeParent(int,int);//父子
int judgeSibling(int,int);//兄弟
int judgeAncestor(int,int);//祖先
void work();
int Index(char*);

int main() {
    int m;
    scanf("%d%d",&n,&m);
    Tree=(Node)malloc(sizeof(struct node)*n);
    getchar();//清除缓存
    for(int i=0; i<n; i++) {
        Tree[i].space=Scan(Tree[i].Name);
        Tree[i].Parant=i;
    }
    Tree[0].Parant=-1;

    for(int i=0; i<m; i++) {
        work();
        getchar();
    }

    return 0;
}
int judgeParent(int x,int y) {
    if(Tree[x].Parant==x)Tree[x].Parant=Trace(x);
    return Tree[x].Parant==y;
}
int judgeSibling(int x,int y) {
    if(Tree[x].Parant==x)Tree[x].Parant=Trace(x);
    if(Tree[y].Parant==y)Tree[y].Parant=Trace(y);
    return Tree[x].Parant==Tree[y].Parant;
}
int judgeAncestor(int x,int y) {
    while(x!=-1) {
        if(judgeParent(x,y))return 1;
        else x=Tree[x].Parant;
    }
    return 0;
}

void work() {
    char StrX[11],StrY[11],relation[11];
    scanf("%s%*s%*s%s%*s%s",StrX,relation,StrY);
//  printf("%s - %s - %s\\n",StrX,relation,StrY);

    int X=Index(StrX);
    int Y=Index(StrY);
//  printf("%d   -    %d",X,Y);
    int result;
    switch(relation[0]) {
        case \'c\':
            result=judgeParent(X,Y);
            break;
        case \'p\':
            result=judgeParent(Y,X);
            break;
        case \'s\':
            result=judgeSibling(X,Y);
            break;
        case \'d\':
            result=judgeAncestor(X,Y);
            break;
        case \'a\':
            result=judgeAncestor(Y,X);
            break;
        default:
            result=-1;
            break;
    }



    if(result==1)printf("True\\n");
    else if(!result)printf("False\\n");
//  else printf("ERROR:系统不能识别所指定关系!\\n");
}


int Index(char*a) {
    for(int i=0; i<n; i++) {
//      printf("*");
        if(strcmp(Tree[i].Name,a)==0)return i;
    }
//  printf("ERROR:所给人名不存在!\\n");
    return -1;
}

int Trace(int child) { //往前遍历第一个比他缩进少的就是他的父亲

    for(int i=child-1; i>=0; i--) {
        if(Tree[i].space<Tree[child].space) {
//      printf("%d\'s parent is %d\'",child,i);
            return i;
        }
    }
    return -1;//如果没有,那么他就是亚当夏娃了。
}

int Scan(char*p) {
    char c;
    int space=0;

    while((c=getchar())==\' \')space++;//记录字符串前面的空格数量

    do {
        *p++=c;
    } while((c=getchar())!=\'\\n\');
    *p=\'\\0\';

    return space;
}

代码链接:https://blog.csdn.net/Changxing898/article/details/52367278?locationNum=6&fps=1

代码功能:家谱处理

代码优点:运用并查集的知识合并查找,提高效率,比较直观,在空格与人物之间关系的处理分明,祖先,父母,孩子的关系能较好分离

5. 代码Git提交记录截图

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

博客作业04--树

博客作业04--树

博客作业04--树

博客作业04--树

博客作业04--树

博客作业04--树