C语言 数据结构之中序二叉树实例详解

发布时间 - 2026-01-10 22:31:12    点击率:

C语言数据结构 中序二叉树

前言:

线索二叉树主要是为了解决查找结点的线性前驱与后继不方便的难题。它只增加了两个标志性域,就可以充分利用没有左或右孩子的结点的左右孩子的存储空间来存放该结点的线性前驱结点与线性后继结点。两个标志性域所占用的空间是极少的,所有充分利用了二叉链表中空闲存的储空间。

   要实现线索二叉树,就必须定义二叉链表结点数据结构如下(定义请看代码):

left

leftTag

data

rightTag

right

说明:

1.       leftTag=false时,表示left指向该结点的左孩子;

2.       leftTag=true时,表示left指向该结点的线性前驱结点;

3.       rightTag=false时,表示right指向该结点的右孩子;

4.       rightTag=true时,表示right指向该结点的线性后继结点;

     以二叉链表结点数据结构所构成的二叉链表作为二叉树的存储结构,叫做线索二叉链表;指向结点的线性前驱或者线性后继结点的指针叫做线索;加上线索的二叉树称为线索二叉树;对二叉树以某种次序遍历将其变为线索二叉树的过程叫做线索化。

中序次序线索化二叉树算法:

  中序次序线索化是指用二叉链表结点数据结构建立二叉树的二叉链表,然后按照中序遍历的方法访问结点时建立线索;(具体看代码)

检索中序二叉树某结点的线性前驱结点的算法:

1.       如果该结点的leftTag=true,那么left就是它的线性前驱;

2.       如果该结点的leftTag=false,那么该结点左子树最右边的尾结点就是它的线性前驱点;

(具体请看代码)

检索中序二叉树某结点的线性后继结点和算法:

1.       如果该结点的right=true,那么right就是它的线性后继结点;

2.       如果该结点的right=false,那么该结点右子树最左边的尾结点就是它的线性后继结点

(具体请看代码)


图:后继线索


图:前驱线索

 节点定义:

struct Node 
{ 
  int data; 
  bool leftTag; 
  bool rightTag; 
  Node* left; 
  Node* right; 
  Node(int _data):data(_data),left(0),right(0),leftTag(false),rightTag(false){} 
}; 

类定义:

class BinaryTree 
{ 
private: 
  Node* root; 
private: 
  Node* head; 
  Node* pre; 
  void makeThread(Node* node); 
public: 
  void buildThread(); 
  void traverseBySuccessor(); 
  void traverseByPredecessor(); 
 
// helper methods 
private: 
  static inline bool visit(Node* T) 
  { 
    if (T) 
    { 
      printf("data:%c, left:%c, right:%c\n", 
        (char)T->data, 
        (T->left!=0) ? (char)T->left->data : '#', 
        (T->right!=0) ? (char)T->right->data : '#'); 
      return true; 
    } 
    else return false; 
  } 
}; 

方法定义:

void BinaryTree::makeThread(Node* node) 
{ 
  if (node!=NULL) 
  { 
    makeThread(node->left); 
    if (pre!= NULL) 
    { 
      if (pre->right==NULL) // 如果前驱节点的右子树为空, 那么把前驱节点的右子树用作线索 
      { 
        pre->rightTag = true;  
        pre->right = node; 
      } 
      else pre->rightTag = false; 
    } 
    if (node->left==NULL) // 如果当前结点的左子树为空, 那么把当前结点的左子树用作线索 
    { 
      node->leftTag = true; 
      node->left = pre; 
    } 
    else node->leftTag = false; 
    pre = node; 
    makeThread(node->right); 
  } 
} 
 
void BinaryTree::traverseBySuccessor() 
{ 
  Node* p = head->left; //first find the root node 
  // 亲测表明 如果不使用head哑节点 就要设三道卡, 防止p访问到NULL,  
  // 分别在主while处, 第二个visit处和下面的p=p->right处 
  while (p!=head) 
  { 
    while (!p->leftTag) 
      p = p->left; 
    visit(p); 
 
    while (p->rightTag && p->right!=head) 
    { 
      p = p->right; 
      visit(p); 
    } 
    p = p->right; 
  } 
  cout<<endl; 
} 
 
void BinaryTree::traverseByPredecessor() 
{ 
  Node* p = head->left; //first find the root node 
  while (p!=head) 
  { 
    while (!p->rightTag) 
      p = p->right; 
    visit(p); 
    if (p!=NULL) 
    { 
      while (p->leftTag && p->left!=head) 
      { 
        p = p->left; 
        visit(p); 
      } 
      p = p->left; 
    } 
  } 
  cout<<endl; 
} 
 
void BinaryTree::buildThread() 
{ 
  pre = NULL; 
  head = new Node('@'); 
  head->left = root; 
  head->right = head; 
  makeThread(root); 
  // 经过了makeThread过程之后, pre必然指向中序遍历最晚的结点. 
  // 把pre的右子树指向head, 就构成了一个双向循环链表 
  // 
  pre->rightTag = 1; 
  pre->right = head; 
  pre = NULL; 
  Node* p = root; 
  /* 
   * 在建立前驱线索的时候,最左边的结点没有和head结点连接。要在这里补上 
   */ 
  while (p->left!=NULL) 
    p = p->left; 
  p->left = head; 
} 

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!


# C语言数据结构  # 中序二叉树  # C语言  # 中序二叉树简单实例  # C  # C语言数据结构二叉树先序、中序、后序及层次四种遍历  # C语言数据结构之二分法查找详解  # 详解C语言数据结构之栈  # C语言数据结构之平衡二叉树(AVL树)实现方法示例  # C语言数据结构之二叉链表创建二叉树  # 子树  # 二叉树  # 链表  # 数据结构  # 遍历  # 充分利用  # 为空  # 是指  # 将其  # 要在  # 希望能  # 第二个  # 谢谢大家  # 极少  # 补上  # 它只  # 三道  # 就可以  # 最晚  # 增加了 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Laravel如何部署到服务器_线上部署Laravel项目的完整流程与步骤  如何有效防御Web建站篡改攻击?  详解MySQL数据库的安装与密码配置  历史网站制作软件,华为如何找回被删除的网站?  Laravel如何安装Breeze扩展包_Laravel用户注册登录功能快速实现【流程】  怎样使用JSON进行数据交换_它有什么限制  如何在阿里云域名上完成建站全流程?  php8.4header发送头信息失败怎么办_php8.4header函数问题解决【解答】  Laravel如何使用Eloquent ORM进行数据库操作?(CRUD示例)  魔方云NAT建站如何实现端口转发?  php做exe能调用系统命令吗_执行cmd指令实现方式【详解】  惠州网站建设制作推广,惠州市华视达文化传媒有限公司怎么样?  PHP正则匹配日期和时间(时间戳转换)的实例代码  PythonWeb开发入门教程_Flask快速构建Web应用  zabbix利用python脚本发送报警邮件的方法  Laravel如何实现本地化和多语言支持?(i18n教程)  大型企业网站制作流程,做网站需要注册公司吗?  Laravel数据库迁移怎么用_Laravel Migration管理数据库结构的正确姿势  北京的网站制作公司有哪些,哪个视频网站最好?  Laravel怎么实现微信登录_Laravel Socialite第三方登录集成  Laravel如何使用Passport实现OAuth2?(完整配置步骤)  Laravel如何生成PDF或Excel文件_Laravel文档导出工具与使用教程  Python文本处理实践_日志清洗解析【指导】  Laravel distinct去重查询_Laravel Eloquent去重方法  WEB开发之注册页面验证码倒计时代码的实现  香港服务器网站搭建教程-电商部署、配置优化与安全稳定指南  什么是javascript作用域_全局和局部作用域有什么区别?  如何在建站之星网店版论坛获取技术支持?  详解Nginx + Tomcat 反向代理 如何在高效的在一台服务器部署多个站点  JavaScript 输出显示内容(document.write、alert、innerHTML、console.log)  网站图片在线制作软件,怎么在图片上做链接?  宙斯浏览器视频悬浮窗怎么开启 边看视频边操作其他应用教程  常州企业网站制作公司,全国继续教育网怎么登录?  Laravel Admin后台管理框架推荐_Laravel快速开发后台工具  php中::能调用final静态方法吗_final修饰静态方法调用规则【解答】  Laravel如何实现全文搜索_Laravel Scout集成Algolia或Meilisearch教程  Laravel如何使用.env文件管理环境变量?(最佳实践)  专业商城网站制作公司有哪些,pi商城官网是哪个?  开心动漫网站制作软件下载,十分开心动画为何停播?  Laravel如何使用Collections进行数据处理?(实用方法示例)  Laravel如何处理异常和错误?(Handler示例)  如何确认建站备案号应放置的具体位置?  详解Android——蓝牙技术 带你实现终端间数据传输  Laravel怎么写单元测试_PHPUnit在Laravel项目中的基础测试入门  Laravel如何使用Blade组件和插槽?(Component代码示例)  如何在万网ECS上快速搭建专属网站?  ai格式如何转html_将AI设计稿转换为HTML页面流程【页面】  Laravel如何处理文件下载请求?(Response示例)  香港服务器如何优化才能显著提升网站加载速度?  ,网页ppt怎么弄成自己的ppt?