• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C语言 > 一波C语言二元查找树算法题目解答实例汇总

一波C语言二元查找树算法题目解答实例汇总

作者:wuzhekai1985 字体:[增加 减小] 来源:互联网 时间:2017-05-28

wuzhekai1985 通过本文主要向大家介绍了二元查找树,二元查找,二元一次方程知识树,二元搜索树,阔叶树二元材积表等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

按层次遍历二元树
问题描述:输入一颗二元树,从上往下按层打印树的每个结点,同一层中按照从左往右的顺序打印。 
例如输入:

 8
 / /
 6 10
/ / / /
5 7 9 11
</div>

输出

8 6 10 5 7 9 11
</div>

          定义二元树(其实是二元搜索树,但并不遍历算法)的结点为:

struct BSTreeNode 
{ 
 int value; 
 BSTreeNode *left; 
 BSTreeNode *right; 
}; 
</div>

      思路:利用队列的先进先出,很容易实现。每次取出队列的首元素,然后将其左右子女放入队列中。直至队列为空即可。按这种方式进出队列,正好是按层遍历二元树。
      参考代码:

//函数功能 : 按层次遍历二元树 
//函数参数 : pRoot指向根结点 
//返回值 : 无 
void LevelReverse(BSTreeNode *pRoot) 
{ 
 if(pRoot == NULL) 
  return; 
 
 queue<BSTreeNode *> nodeQueue; 
 nodeQueue.push(pRoot); 
 while(nodeQueue.size()) 
 { 
  BSTreeNode * pNode = nodeQueue.front(); //取队首元素 
  nodeQueue.pop(); //必须出队列 
  if(pNode->left) //左子女 
   nodeQueue.push(pNode->left); 
  if(pNode->right) //右子女 
   nodeQueue.push(pNode->right); 
 
  cout<<pNode->value<<' '; 
 } 
} 
</div>

       扩展一:上文给出的代码,所有结点都输出在同一行。如果希望仅仅同层结点输出在同一行,该如何修改代码呢?
       思路:如果我们能知道每层的最后一个结点,那么就方便多了,输出每层最后一个结点的同时,输出一个换行符。因此,关键在于如何标记每层的结束。可以考虑在每层的最后一个点之后,插入一个空结点。比如队列中先放入根结点,由于第0层只有一个结点,因此放入一个空结点。然后依次取出队列中的结点,将其子女放入队列中,如果遇到空结点,表明当前层的结点已遍历完了,而队列中放的恰恰是下一层的所有结点。如果当前队列为空,表明下一层无结点,也就说是所有结点已遍历好了。如果不为空,那么插入一个空结点,用于标记下一层的结束。
      参考代码:

void LevelReverse(BSTreeNode *pRoot) 
{ 
 if(pRoot == NULL) 
  return; 
 queue<BSTreeNode *> nodeQueue; 
 nodeQueue.push(pRoot); 
 nodeQueue.push(NULL); //放入空结点,作为层的结束符 
 while(nodeQueue.size()) 
 { 
  BSTreeNode * pNode = nodeQueue.front(); //取队首元素 
  nodeQueue.pop(); //必须出队列 
  if(pNode) 
  { 
   if(pNode->left) //左子女 
    nodeQueue.push(pNode->left); 
   if(pNode->right) //右子女 
    nodeQueue.push(pNode->right); 
   cout<<pNode->value<<' '; 
  } 
  else if(nodeQueue.size()) //如果结点为空并且队列也为空,那么所有结点都已访问 
  { 
   nodeQueue.push(NULL); 
   cout<<endl; 
  } 
 } 
} 

</div>

       扩展二:之前讨论的都是从上往下、从左往右遍历二叉树,那么如果希望自下往上、从左右往右遍历二叉树,该如何修改代码呢?
       思路:比较简单的方法,首先遍历二叉树,将所有结点保存在一个数组中,遍历的同时记录每一层在数组中的起止位置。然后根据起止位置,就可以自下往上的打印二叉树的结点。

//每层的起止位置 
struct Pos 
{ 
 int begin; 
 int end; 
 Pos(int b, int e): begin(b),end(e) {} 
}; 
void LevelReverse(BSTreeNode *pRoot) 
{ 
 if(pRoot == NULL) 
  return; 
 
 vector<BSTreeNode*> vec; //用以存放所有结点 
 vector<Pos> pos;   //用以记录每层的起止位置 
 vec.push_back(pRoot); 
 
 int level = 0; //树的层数 
 int cur = 0; 
 int last = 1; 
 
 while(cur < vec.size()) 
 { 
  last = vec.size(); 
  pos.push_back(Pos(cur, last)); //记录当前层的起止位置 
 
  while(cur < last) //遍历当前层的结点,将子女放入数组中 
  { 
   if(vec[cur]->left) //先是左然后是右。如果希望自由向左,交换一下顺序即可 
    vec.push_back(vec[cur]->left); 
   if(vec[cur]->right) 
    vec.push_back(vec[cur]->right); 
   cur++; 
  } 
  level++; //层数加1 
 } 
 
 for(int i = level - 1; i >= 0; i--) //自下往上遍历 
 { 
  for(int j = pos[i].begin; j < pos[i].end; j++) 
   cout<<vec[j]->value<<' '; 
  cout<<endl; 
 } 
} 
</div>

输入一颗二元查找树,将该树转换为它的镜像
  问题描述:输入一颗二元查找树,将该树转换为它的镜像,即在转换后的二元查找树中,左子树的结点都大于右子树的结点。用递归和循环两种方法完成树的镜像转换。 
        例如输入:

 8
 / /
 6 10
 // //
5 7 9 11
</div>

输出:

 8
 / /
 10 6
 // //
11 9 7 5
</div>

      定义二元查找树的结点为:

struct BSTreeNode 
{ 
 int value; 
 BSTreeNode *left; 
 BSTreeNode *right; 
}; 
</div>

      思路:题目要求用两种方法,递归和循环,其实质是一样的。
      解法一:用递归。假设当前结点为pNode,只需交换该结点的左右子女,然后分别递归求解左子树和右子树即可。代码极为简单。
      解法二:用循环,需要一个辅助栈完成,每次取栈顶元素交换左右子女,然后将左右子女分别压入辅助栈,当栈中元素为空时,结束循环。其实不论是递归也好,循环也好,都是利用栈的特性完成。
      参考代码:

//函数功能 : 输入一颗二元查找树,将该树转换为它的镜像 
//函数参数 : pRoot为根结点 
//返回值 : 根结点 
BSTreeNode * Mirror_Solution1(BSTreeNode * pRoot) 
{ 
 if(pRoot != NULL) 
 { 
  BSTreeNode * pRight = pRoot->right; 
  BSTreeNode * pLeft = pRoot->left; 
  pRoot->left = Mirror_Solution1(pRight); //转化右子树 
  pRoot->right = Mirror_Solution1(pLeft); //转化左子树 
 } 
 return pRoot; 
} 
BSTreeNode * Mirror_Solution2(BSTreeNode * pRoot) 
{ 
 if(pRoot != NULL) 
 { 
  stack<BSTreeNode *> stk; //辅助栈 
  stk.push(pRoot);   //压入根结点 
  while(stk.size()) 
  { 
   BSTreeNode *pNode = stk.top(); 
   BSTreeNode *pLeft = pNode->left; 
   BSTreeNode* pRight = pNode->right; 
   stk.pop(); 
 
   if(pLeft != NULL) 
    stk.push(pLeft); 
   if(pRight != NULL) 
    stk.push(pRight); 
   pNode->left = pRight; //交换左右子女 
   pNode->right = pLeft; 
  } 
 } 
 return pRoot; 
} 
</div>

判断整数序列是不是二元查找树的后序遍历结果
问题描述:输入一个整数数组,判断该数组是不是某二元查找树的后序遍历的结果。如果是返回true,否则返回false。
例如输入5、7、6、9、11、10、8,由于这一整数序列是如下树的后序遍历结果:

   8
  / /
  6 10
 / / / /
 5 7 9 11
</div>

因此返回true。如果输入7、4、6、5,没有哪棵树的后序遍历的结果是这个序列,因此返回false。
         思路:分析后序遍历的特点,序列的最后一个数应该是根结点,剩余的节点分为两个连续的子序列,前一子序列的值小于最后一个数,后一子序列的值大于最后一个数。然后递归求解这两个子序列。
         如果是判断是前序遍历也很简单,只不过根节点变为了第一个数,剩余的节点也是分为两个连续的子序列。如果判断是中序遍历,更方便,只需扫描一遍,检查序列是不是排好序的,如果没有排好序,就不是中序遍历的结果。


把二元查找树转变成排序的双向链表
    问题描述:输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。要求不能创建任何

分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • 一波C语言二元查找树算法题目解答实例汇总
  • C语言实现输入一颗二元查找树并将该树转换为它的镜像
  • 判断整数序列是否为二元查找树的后序遍历结果的解决方法

相关文章

  • 2017-05-28使用root权限运行自己所编译程序的解决方法
  • 2017-05-28c++非变易算法-stl算法
  • 2017-05-28c++基础语法:普通继承
  • 2017-05-28C/C++函数调用的几种方式总结
  • 2017-05-28c++图像处理:24位真彩图颜色变换实例
  • 2017-05-28将字符串str1复制为字符串str2的三种解决方法
  • 2017-05-28C++ 中的Lambda表达式写法
  • 2017-05-28输出1000以内的素数的算法(实例代码)
  • 2017-05-28wchar_t,char,string,wstring之间的相互转换
  • 2017-05-28进程间通信之深入消息队列的详解

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • C语言循环结构与时间函数用法实例教程
    • c语言实现的带通配符匹配算法
    • 解析C++中虚析构函数的作用
    • 分析C语言一个简单程序
    • 利用C/C++二进制读写png文件的方法示例
    • C语言基础 原码、反码、补码和移码详解
    • C语言将数组中元素的数排序输出的相关问题解决
    • C++中的三大函数和操作符重载(Boolan)
    • C++实现大数乘法算法代码
    • C语言实现两个递减数列中寻找某一个数

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有