【408考点之数据结构】二叉树的遍历及线索二叉树

二叉树的遍历及线索二叉树

一、二叉树的遍历

二叉树的遍历是指按照一定的顺序访问二叉树中所有节点。常见的遍历方法有前序遍历(Preorder Traversal)、中序遍历(Inorder Traversal)、后序遍历(Postorder Traversal)和层次遍历(Level Order Traversal)。

  1. 前序遍历(Preorder Traversal)

    • 过程:访问根节点 -> 前序遍历左子树 -> 前序遍历右子树
    • 代码实现
    c 复制代码
    void preorderTraversal(TreeNode *root) {
        if (root) {
            printf("%d ", root->data);
            preorderTraversal(root->left);
            preorderTraversal(root->right);
        }
    }
  2. 中序遍历(Inorder Traversal)

    • 过程:中序遍历左子树 -> 访问根节点 -> 中序遍历右子树
    • 代码实现
    c 复制代码
    void inorderTraversal(TreeNode *root) {
        if (root) {
            inorderTraversal(root->left);
            printf("%d ", root->data);
            inorderTraversal(root->right);
        }
    }
  3. 后序遍历(Postorder Traversal)

    • 过程:后序遍历左子树 -> 后序遍历右子树 -> 访问根节点
    • 代码实现
    c 复制代码
    void postorderTraversal(TreeNode *root) {
        if (root) {
            postorderTraversal(root->left);
            postorderTraversal(root->right);
            printf("%d ", root->data);
        }
    }
  4. 层次遍历(Level Order Traversal)

    • 过程:按照层次从上到下、从左到右依次访问各节点
    • 代码实现
    c 复制代码
    #include <stdio.h>
    #include <stdlib.h>
    #define MAX_QUEUE_SIZE 100
    
    typedef struct TreeNode {
        int data;
        struct TreeNode *left;
        struct TreeNode *right;
    } TreeNode;
    
    typedef struct {
        TreeNode *data[MAX_QUEUE_SIZE];
        int front;
        int rear;
    } Queue;
    
    void initQueue(Queue *q) {
        q->front = q->rear = 0;
    }
    
    int isQueueEmpty(Queue *q) {
        return q->front == q->rear;
    }
    
    void enqueue(Queue *q, TreeNode *node) {
        if ((q->rear + 1) % MAX_QUEUE_SIZE == q->front) {
            printf("Queue is full\n");
            return;
        }
        q->data[q->rear] = node;
        q->rear = (q->rear + 1) % MAX_QUEUE_SIZE;
    }
    
    TreeNode* dequeue(Queue *q) {
        if (isQueueEmpty(q)) {
            printf("Queue is empty\n");
            return NULL;
        }
        TreeNode *node = q->data[q->front];
        q->front = (q->front + 1) % MAX_QUEUE_SIZE;
        return node;
    }
    
    void levelOrderTraversal(TreeNode *root) {
        if (!root) return;
        Queue q;
        initQueue(&q);
        enqueue(&q, root);
        while (!isQueueEmpty(&q)) {
            TreeNode *node = dequeue(&q);
            printf("%d ", node->data);
            if (node->left) enqueue(&q, node->left);
            if (node->right) enqueue(&q, node->right);
        }
    }
二、线索二叉树

线索二叉树是一种特殊的二叉树,通过对空指针加以利用,使得二叉树的遍历更加高效。在线索二叉树中,每个节点的空指针指向在某种遍历方式下的前驱或后继节点。

  1. 线索的定义

    • 前驱(Predecessor):在某种遍历方式下,当前节点的前一个节点。
    • 后继(Successor):在某种遍历方式下,当前节点的后一个节点。
  2. 线索二叉树的类型

    • 前序线索二叉树(Preorder Threaded Binary Tree):前序遍历下的前驱和后继。
    • 中序线索二叉树(Inorder Threaded Binary Tree):中序遍历下的前驱和后继。
    • 后序线索二叉树(Postorder Threaded Binary Tree):后序遍历下的前驱和后继。
  3. 线索二叉树的结构定义

    c 复制代码
    typedef struct ThreadedTreeNode {
        int data;
        struct ThreadedTreeNode *left;
        struct ThreadedTreeNode *right;
        int ltag; // 0: left指向左孩子, 1: left指向前驱
        int rtag; // 0: right指向右孩子, 1: right指向后继
    } ThreadedTreeNode;
  4. 中序线索二叉树的建立

    c 复制代码
    void createInorderThread(ThreadedTreeNode *root, ThreadedTreeNode **pre) {
        if (root) {
            createInorderThread(root->left, pre);
            if (!root->left) {
                root->left = *pre;
                root->ltag = 1;
            }
            if (*pre && !(*pre)->right) {
                (*pre)->right = root;
                (*pre)->rtag = 1;
            }
            *pre = root;
            createInorderThread(root->right, pre);
        }
    }
    
    void createInorderThreadTree(ThreadedTreeNode *root) {
        ThreadedTreeNode *pre = NULL;
        if (root) {
            createInorderThread(root, &pre);
            if (pre->right == NULL) {
                pre->rtag = 1;
            }
        }
    }
  5. 中序线索二叉树的遍历

    c 复制代码
    void inorderThreadedTraversal(ThreadedTreeNode *root) {
        ThreadedTreeNode *p = root;
        while (p) {
            while (p->ltag == 0) {
                p = p->left;
            }
            printf("%d ", p->data);
            while (p->rtag == 1 && p->right != NULL) {
                p = p->right;
                printf("%d ", p->data);
            }
            p = p->right;
        }
    }

使用场景

  1. 表达式树的构建和求值:通过中序遍历和后序遍历,可以有效地对表达式进行解析和求值。
  2. 数据库查询优化:使用线索二叉树可以加快查询速度,减少查询时间。
  3. 文件系统管理:层次遍历用于文件系统目录的遍历,便于管理和查找文件。
  4. 数据压缩与编码:霍夫曼树利用二叉树结构实现高效的编码和解码。
相关推荐
a1879272183138 分钟前
【算法】动态规划第四篇:背包收官——min 哨兵、计数世界与组合排列分水岭
算法·leetcode·动态规划·dp·01背包·算法讲解·决策合并
2601_962297481 小时前
在python3中、下列输出变量a的正确写法是_2020超星大数据Python免费答案
数据结构·python·算法·编程·字符串操作
辰烨chenye1 小时前
LeetCode Hot 100 题解 · 子串篇
算法·leetcode·职场和发展
辰烨chenye1 小时前
LeetCode Hot 100 题解 · 堆篇
java·算法·leetcode
手写码匠1 小时前
华为云Flexus+DeepSeek征文|DeepSeek 应用监控告警体系实战:从“用户投诉才知道“到“故障前就发现“
人工智能·深度学习·算法·aigc
shehuiyuelaiyuehao2 小时前
算法29,前缀和,除自身以外的数组的乘积
java·数据结构·算法
智购科技自动售货机厂家2 小时前
2026自动售货机设备清洁效果自动验证:从图像比对到评分算法的工程实践~YH
人工智能·算法·计算机视觉
姜穆澜3 小时前
机器学习实战指南:从算法原理到工程落地
人工智能·算法·机器学习
啵啵啵鱼3 小时前
DS-顺序表
java·数据结构·笔记·后端·链表·obsidian