一步一步写算法(之二叉树广度遍历)

来源:互联网 发布:淘宝部分退货运费险 编辑:程序博客网 时间:2024/06/18 15:48

原贴地址: http://blog.csdn.net/feixiaoxing/article/details/6897095

【 声明:版权所有,欢迎转载,请勿用于商业用途。  联系信箱:feixiaoxing @163.com】


    在二叉树的遍历当中,有一种遍历方法是不常见的,那就是广度遍历。和其他三种遍历方法不同,二叉树的广度遍历需要额外的数据结构来帮助一下?什么数据结构呢?那就是队列。因为队列具有先进先出的特点,这个特点要求我们在遍历新的一层数据之前,必须对上一次的数据全部遍历结束。暂时还没有掌握队列知识的朋友可以看一看我的这一篇博客—队列。

    a)下面是新添加的队列数据结构,其中数据部分换成了树节点指针的指针:

[cpp] view plaincopy
  1. typedef struct _QUEUE  
  2. {  
  3.     int head;  
  4.     int tail;  
  5.     int length;  
  6.     TREE_NODE** pHead;  
  7. }QUEUE;  
    注:head表示开始,tail表示结束,length表示pHead的长度,pHead表示指针的起始地址


    b)创建队列,因为涉及到length的长度问题,所以需要计算二叉树中节点的总数

[cpp] view plaincopy
  1. QUEUE* create_queue_for_tree(const TREE_NODE* pTreeNode)  
  2. {  
  3.     QUEUE* pQueue;  
  4.     int count;  
  5.   
  6.     if(NULL == pTreeNode)  
  7.         return NULL;  
  8.   
  9.     count = count_all_node_number(pTreeNode);  
  10.     pQueue = (QUEUE*)malloc(sizeof(QUEUE));  
  11.     assert(NULL != pQueue);  
  12.     memset(pQueue, 0, sizeof(QUEUE));  
  13.   
  14.     pQueue->pHead = (TREE_NODE**)malloc(sizeof(TREE_NODE*)* count);  
  15.     assert(NULL != pQueue->pHead);  
  16.     memset(pQueue->pHead, 0, sizeof(TREE_NODE*) * count);  
  17.   
  18.     pQueue->head = pQueue->tail = 0;  
  19.     pQueue->length = count;  
  20.     return pQueue;  
  21. }  


    c)实现队列的数据加入和数据弹出操作

[cpp] view plaincopy
  1. void insert_node_into_queue(QUEUE* pQueue, TREE_NODE* pNode)  
  2. {  
  3.     if(NULL == pQueue || NULL == pQueue->pHead ||NULL == pNode)  
  4.         return;  
  5.   
  6.     pQueue->pHead[pQueue->tail ++] = pNode;  
  7.     return;  
  8. }  
  9.   
  10. TREE_NODE* get_node_from_queue(QUEUE* pQueue)  
  11. {  
  12.     if(NULL == pQueue || NULL == pQueue->pHead)  
  13.         return NULL;  
  14.   
  15.     if(pQueue->head == pQueue->tail)  
  16.         return NULL;  
  17.   
  18.     return pQueue->pHead[pQueue->head++];  
  19. }  
    注:这里定义的队列不是循环队列,所以数据的压入和弹出比较简单,直接对head和tail处理即可


    d)遍历节点,按层得到数据,最后再pQueue->pHead中得到的指针数据就是按层输出的结果

[cpp] view plaincopy
  1. QUEUE* traverse_node_by_layer(TREE_NODE* pNode)  
  2. {  
  3.     QUEUE* pQueue;  
  4.     if(NULL ==pNode)  
  5.         return NULL;  
  6.   
  7.     pQueue = create_queue_for_tree(pNode);  
  8.     assert(NULL != pQueue);  
  9.   
  10.     /* 首个节点加入队列 */  
  11.     insert_node_into_queue(pQueue, pNode);  
  12.     pNode = get_node_from_queue(pQueue);  
  13.   
  14.     while(pNode){  
  15.         if(pNode->left)  
  16.             insert_node_into_queue(pQueue, pNode->left);  
  17.   
  18.         if(pNode->right)  
  19.             insert_node_into_queue(pQueue, pNode->right);  
  20.   
  21.         pNode = get_node_from_queue(pQueue);  
  22.     }  
  23.   
  24.     return pQueue;  
  25. }  

扩充部分:

    上面的办法已经可以实现队列的按层输出,那么如果想在节点结构中直接实现数据的按层访问怎么办?其实两步走就可以:1)在已有的TREE_NODE添加prev和next;(2)按照刚才得到的pQueue->pHead结果,依次对prev和next进行赋值即可。不知道朋友们明白了没?



0 0