icoding测试代码--路径&&共同祖先

icoding的数据结构并没有一个测试代码,其都是直接编写一个函数的形式,因此很难知道自己的实际输出是什么。针对部分题目,我编写了一系列测试代码以供大家进行数据输出的测试。

bool path(BiTNode* root, BiTNode* node, Stack* s){
//TODO

}

BiTNode * nearest_ancestor(BiTree root, BiTNode *p, BiTNode *q){
//TODO
}
请将您的函数代码复制到上述函数中,然后修改main函数的相关内容,完成测试样例的输入

注意:icoding代码以int为数据类型,我们这里以字母为数据

打印树的代码源程序来自 打印树源程序

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

//二叉树的创建
#define Stack_Size 50
typedef char DataType;

typedef struct Node{
    DataType data;
    struct Node* left;
    struct Node* right;
}BiTNode, *BiTree;

typedef BiTNode* ElemType;
typedef  BiTNode* P_Node;
typedef struct{
    ElemType elem[Stack_Size];
    int top;
}Stack;

int width,height;//打印需要用到的
void visit_node(BiTNode *node){
    printf("%c ",node->data);
}

void init_stack(Stack *S) // 初始化栈
{
    S->top = -1;
}
bool push(Stack* S, ElemType x) //x 入栈
{
    if (S->top == Stack_Size - 1)
        return false;
    S->top++;
    S->elem[S->top] = x;
    return true;
}
bool pop(Stack* S, ElemType *px) //出栈,元素保存到px所指的单元,函数返回true,栈为空时返回 false
{
    if (S->top == -1)
        return false;
    *px = S->elem[S->top];
    S->top--;
    return true;
}
bool top(Stack* S, ElemType *px) //获取栈顶元素,将其保存到px所指的单元,函数返回true,栈满时返回 false
{
    if (S->top == -1)
        return false;
    *px = S->elem[S->top];
    return true;
}
bool is_empty(Stack* S)  // 栈为空时返回 true,否则返回 false
{
    if (S->top == -1)
        return true;
    return false;
}

//创建树,将输入的字符串以先序的形式存入二叉树
BiTree _CreateByStr(char *nodes, int *i) {
    //定位串处理完了
    if (nodes[*i] == '\0') return NULL;

    //遇到了定位串中的'.',这表明这颗子树是空树
    if (nodes[*i] == '.') {
        ++ *i;
        return NULL;
    }

    //生成新节点,填充数据
    BiTree root = (BiTree)malloc(sizeof(BiTNode)); //生成一个新结点
    //找到字母标签对应的对照表项,并赋值给data域
    root->data = nodes[*i];
    
    //每消费了一个字符,下标*i要后移
    ++ *i;
    //递归生成子树
    root->left = _CreateByStr(nodes, i); //生成左子树
    root->right = _CreateByStr(nodes, i); //生成右子树

    return root;
}

//求深度
int DeepTree(P_Node T)
{
    if(!T)
    {
        return 0;
    }
    return DeepTree(T->left)>DeepTree(T->right)?DeepTree(T->left)+1:DeepTree(T->right)+1;
//关键代码:如果该节点的左子树深度大于右子树则将左子树的深度加一返回,这个返回值便是以该节点做根节点的树的深度,右子树深度大时则相反
}

//T为二叉树的根节点,a是数组的起始地址,i,j是当前节点在数组中的位置
//如果节点有孩子,其孩子的j坐标为 j±(height-i+1)/2
void fillArray(P_Node T,char *a,int i, int j)
{
    int ti,tj;
    if(T) //如果该位置有节点
    {
        *(a+(i*width)+j) = T->data; //向数组该点填入字符
        if(T->left) //有左右孩子给对应的连接线,左右孩子的值在下一层递归赋
        {
            //将该点与其左孩子之间的连线全部填上'/'
            for(ti=i+1,tj=j-1;tj>j-(height-i+1)/2;tj--)
            {
                *(a+((ti)*width)+tj) = -1;
                ti++;
            }
        }
        if(T->right)
        {
            for(ti=i+1,tj=j+1;tj<j+(height-i+1)/2;tj++)
            {
                *(a+((ti)*width)+tj) = 1;
                ti++;
            }
        }
        //经过循环,ti恰好指到其孩子所在的层
        fillArray(T->left, a, ti, j-(height-i+1)/2);
        fillArray(T->right, a, ti, j+(height-i+1)/2);
    }
}

void printBiTree(P_Node T,char  search_node)
{
    int i,j;
    int n = DeepTree(T); //计算出深度n
    //在计算机中数据以二进制形式存储,所以一个数据左移1位就相当于乘以2的1次方
    width = (2<<n)-3;  // 2^(n+1)-3
    height = (2<<(n-1))-1; // 2^n-1
    char *a = (char *)malloc(sizeof(char) * (width*height)); // 申请空间
 
    // 空间初始化为0
    for(i=0;i<height;i++)
    {
        for(j=0;j<width;j++)
        {
            *(a+(i*width)+j) = 0;
        }
    }
 
    //调用之前定义好的函数,填充打印数组
    fillArray(T, a, 0, (width-1)/2);
 
    //根据打印数组的内容来实现打印
    for(i=0;i<height;i++)
    {
        for(j=0;j<width;j++)
        {
            if(*(a+(i*width)+j) == -1)
            {
                printf("/");
            }else if(*(a+(i*width)+j) == 1)
            {
                printf("\\");
            }else if(*(a+(i*width)+j) == 0)
            {
                printf(" ");
            }else
            {
                if(search_node==*(a+(i*width)+j)){
                printf("*%c", *(a+(i*width)+j));
                }
                else{
                printf("%c", *(a+(i*width)+j));
                }
            }
        }
        printf("\n");
    }
}

//查找节点
P_Node Search(P_Node T, char c)
{
    if(!T)
    {
        return NULL;
    }
    if(T->data == c)
    {
        return T;
    }
    P_Node p = Search(T->left, c);
    if(p)
    {
        return p;
    }
    p = Search(T->right, c);
    if(p)
    {
        return p;
    }
    return NULL;
}
void printPreOrder(P_Node T,char search_node){
    if(T){
        if(search_node==T->data){
            printf("[%c]",T->data);
        }
        else{
            printf("%c",T->data);
        }
        printPreOrder(T->left,search_node);
        printPreOrder(T->right,search_node);
    }
}

//  /以上为辅助函数
bool path(BiTNode* root, BiTNode* node, Stack* s){
   //TODO

}

BiTNode * nearest_ancestor(BiTree root, BiTNode *p, BiTNode *q){
//TODO
    

}

int main(){
///--------以 下 内 容 可 以 修 改 ----------------
    char nodes[] = "ABC..D..EF..GH..";
    //这是树的定位串,采用先序排列,每个节点的左右孩子用'.'分隔,空节点用'.'代替
    //”.”表示空节点,即左/右孩子不存在
    //这里提供了一些树的先序定位串
    
    //1. ABC..DE..GH..F... ( 图大,不便打印)
    //2. ABC...DE.F..       (图小,可以打印)
    //3. ABCD....EF..G... (图小,可以打印)
    //4. ABCD.E..F..G... (图大,不便打印)
    //5. AB.CD.E..F..G...(图小)
    //6. ABC..D..EF..GH..(图小)
    //错误的使用“.”可能造成无法打印或者输出图形过于大

    
    int print=3;//是否打印树,0:不打印,1:打印图形,2:打印先序遍历,3:两者都打印。

    char search_node='C';//路径,要查找的节点(字母)
    //无论是否运行路径函数,都需要指定一个path的待寻找的节点,不能不写。

    bool flag=true;//是否进行共同祖先题目的运行?
    char node_p='C';//共同祖先,需要定位的节点1(字母)
    char node_q='E';//共同祖先,需要定位的节点2(字母)
///--------以 上 内 容 可 以 修 改 ----------------
    printf("---开始测试---\n");
    printf("icoding\n路径&&共同祖先\n");
    

    printf(">>正在根据定位串生成树,若生成异常请检查定位码是否正确\n");
    //检查nodes是否合法(所有元素是否均为大写字母或者.)
    int check[27]={0};
    for(int i=0;i<strlen(nodes);i++){
        if(nodes[i]=='.'||nodes[i]>='A' || nodes[i]<='Z'){
            if(nodes[i]>='A' && nodes[i]<='Z'){
                check[nodes[i]-'A']++;
            }
        }else{
            printf(">>定位串中存在非法字符(不是大写字母或.),请检查定位串是否正确,程序自动终止\n");
            return 0;
        }
    }
    for(int i=0;i<26;i++){
        if(check[i]!=1||check[i]!=0){
            printf(">>定位串中存在重复大写字母,程序自动终止\n");
            return 0;
        }
    }
    //检查节点是否在A-Z范围内
    if(search_node<'A' || search_node>'Z'){
        printf(">>待搜索的节点不在A-Z范围内,请检查输入\n程序自动终止,请修改search_node\n");
        return 0;
    }

    int i=0;//定位串起始点,请勿更改!
    BiTree T = _CreateByStr(nodes, &i);
    printf(">>树生成完毕\n");
    printf("##打印树的图形较大时,为了展示效果,请关闭树的打印功能,开启打印树的先序遍历串或换用图形小的树。\n   若需要请修改main函数的print\n\n--------\n");
    if(print==1||print==3){
        printf(">>打印树,树的打印代码来自于CSDN博主@冀中阿板,若侵权请联系删除,要查找的节点已用*标注\n");
        printBiTree(T,search_node);
        putchar('\n');
    }
    if(print==2||print==3){
        printf(">>打印树的先序遍历串,要查找的节点已用[]标注\n\n");
        printPreOrder(T,search_node);
        putchar('\n');
    }

    Stack s;
    init_stack(&s);
    BiTNode* node = Search(T, search_node);

    printf("\n--------\n>>正在查找节点:%c\n", search_node);
    
    bool ret;
    ret=path(T, node, &s);
    printf(">>查找完毕");

    if(ret){
    printf("函数返回true\t正在打印路径\n");
    //倒序打印路径
    int cou_k=0;
    while(!is_empty(&s)){
        BiTNode* p;
        top(&s, &p);
        if(cou_k==0){
            printf(" %c ", p->data);
            cou_k++;
        }
        else{
        printf("--> %c ", p->data);
        }
        pop(&s, &p);
  
    }
    printf("\n\n路径为从节点到根的顺序,因为栈是先进后出,这是正常的\n");
    }
    else{
        printf("函数返回false\t没有找到节点\n");
        if(node!=NULL){
            printf("\n但是树中确实有%c节点存在,请检查编写的代码!\n", search_node);
            if(flag){
                printf("因为您的path函数错误,因而我们无法保障共同祖先函数的正常运行,请修改path函数!共同祖先函数将不会运行\n");
                flag=false;
            }
        }
    }

    
    if(flag){
        printf("-----\n");
        printf("根据设置,将继续运行共同祖先测试,请保证先完成path的编写,保证至少90的得分\n");

        //检查节点是否在A-Z范围内
        if(node_p<'A' || node_p>'Z'){
        printf(">>node_p节点不在A-Z范围内,请检查输入\n程序自动终止,请修改search_node\n");
        return 0;
        }
        if(node_q<'A' || node_q>'Z'){
        printf(">>node_q节点不在A-Z范围内,请检查输入\n程序自动终止,请修改search_node\n");
        return 0;
        }

        BiTNode* nodep = Search(T, node_p);
        BiTNode* nodeq = Search(T, node_q);
        if(nodep==NULL||nodeq==NULL){
            printf("请留意,无法在图中找到node_p/node_q节点,寻找到的共同祖先应该为空\n");
        }
        printf("\n>>正在寻找 %c 和 %c 的共同祖先\n", node_p, node_q);
        BiTNode* ptr=nearest_ancestor(T, nodep, nodeq);
        if(ptr!=NULL){
        printf(">>函数有返回值\t共同祖先为:%c\n", ptr->data);
        }
        else{
            printf(">>函数返回指针为空\t未找到共同祖先,可能是您输入的节点不存在或者代码编写错误。\n");
        }

        
    }
    else{
        printf("\n>>您未运行共同祖先的函数,若需要请修改main函数的flag\n");
    }

    
    printf("本程序仅供输出结果,不判断结果的正确性\n");
    printf("\n---测试结束---\n");
    
    

    return 0;
}

若不对main函数的内容进行改动,那么输出的结果将是

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

谨慎谦虚

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值