icoding测试代码--先序打印

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

void pre_order(BiTree root){
// 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)
{
    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
            {
                printf("%c", *(a+(i*width)+j));
            }
        }
        printf("\n");
    }
}
/以上为辅助函数
void pre_order(BiTree root){
   //    todo

}

void pre_order_digui(BiTree root){
    if (root == NULL)
        return;
    visit_node(root);
    pre_order_digui(root->left);
    pre_order_digui(root->right);
}


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

    bool print=false;//是否打印树,默认不打印
///--------以 上 内 容 可 以 修 改 ----------------
    printf("---开始测试---\n");
    printf("icoding\n先序遍历\n");
    

    printf(">>正在根据定位串生成树,若生成异常请检查定位码是否正确\n");

    int i=0;//定位串起始点,请勿更改!
    BiTree T = _CreateByStr(nodes, &i);
    printf(">>树生成完毕\n");
    if(!print) printf("\n请注意,打印树的图形过大,默认关闭树的打印功能,若需要请修改main函数的print\n");
    if(print){
        printf(">>打印树,树的打印代码来自于CSDN博主@冀中阿板,若侵权请联系删除\n");
        printBiTree(T);
        putchar('\n');
    }

    
    printf("\n>>基于递归先序遍历(正确的遍历结果)\n");
    pre_order_digui(T);
    printf("\n>>基于栈先序遍历(您的代码的遍历结果)\n");
    pre_order(T);
    printf("\n\n若打印为空请检查是否用到了visit_node()函数");
    printf("\n\n本程序仅供输出结果,不判断结果的正确性");
    printf("\n---测试结束---\n");
    

    return 0;
}

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

 你可以自行修改main函数的print的值来实现打印图的功能。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

谨慎谦虚

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

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

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

打赏作者

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

抵扣说明:

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

余额充值