二叉树按层次遍历--队列实现

来源:互联网 发布:mac os x cdr镜像下载 编辑:程序博客网 时间:2024/05/22 01:54

    最近数据结构看的还真是恶心额,脑子不好使,算法写不来额大哭·····

    二叉树一大堆概念性的东西,不过还是写吧。


二叉树(binary tree)

二叉树的基本形态
  二叉树也是递归定义的,其结点有左右子树之分,逻辑上二叉树有五种基本形态:
  (1)空二叉树——(a);  
      (2)只有一个根结点的二叉树——(b);
  (3)只有左子树——(c);
  (4)只有右子树——(d);
  (5)完全二叉树——(e)


度(Degree):节点孩子的数目。
叶子(Leaf): 度为0的节点称为叶子。
深度(Depth):树中最大的层次(从最上0开始数)


满二叉树:一棵深度为k且有2^k -1个节点的二叉树。
完全二叉树:若设二叉树的高度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层有叶子节点,并且叶子节点都是从左到右依次排布,这就是完全二叉树。


性质1:
在二叉树的第i层上至多有2^(i-1)个节点(i >= 1)
性质2:深度为k的二叉树至多有2^k - 1个节点
性质3:任意一棵二叉树T,若其叶子节点数为n0,度为2的节点数为n2,则n0 = n2 + 1


对于完全二叉树:

性质4:具有n个节点的完全二叉树的深度是[log2n] + 1
性质5:有N个结点的完全二叉树各结点如果用顺序方式存储,则结点之间有如下关系:
    若I为结点编号则 如果I<>1,则其父结点的编号为I/2;
    如果2*I<=N,则其左儿子(即左子树的根结点)的编号为2*I;若2*I>N,则无左儿子;
    如果2*I+1<=N,则其右儿子的结点编号为2*I+1;若2*I+1>N,则无右儿子。


二叉树按层次遍历----队列实现
1.创建二叉树,输入#代表NULL,调用递归创建二叉树。
2.构建一个队列专门用来储存二叉树节点指针,先把根节点入队,假设是A,对A元素进行访问,然后对A的左右孩子依次入队,假设B,C。A出队列,再是对B进行访问,同样将B的左右孩子入队列,B出对列······重复以上,知道队列为空。

下面是的代码是实现按层次从上到下遍历二叉树:

[cpp] view plaincopyprint?
  1. <span style="font-size:16px;">#include <Windows.h>  
  2. #include <stdio.h>  
  3.   
  4. #define ElemType char   
  5.   
  6. typedef struct TreeNode{                //单位节点  
  7.     struct TreeNode *LChild;  
  8.     struct TreeNode *RChild;  
  9.     ElemType c;  
  10. }TreeNode,* p_Tree;  
  11.   
  12. typedef struct Link{                    //单向链表  
  13.     struct Link *Next;  
  14.     TreeNode *Node;  
  15. }Link,*P_Link;  
  16.   
  17. typedef struct Queue{                   //形成队列  
  18.     P_Link front;                         
  19.     P_Link rear;  
  20.     int Q_Len;  
  21. }Queue,*p_Queue;  
  22.   
  23. BOOL PrintElement(ElemType e);          //对二叉树节点的操作,自定义,这里我设置为打印出内容  
  24. BOOL CreateTree(p_Tree* pBiTree);       //创建二叉树  
  25. P_Link InitLink(P_Link L);              //初始化链表               
  26. P_Link InsertLink(P_Link L,TreeNode *Tree_Node,p_Queue *Q);             //插入队列  
  27. p_Queue GetTopLinkNode(P_Link L, BOOL(*Visit)(ElemType),p_Queue Q);     //取出队列第一个元素,并且访问左右孩子  
  28. p_Queue InitQueue(p_Queue T,P_Link L);                                  //初始化队列  
  29.   
  30. int main()   
  31. {  
  32.     p_Tree Tree = NULL;           
  33.     P_Link Link = NULL;  
  34.     p_Queue Queue = NULL;  
  35.     if(!CreateTree(&Tree))                                              //创建二叉树  
  36.     {  
  37.         printf("Create Tree Error\n");  
  38.         return 0;  
  39.     }  
  40.     p_Tree p_Temp_Node = Tree;  
  41.     Link = InitLink(Link);    
  42.     Queue = InitQueue(Queue,Link);  
  43.       
  44.     Link = InsertLink(Link,p_Temp_Node,&Queue);                      //根节点入队  
  45.   
  46.     BOOL(*Operate)(ElemType);                                       //定义函数指针  
  47.     Operate = PrintElement;  
  48.   
  49.     while(Queue->front != Queue->rear)  
  50.     {             
  51.         Queue = GetTopLinkNode(Link,Operate,Queue);                 //获取队列第一个节点  
  52.         Link = InsertLink(Link,Queue->front->Node->LChild,&Queue); //左孩子入队  
  53.         Link = InsertLink(Link,Queue->front->Node->RChild,&Queue); //右孩子入队  
  54.     }  
  55.   
  56.     return 0;  
  57. }  
  58.   
  59. BOOL CreateTree(p_Tree* pBiTree)  
  60. {  
  61.     ElemType ch;  
  62.     ch = getchar();  
  63.     if (ch == '#')                                                  //#代表NULL  
  64.     {  
  65.         (*pBiTree) = NULL;  
  66.     }  
  67.     else  
  68.     {  
  69.         (*pBiTree) = (p_Tree)calloc(1,sizeof(TreeNode));  
  70.         if (!(*pBiTree))  
  71.         {  
  72.             printf("Allocate Memory Error\n");  
  73.             return FALSE;  
  74.         }  
  75.         else  
  76.         {  
  77.             (*pBiTree)->c = ch;  
  78.             CreateTree(&(*pBiTree)->LChild);         //调用递归创建二叉树  
  79.             CreateTree(&(*pBiTree)->RChild);  
  80.         }  
  81.     }  
  82.         return TRUE;  
  83. }  
  84.   
  85. P_Link InitLink(P_Link L)  
  86. {  
  87.     L = (P_Link)calloc(1,sizeof(Link));  
  88.     if (!L)  
  89.     {  
  90.         printf("Memory Error\n");  
  91.         return NULL;  
  92.     }  
  93.     L->Node = NULL;  
  94.     L->Next = NULL;  
  95.     return L;  
  96. }  
  97.   
  98. p_Queue InitQueue(p_Queue T,P_Link L)  
  99. {  
  100.     T = (p_Queue)calloc(1,sizeof(Queue));  
  101.     T->Q_Len = 0;  
  102.     T->front = L;  
  103.     T->rear = L;  
  104.     return T;  
  105. }  
  106.   
  107. P_Link InsertLink(P_Link L,TreeNode *Tree_Node,p_Queue *Q)  
  108. {  
  109.     if (Tree_Node == NULL)  
  110.     {     
  111.         return L;  
  112.     }  
  113.     else  
  114.     {  
  115.         static P_Link p = L;  
  116.         P_Link pNew;  
  117.         pNew = (P_Link)calloc(1,sizeof(Link));  
  118.         if (!pNew)  
  119.         {  
  120.             printf("Memory Error\n");  
  121.             return 0;  
  122.         }     
  123.         pNew->Node = Tree_Node;      //New Node  
  124.         pNew->Next = NULL;  
  125.         p->Next = pNew;              //p to Next  
  126.         p = pNew;  
  127.         (*Q)->rear = p;             //Add Queue  
  128.         (*Q)->Q_Len++ ;             //Q len ++  
  129.         return L;  
  130.     }  
  131. }  
  132.   
  133. p_Queue GetTopLinkNode(P_Link L, BOOL(*Visit)(ElemType),p_Queue Q)  
  134. {  
  135.     Q->front = Q->front->Next;    //remove first Node  
  136.     Visit(Q->front->Node->c);  
  137.     Q->Q_Len--;  
  138.     return Q;  
  139. }  
  140.   
  141. BOOL PrintElement(ElemType e)  
  142. {  
  143.     // 输出元素e的值  
  144.     printf("%c",e);  
  145.     return TRUE;  
  146. }</span>  
0 0
原创粉丝点击