二叉树:层次遍历和应用
来源:互联网 发布:如何查找电脑的mac地址 编辑:程序博客网 时间:2024/06/05 15:07
声明:
数据结构和功能函数如之前博客所述,如有疑问,详见系列博客
版权所有,如果转载,请注明出处http://blog.csdn.net/tubin100
一 层次遍历
层次遍历:需要队列作为数据结构
代码如下:
void LevelOrder(BiTree T) { if (nullptr == T) { Error(); return; } std::queue<BiTNode*> q; BiTNode *p = T; q.push(p); while (!q.empty()) { p = q.front(); q.pop(); visit(p); if (p->lChild) { q.push(p->lChild); } if (p->rChild) { q.push(p->rChild); } }}
二 层次遍历应用
1 从下到上,从右到左遍历二叉树
思路分析:
层次遍历每一个节点,每次出队列同时,进入另一个栈,遍历结束后,顺序弹出栈中内容即可。
void LevelOrder_Invert(BiTree T) { if (nullptr == T) { Error(); return; } std::queue<BiTNode*> q; std::stack<BiTNode*> st; BiTNode *p = T; q.push(p); while (!q.empty()) { p = q.front(); q.pop(); st.push(p); if (p->lChild) { q.push(p->lChild); } if (p->rChild) { q.push(p->rChild); } } while (!st.empty()) { std::cout << (st.top())->data << " "; st.pop(); }}
2 判断是否为完全二叉树
思路分析:
a 层次遍历二叉树,不判断孩子节点是否为空,直接入队。
b 每次出队时,判断是否为空,
c 一旦有一个节点为空,则根据完全二叉树的性质,队列中若还有元素,则全部应该为空;
d 若出现一个节点不为空,则立即判断不是完全二叉树;
bool IsCompleteTree(BiTree T) { if (nullptr == T) { Error(); return false; } std::queue<BiTNode*> q; BiTNode *p = T; q.push(p); while (!q.empty()) { p = q.front(); q.pop(); if (p) { q.push(p->lChild); q.push(p->rChild); } else { while (!q.empty()) { p = q.front(); q.pop(); if (nullptr != p) { return false; } } } } return true;}
3 删除以x为根节点的子树
3.1 递归删除二叉树
首先引入,递归删除二叉树的代码。
void DeleteTree(BiTNode* T) { if (T) { DeleteTree(T->lChild); DeleteTree(T->rChild); delete T; }}
3.2 删除以x为根节点的子树
为什么要用层次遍历?
因为删除一个以x为根的节点需要设置x的父节点的孩子域,所以得需要明确父子关系,层次遍历是简单的选择。
思路分析:
层次遍历二叉树,查找以x为儿子的节点,如果找到了,删除该子树,并设置孩子域为空。
代码如下:
bool DeleteXTree(BiTree T, BTElemType x) { if (nullptr == T) { Error(); return false; } std::queue<BiTNode*> q; BiTNode *p = T; q.push(p); while (!q.empty()) { p = q.front(); q.pop(); if (p->lChild && p->lChild->data == x) { DeleteTree(p->lChild); p->lChild = nullptr; return true; } if (p->rChild && p->rChild->data == x) { DeleteTree(p->rChild); p->rChild = nullptr; return true; } } return false;}
4 非递归算法求解树的高度
思路分析
a 用一个last指针指向每一层节点的最后一个元素
b 元素正常入队。
c 每次出队时,front指针会自增,每当front指针 ‘赶上’ 了 last指针时,说明此时一层已经完全出队。此时设置last指针指向rear指针,并且level自增
代码如下:
int BiTreeHeight_non_recur(BiTree T) { if (!T) { return 0; } //模拟队列 int front, rear; BiTNode* q[50]; //假设元素个数小于50 front = rear = -1; int level = 0; //标识层次 int last = 0; //标识当前层中最右端节点 BiTNode *p = T; ++rear; q[rear] = p; while (front < rear) { ++front; p = q[front]; if (p->lChild) { ++rear; q[rear] = p->lChild; } if (p->rChild) { ++rear; q[rear] = p->rChild; } //关键点 if (front == last) { //front 赶上了 last ++level; last = rear; //重新指向当前层的最右端节点 } } return level;}
5 求二叉树宽度
思路分析:
a 定义结构体如下:
typedef struct WidthNode { BiTNode *pointer; int level;}WidthNode;
b 每个节点都有层号。
设置根节点的层号为1,通过遍历的过程给每个节点设置层号,可以得到一组带有层号的节点队列。
c 层号出现次数最多,则出现的次数即为二叉树的宽度。
d 通过遍历该队列,将层号映射到数组中,通过一次遍历数组即可求得层号出现最多的次数。
代码如下:
int BiTreeWidth(BiTree T) { if (!T) { return 0; } WidthNode q[50]; int front, rear; front = rear = -1; WidthNode p; p.pointer = T; p.level = 1; //根节点的层号为1 ++rear; q[rear] = p; WidthNode temp; while (front < rear) { ++front; p = q[front]; if (p.pointer->lChild) { temp.pointer = p.pointer->lChild; temp.level = p.level + 1; ++rear; q[rear] = temp; } if (p.pointer->rChild) { temp.pointer = p.pointer->rChild; temp.level = p.level + 1; ++rear; q[rear] = temp; } } //假设树高不超过10 //在一组数据中选择一个出现次数最大的数---- //数据的特点:递增,且范围在1-height之间, //思路:把数据映射到数组中 int a[11] = {0}; for (int i = 0; i <= rear; ++i) { ++a[q[i].level]; } int width = -1; for (int i = 0; i < 11; i++) { if (a[i] > width) { width = a[i]; } } return width;}
6 总结
1 在熟练掌握了层次遍历的基本框架之后,对于一些简单的应用还是比较熟练的用代码实现。
2 只是其中有些并没有考虑到扩展性,例如自定义的队列数组的大小,这个在实践中最好是不要用的额,因为很容易有各种问题(空间不足或者资源浪费)。
- 二叉树:层次遍历和应用
- 二叉树层次遍历和深度遍历
- 二叉树层次遍历和深度遍历
- 二叉树层次遍历的应用--改造二叉链表
- 层次遍历二叉树
- 层次遍历二叉树
- 二叉树层次遍历
- 二叉树 层次遍历
- 二叉树层次遍历
- 层次遍历二叉树
- 二叉树层次遍历
- 层次遍历二叉树
- 二叉树层次遍历
- 二叉树层次遍历
- 层次遍历二叉树
- 二叉树层次遍历
- 二叉树层次遍历
- 层次遍历 二叉树
- OpenCV学习14
- SSDC_新型架构案例与实践
- SSDC_从概率统计方向来做系统稳定性
- C#---抽象类与接口
- C++面试题2
- 二叉树:层次遍历和应用
- Shell 排序
- SSDC_高可用系统在点评的实践与经验
- 《三种继承方式详解》
- ScrollView中ViewPager无法正常滑动的问题
- C++面试题3
- SSDC_从0到1,手腕上的人工智能
- HDU 4323 Magic Number(DP)
- JavaWeb开发之一:入门篇