C语言打印树基础

相信二叉树是学算法很重要的一门课,但是网上的打印树实现都不好找,于是自己写来玩玩。这是过程代码,最终版在

http://blog.csdn.net/xzongyuan/article/details/22073619

C语言打印二叉树


本章基于前一篇http://blog.csdn.net/xzongyuan/article/details/21880013(实现广度遍历)

实现了二叉树的打印,要点:

1.要使得二叉树节点排列对齐,首先以个位数作为模型,计算出每个字符之间的间距是多少

// ***************0****************  pad_between = 31 ; pad_front = 15  (depth == 1)
// *******0***************0********  pad_between = 15 ; pad_front = 7   (depth == 2)
// ***0*******0*******0*******0****  pad_between = 7  ; pad_front = 3   (depth == 3)
// *0***0***0***0***0***0***0***0**  pad_between = 3  ; pad_front = 1   (depth == 4)
// 0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*  pad_between = 1  ; pad_front = 0;  (depth == 5)

定义pad_num表示位数大小,如果是二位树或更多位,则个位数的模型间距乘以pad_num就可以保证这个模型的对齐了。


2.给队列节点增加表示深度depth和空节点的标识。如果是blank节点,则打印成o,而且,blank节点要加入队列,并且其子树也是blank节点,要参与遍历。这样做的目的是在遇到空节点时候,可以打印出空节点的前后间隔。我还想过用二进制表示左右方向,然后转化为十进制,例如00,01,10,11,对应的是1,2,3,4.我在队列遍历时候,用十进制就可以计算出前面缺了哪个数据节点。但我觉得这算法有点麻烦,就用了最直观的办法:增加空节点。

3.关键思想是利用深度去计算间距,而且每一层间距的差别都是倍数,用移位的办法就可以实现倍数计算。两个节点之间的间距,除了本身有的间距pad_front,还要加上父节点的间距.

4.使用printf打印指定间隔,可以打印指定数量的字符,用%*s参数或者%*d,但是printf只能对余下的补空格或0,不能补其它字符。如果要补其它字符,可能要自己写函数。

5.使用办法,默认节点书用define NUM 10定义为5,可以在运行程序时候,输入一个参数如./a.out 15,就可以改变NUM大小,详情请看代码

6.下一步打算给树加上树枝,显得更加清晰。然后不再把那些空节点打印出来。

7.在createTree函数里面,可以修改随机的range范围,但是要注意位数,为了不把程序写的太复杂,没有判断最大range的位数的算法,所以要在breath_travel里面把pad_num修改为对应的。如range为100,则pad_num为2.range为500,则pad_num为3.

结果如下:

 

由于格式问题,贴上来的树没对齐,不过在终端上是对齐的,如图


 

//Design by Dark:http://blog.csdn.net/xzongyuan

 #include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define NUM 5
typedef struct _node
{
   int value;
   struct _node *left;
   struct _node *right;
}TNode,*Tree;

//add a *next in q_node is my purpose
//other wise , we need to add in the Tree node struct
//So, for the sake of doesn't modify the struct of tree
//I design a q_node struct to include it
//we can use define command to make it as a template.
typedef struct _q_node
{
  TNode *t_node;
  int depth;
  int blank;  //0: means correspoinding tree node is not NULL(default)
  struct _q_node *next;
}QNode;

typedef struct _Queue
{
   QNode *head;
   QNode *tail;
}Queue;

Queue* init_queue()
{
   Queue *queue=(Queue*)malloc(sizeof(Queue));
   queue->head = queue->tail = NULL;
   return queue;
}

int enQueue(Queue *pQueue,TNode *pTNode,int pDepth)
{

      QNode *pQNode = (QNode *)malloc(sizeof(QNode));
      pQNode->depth = pDepth;
      pQNode->blank = 0; //default config 
      if(pTNode==NULL)
      {
         //change default setting; 1 means it's blank QNode
         pQNode->blank =1;
      }

      pQNode->t_node= pTNode;
      if(pQueue->head == NULL)
      {//when it's empty
           pQueue->head = pQNode; 
       pQueue->tail = pQNode;     
      }    
      else
      {
           pQueue->tail->next = pQNode;
       pQueue->tail = pQNode;
      }
}

QNode* deQueue(Queue *pQueue)
{
    if(pQueue->head == NULL)
    {
       return NULL;
    }

    QNode *deNode= pQueue->head;
    pQueue->head = pQueue->head->next;  
        return deNode;
}

TNode* init_TNode(int value)
{
    TNode  *new_node = (TNode*)malloc(sizeof(TNode));
    new_node->value=value;
    new_node->left = new_node->right = NULL;
    return new_node;
}

//0:empty
int ifEmpty(Queue *pQueue)
{
   if(pQueue->head == NULL)
   {
     //printf("empty tree\n");
     return 0;
   }
   
   //printf("queue is not empty\n");
   return 1;
}


int insert_tree(Tree pTree,int pValue)
{

   //found NULL sub tree, then add to his father->left
   if(!pTree)
   {
      return 0;
   }
   TNode *tNode = init_TNode(pValue);
   if(tNode==NULL)
   {
       printf("create TNode error!\n");
       return 0;
   }
       

   if(pValue < pTree->value) 
        if(insert_tree(pTree->left,pValue)==0)
        {
       //no left child any more,set a new left child to pTree
       pTree->left = tNode;
          printf("insert :%d\n",pValue);
    }
   if(pValue > pTree->value)
        if(insert_tree(pTree->right,pValue)==0)
        {
           pTree->right = tNode;
       printf("insert :%d\n",pValue);
        }
}

Tree creatTree(int num)
{
    srand(time(NULL));
    Tree root = init_TNode(rand()%500);
    printf("root is %d\n",root->value);
    int i ;
    for(i=1;i<num;i++)
    {
        insert_tree(root,rand()%100); 
    }
    printf("creat tree succuess!Tree heigh is:%d\n",get_tree_height(root));
    return root ;
}

int get_tree_height(Tree pRoot)
{

  if(!pRoot)
  {
    return 0; 
  }

  int lh=0,rh=0;
  lh = get_tree_height(pRoot->left);
  rh = get_tree_height(pRoot->right);
  return (lh<rh)?(rh+1):(lh+1);
}



int breath_travel(Tree pRoot,Queue *pQueue)
{
   int height = get_tree_height(pRoot);
   int pad_num = 3;
   //compare to the node's depth in the "while loop"
   int current_depth = 1;
   if(!pRoot)
   {
      return 0;
   }      
   
   enQueue(pQueue,pRoot,1);
   printf("_______________________\n");
   printf("breath begin,enter root:\n");

   while(ifEmpty(pQueue)!=0)
   {

     QNode  *qNode  = deQueue(pQueue);
     //the sub node's depth is 1 more then the parent's
     int child_depth = qNode->depth+1; 

     if(qNode->depth > current_depth)
     {
         current_depth = qNode->depth;
         printf("\n\n");
     }
// ***************0****************  pad_between = 31 ; pad_front = 15  (depth == 1)
// *******0***************0********  pad_between = 15 ; pad_front = 7   (depth == 2)
// ***0*******0*******0*******0****  pad_between = 7  ; pad_front = 3   (depth == 3)
// *0***0***0***0***0***0***0***0**  pad_between = 3  ; pad_front = 1   (depth == 4)
// 0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*  pad_between = 1  ; pad_front = 0;  (depth == 5)
// Tree height = 5
// pad_num = 1
// padding between node = (1+2*pad_front)*pad_num = (1+ (1<<(height-depth))-1)*pad_num
    
     int pad_front = (1<< (height - current_depth))-1;

     if((qNode->blank == 1))
     {
       //add the parent node's padding:2
        if(pad_front == 0)    printf("%*s%*s",pad_num,"o",pad_num," ");
        else                  printf("%*s%*s%*s",pad_front*pad_num," ",pad_num,"o",(1+pad_front)*pad_num," ");

       if(child_depth<=height)
       {
         //enter two NULL sub-tree node.
         //every time you enter NULL TNode,there's corresponding blank QNode.
         enQueue(pQueue,NULL,child_depth);
         enQueue(pQueue,NULL,child_depth);
       }
     }
     else
     {
        if(pad_front == 0)   printf("%*d%*s",pad_num,qNode->t_node->value,pad_num," ");
        else                 printf("%*s%*d%*s",pad_front*pad_num," ",pad_num,qNode->t_node->value,(1+pad_front)*pad_num," ");
       if(child_depth <=height)
       {
     enQueue(pQueue,qNode->t_node->left,child_depth);
         enQueue(pQueue,qNode->t_node->right,child_depth); 
       } 
     }

   } //while end   
     printf("\n-----------\nbreath end!\n-----------\n");

   return 1;
}

int main(int argc,char **argv)
{
  Queue *queue=init_queue();
  int i;

  ifEmpty(queue);
  printf("insert node to queue\n");

  int num = NUM; //default
  if(argc == 2)
  {
    num = atoi(argv[1]); 
  }

  Tree root = creatTree(num);
  if(!root)
  {
    printf("create Tree failed!\n");
    return 0;
  }

  breath_travel(root,queue);
  return 0;
}


  • 10
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,我可以帮你回答这个问题。下面是一个基于C语言的二叉排序的创建函数CreateBSTree的实现: ```c #include <stdio.h> #include <stdlib.h> typedef struct BSTreeNode { int data; struct BSTreeNode* left; struct BSTreeNode* right; } BSTreeNode; // 在二叉排序中插入一个节点 void insert(BSTreeNode** root, int data) { if (*root == NULL) { *root = (BSTreeNode*)malloc(sizeof(BSTreeNode)); (*root)->data = data; (*root)->left = NULL; (*root)->right = NULL; } else if (data < (*root)->data) { insert(&((*root)->left), data); } else if (data > (*root)->data) { insert(&((*root)->right), data); } } // 建立二叉排序 BSTreeNode* CreateBSTree(int* arr, int n) { BSTreeNode* root = NULL; int i; for (i = 0; i < n; i++) { insert(&root, arr[i]); } return root; } // 打印二叉排序 void printBSTree(BSTreeNode* root) { if (root != NULL) { printf("%d ", root->data); printBSTree(root->left); printBSTree(root->right); } } int main() { int arr[] = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5}; int n = sizeof(arr) / sizeof(arr[0]); BSTreeNode* root = CreateBSTree(arr, n); printBSTree(root); return 0; } ``` 在这个实现中,我们定义了一个`BSTreeNode`结构体,它包含了一个`int`类型的数据和两个指向左右子节点的指针。我们还定义了一个`insert`函数,它用于向二叉排序中插入一个节点。在`CreateBSTree`函数中,我们遍历输入的数组,然后对于每个元素调用`insert`函数来插入到二叉排序中。最后,我们返回指向根节点的指针。 在这个例子中,我们输入了一个整数数组,但你可以根据需要更改输入方式。同时,该代码还包括一个`printBSTree`函数用于输出二叉排序中的节点。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值