IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 二叉树的实现及非递归遍历 -> 正文阅读

[数据结构与算法]二叉树的实现及非递归遍历

二叉树的结构体定义

 struct TreeNode {  //二叉树结构体定义(来自leetcode)
      int val;
      TreeNode *left;
      TreeNode *right;
      TreeNode() : val(0), left(nullptr), right(nullptr) {}
      TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 };

二叉树的构建
这里采用层序遍历对二叉树进行插入操作(需要关注的点时,构建树时一般站在父节点的角度,防止丢失与根结点的联系,而遍历二叉树时可以站在当前结点去考虑问题。(这是本蒟蒻目前能达到的理解深度)

TreeNode* LevelOrder(TreeNode* p,int v) {  //采用层序遍历构建二叉树,在移动f结点时要小心不要让它丢失了和树的联系,尽量站在存在的父节点对左右孩子进行判断
     TreeNode* tmp = new TreeNode(v);  //建立新结点并赋值
     queue<TreeNode*> qt;  //层序遍历用的队列
     TreeNode* f = p;
         if (!p) {  //若根结点为空则直接赋值并返回
             p = tmp;
             cout << p->val << " ";
             return p;
         }
         else {   //若根结点不为空则入队
             qt.push(p);
             while (!qt.empty()) {  //当队伍不为空时循环
                 f = qt.front();  //对队头结点的左孩子和右孩子进行判断
                 qt.pop();
                 if (f->left) qt.push(f->left);  //左孩子和右孩子非空时入队,为空时则直接赋值退出循环
                 else if (!f->left) {
                     f->left = tmp; 
                     cout << f->left->val << " ";
                     break;
                 }
                 if(f->right) qt.push(f->right);
                 else
                 {
                     f->right = tmp;
                     cout << f->right->val << " ";
                     break;
                 }
             }
             return p;  //返回
         }
 }

非递归先序遍历
//遍历树时一般基于当前结点,对于先序遍历,若当前结点存在则访问,并指向它的左孩子;若当前结点不存在,弹出一个结点,并指向该结点的右孩子。

void PreOrder(TreeNode* node) {  //先序遍历
     stack<TreeNode*> s;
     TreeNode* p = node;
     while (p || !s.empty()) {  
         if (p) {
             cout << p->val<<" ";  
             s.push(p);
             p = p->left;
         }
         else{
             p = s.top();
             s.pop();
             p = p->right;
         }
     }
 }

非递归中序遍历

void InOrder(TreeNode* node) { //中序遍历
     stack<TreeNode*> s;
     TreeNode* p=node;
     while (p || !s.empty()) {
         if (p) {
             s.push(p);
             p = p->left;
         }
         else {
             p = s.top();
             s.pop();
             cout << p->val << " ";
             p = p->right;
         }
     }
 }

主函数如下:

int main() {
    TreeNode* node=NULL;

   for (int i = 0; i < 9; i++) {
        node=LevelOrder(node,i);  //层序遍历
    }

    PreOrder(node);  //先序遍历
    InOrder(node);  //中序遍历
    return 0;
}

后序遍历
以查找某结点的所有祖先为例

 struct myStack {  //后序遍历需要记录该结点的右子树是否访问过,因此自建一个栈;
     TreeNode* t;
     int tag;  //为1时表示右子树已经访问过了,此时可以出栈
 };

 void postOrder(TreeNode* node, int v) {
     myStack *s = new myStack[9];  //定义一个足够大的栈内存
     int top = 0;
     while (node || top > 0) {    //当结点非空或栈非空时循环
         while (node&&node->val!=v) {  //结点存在并且不是v时则沿着左子树入栈
             s[++top] = { node ,0};
             node = node->left;
         }
         if (node && node->val == v) {  //结点为v时,栈中所有元素为该结点的祖先结点;
             cout << "v的所有祖先:";
             for(int i=1;i<top;i++){  
                 cout << s[i].t->val << " ";
             }
             cout << endl;
             return;
         }
         //栈非空且栈顶tag为1时出栈,这里为1说明刚刚被访问过右子树,即可出栈(因为在入栈
         //的时候已经访问过(非v)了,所以无需再访问,直接出栈)
         while (top > 0 || s[top].tag == 1) {  
             top--;
         }
         if (top > 0) {
             s[top].tag = 1;
             node = s->t->right;
         }
     }
 }
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-08-15 15:50:18  更:2021-08-15 15:53:11 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/28 17:03:24-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计