在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
!!版权声明:本文为博主原创文章,版权归原文作者和博客园共有,谢绝任何形式的 转载!! 作者:mohist
--- 欢迎指正--- 题外话:上一篇关于平衡二叉树文章中,我都没说自己是怎么理解的。别人终归就是别人的。但别人真的是写的棒棒的。 这里续平衡二叉树的其他方法: 二叉树的 层次遍历 。 层次遍历,原则:从上到下,从左到右。 1、使用队列: 思路: A、首先将根结点入队 B、再输出队首的值 C、若队首结点的左孩子不为空,将其入队 D、若队首结点的右孩子不为空,将其入队 E、因为已经输出队首的值,这时,需要将其出队。 F、反复执行A到E的步骤。直到树的最后一个元素。 分析: 执行过上面的步骤 E,此时,队列中对头的元素就是上次以入队的元素,若步骤C中队首的左孩子不为空,左孩子就是现在的队首。当执行下一次循环是,首先输出的就是左孩子了。同理,步骤D中的右孩子如果入队,下次循环执行输出的就是它了。以此类推。 2、上源码: 例子中使用的根结点结构: struct node { int data; int height; node *lc; node *rc; node() : data(0) , height(0) , lc(0) , rc(0) { } }; 使用队列,需要包含头文件 #include <queue> 队列实现: // 层次遍历树 (使用队列) void layer_order() { cout << endl << endl << "层次遍历,是用队列完成" << endl; queue<node*> vq; if (NULL != root) vq.push(root); // 队列不为空,继续遍历 while (false == vq.empty()) { cout << vq.front()->data << " -> "; // 若左孩子不为空,则继续加入队列 if ( NULL != vq.front()->lc ) { vq.push(vq.front()->lc); } // 若右孩子不为空,则继续入队 if (NULL != vq.front()->rc) vq.push(vq.front()->rc); // 已经遍历输出的元素,出队 vq.pop(); } cout << endl << endl; }
我的测试结果: 4、其他方法 若不实用队列,怎么实现? 数组。前提,数组能够存放整棵树的结点、数组大小不会 爆栈 。有缺陷。 数组的化,模拟上面的队列输出,增加两个索引,一个用来添加树的结点元素用,一个用来输出元素用。 上代码: // 层次遍历,不是用队列,使用数组完成 void layer_order_arr() { cout << endl << endl << " 层次遍历,不是用队列,使用数组完成 " << endl; // 定义指针数组的大小 const int arr_len = 100; // 保存结点指针 node *arr[arr_len] = {0}; // 添加元素索引,添加到数组时使用 int in_index = 0; // 输出元素索引,输出元素使用 int out_index = 0; // 添加结点 if (NULL != root) arr[in_index++] = root; // 若 添加元素索引大于输出元素索引,说明数组中还有没有输出的元素 while ( in_index > out_index) { // 输出 cout << arr[out_index]->data << " -> "; // 若左子树不为空,将其添加到数组 if (NULL != arr[out_index]->lc) arr[in_index++] = arr[out_index]->lc; // 若右子树不为空,将其添加到数组 if (NULL != arr[out_index]->rc) arr[in_index++] = arr[out_index]->rc; // 输出索引指向数组的下一个元素 out_index++; } } 数组的方式输出结果:
GitHub地址: https://github.com/mohistH/base_data_structure
|
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论