Chinaunix首页 | 论坛 | 博客
  • 博客访问: 91268
  • 博文数量: 71
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 30
  • 用 户 组: 普通用户
  • 注册时间: 2015-05-13 20:27
文章分类

全部博文(71)

文章存档

2015年(71)

我的朋友

分类: C/C++

2015-07-02 19:11:19

装载请注明来源chengyaogen.blog.chinaunix.net
 
二叉树的创建和遍历网上资料很多,非二叉树的创建和遍历很少有人研究,今天研究了非二叉树创建和遍历。
 
先来看看我们的小树吧:
 
怎么创建,怎么遍历,一个字晕!
总有解决问题的办法的,提供一种思路:
1(2(5,6),3(7,8),4(9))
1是根节点,2是根的第一个孩子,3,4是2的兄弟结点
同理2的第一个孩子结点是5,6是5的兄弟结点
最后就变成了下面图形:
 
 
我们把1(2(5,6),3(7,8),4(9))作为输入,然后构建上面的图:
  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. #define MAX 3

  4. //树的数据结构设计
  5. typedef struct _tree_
  6. {
  7.     int data;
  8.     struct _tree_ *fchild;//第一个孩子结点
  9.     struct _tree_ *schild;//兄弟结点
  10. }Tree;

  11. //分配一个树结点
  12. Tree *space_tnode(char ch)
  13. {
  14.     Tree *cureent;
  15.     
  16.     cureent = (Tree *)malloc(sizeof(Tree));
  17.     cureent->data = ch - '0';
  18.     cureent->fchild = cureent->schild = NULL;

  19.     return cureent;
  20. }

  21. //创建树
  22. Tree *create_tree(char *str)
  23. {
  24.     int level = 0;//层次,我们知道上面的树可以看成三层
  25.     
  26.     Tree *L[MAX],*current;//L[0]指向第一层,L[1]第二层,依次类推

  27.     if(*str >= '0' && *str <= '9' && *(str + 1) == '(')
  28.     {    
  29.         L[0] = space_tnode(*str);
  30.         
  31.     }else{

  32.         printf("format error!\n");
  33.         return NULL;
  34.     }

  35.     while(*str)
  36.     {
  37.         switch(*str)
  38.         {    
  39.             //进入一层
  40.             case '(':
  41.                 str ++;
  42.                 current = space_tnode(*str);
  43.                 //链接第一个孩子结点
  44.                 L[level]->fchild = current;
  45.                 L[++level] = current;
  46.                 break;

  47.             //链接兄弟结点
  48.             case ',':
  49.                 str ++;
  50.                 current = space_tnode(*str);
  51.                 L[level]->schild = current;
  52.                 L[level] = current;
  53.                 break;
  54.                 
  55.             //退出一层
  56.             case ')':
  57.                 level --;
  58.                 break;
  59.         }

  60.         str ++;
  61.     }
  62.     
  63.     return L[0];
  64. }


  65. //以下是队列的设计和实现
  66. typedef Tree *DataType;

  67. typedef struct node
  68. {
  69.     DataType data;
  70.     struct node *next;
  71. }ListNode;

  72. typedef struct
  73. {
  74.     struct node *front;
  75.     struct node *rear;
  76.     
  77. }ListQueue;

  78. ListQueue *create_empty_queue()
  79. {
  80.     ListNode *temp;
  81.     ListQueue *qhead;

  82.     temp = (ListNode *)malloc(sizeof(ListNode));
  83.     temp->next = NULL;

  84.     qhead = (ListQueue *)malloc(sizeof(ListQueue));
  85.     qhead->front = qhead->rear = temp;

  86.     return qhead;
  87. }

  88. int is_empty_queue(ListQueue *p)
  89. {
  90.     if(p->front == p->rear)
  91.         return 1;
  92.     else
  93.         return 0;
  94. }

  95. int enter_queue(ListQueue *p,DataType data)
  96. {
  97.     ListNode *temp;

  98.     temp = (ListNode *)malloc(sizeof(ListNode));
  99.     temp->data = data;
  100.     temp->next = NULL;

  101.     p->rear->next = temp;
  102.     p->rear = temp;

  103.     return 0;
  104. }

  105. DataType delete_queue(ListQueue *p)
  106. {
  107.     ListNode *temp;
  108.     //保存第一个结点
  109.     temp = p->front;
  110.     //移动指针
  111.     p->front = temp->next;
  112.     //删除第一个结点
  113.     free(temp);
  114.     temp = NULL;

  115.     return p->front->data;
  116. }


  117. int main()
  118. {
  119.     Tree *TreeHead,*current;
  120.     char buf[100];
  121.     ListQueue *QueueHead;

  122.     QueueHead = create_empty_queue();
  123.     
  124.     scanf("%s",buf);
  125.     TreeHead = create_tree(buf);
  126.         
  127.          //遍历的思想是树的按层次遍历
  128.     //头结点先入队
  129.     enter_queue(QueueHead,TreeHead);
  130.     while(!is_empty_queue(QueueHead))
  131.     {    
  132.         //头结点出队
  133.         current = delete_queue(QueueHead);
  134.         printf("%d ",current->data);

  135.         //孩子结点入队
  136.         if((current = current->fchild) != NULL)
  137.         {
  138.             enter_queue(QueueHead,current);

  139.             //孩子的所有兄弟结点入队
  140.             while((current = current->schild) !=NULL)
  141.             {
  142.                 enter_queue(QueueHead,current);
  143.             }
  144.         }
  145.     }

  146.     printf("\n");

  147.     return 0;
  148. }
树在遍历的过程,用队列使用层次进行遍历的,先将根节点入队,然后出队,然后把其第一个孩子和第一个孩子的所有兄弟接点入队,依次类推...
阅读(518) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~