c++树及树与二叉树的转换
此算法中的树结构为“左儿子有兄弟链接结构”
在这样的一个二叉树中,一个节点的左分支是他的大儿子节点,右分支为他的大兄弟节点。
这里讲的树有递归前根,中根,后根遍历,插入节点,插入兄弟节点,查找结点,释放内存这些功能。
重点说一下查找节点这一算法:
pSTreeNode CTree::Search( pSTreeNode pNode, TreeDataType Value )
{
if ( pNode == NULL )
return NULL;
if ( pNode->data == Value )
return pNode;
if ( pNode->pFirstChild == NULL && pNode->pNextBrother == NULL )
return NULL;
else
{
if ( pNode->pFirstChild != NULL ) //首先判断根节点的左儿子节点是否为空,若不为空,通过引入指针来寻找节点
{
pSTreeNode pNodeTemp = Search( pNode->pFirstChild, Value );
if ( pNodeTemp != NULL )
return pNodeTemp;
else
{
return Search( pNode->pNextBrother, Value );
}
}
else //否则在根节点的右兄弟节点中寻找
return Search( pNode->pNextBrother, Value );
}
}
完整代码如下:
#include <iostream>
using namespace std;
typedef struct STreeNode* pSTreeNode;
typedef int TreeDataType;
//定义结构体
struct STreeNode
{
TreeDataType data;
pSTreeNode pFirstChild;
pSTreeNode pNextBrother;
//结构体构造函数
STreeNode( TreeDataType Value )
{
data = Value;
pFirstChild = NULL;
pNextBrother = NULL;
}
};
//定义类
class CTree
{
public:
CTree();
CTree( TreeDataType Value );
~CTree();
public:
void Insert( TreeDataType parentValue, TreeDataType Value ); // parentValue:该点的父亲节点;Value:该点的值
void InsertBrother( pSTreeNode pParentNode, TreeDataType Value );
pSTreeNode Search( pSTreeNode pNode, TreeDataType Value );
void Preorder( pSTreeNode pNode ); // 前序遍历
void Inorder( pSTreeNode pNode ); // 中序遍历
void postorder( pSTreeNode pNode ); // 后序遍历
void FreeMemory( pSTreeNode pNode ); // 释放内存
public:
pSTreeNode pRoot;
};
//构造函数
CTree::CTree()
{
pRoot = NULL;
}
//构造函数
CTree::CTree( TreeDataType Value )
{
pRoot = new STreeNode( Value );
}
//析构函数
CTree::~CTree()
{
if (pRoot == NULL )
return;
FreeMemory( pRoot );
}
//释放内存
void CTree::FreeMemory( pSTreeNode pNode )
{
if ( pNode == NULL )
return;
if ( pNode->pFirstChild != NULL )
FreeMemory( pNode->pFirstChild );
if ( pNode->pNextBrother != NULL )
FreeMemory( pNode->pNextBrother );
delete pNode;
pNode = NULL;
}
//插入节点
void CTree::Insert( TreeDataType parentValue, TreeDataType Value )
{
if ( pRoot == NULL )
return;
pSTreeNode pFindNode = Search( pRoot, parentValue );
if ( pFindNode == NULL )
return;
if ( pFindNode->pFirstChild == NULL )
{
pFindNode->pFirstChild = new STreeNode( Value );
return;
}
else
{
InsertBrother( pFindNode->pFirstChild, Value );
return;
}
}
//插入右兄弟节点
void CTree::InsertBrother( pSTreeNode pBrotherNode, TreeDataType Value )
{
if ( pBrotherNode->pNextBrother != NULL )
InsertBrother( pBrotherNode->pNextBrother, Value );
else
{
pBrotherNode->pNextBrother = new STreeNode( Value );
return;
}
}
//查找函数
pSTreeNode CTree::Search( pSTreeNode pNode, TreeDataType Value )
{
if ( pNode == NULL )
return NULL;
if ( pNode->data == Value )
return pNode;
if ( pNode->pFirstChild == NULL && pNode->pNextBrother == NULL )
return NULL;
else
{
if ( pNode->pFirstChild != NULL )
{
pSTreeNode pNodeTemp = Search( pNode->pFirstChild, Value );
if ( pNodeTemp != NULL )
return pNodeTemp;
else
{
return Search( pNode->pNextBrother, Value );
}
}
else
return Search( pNode->pNextBrother, Value );
}
}
//前序遍历
void CTree::Preorder( pSTreeNode pNode )
{
if (pNode == NULL)
return;
cout << " " << pNode->data << " ";
Preorder( pNode->pFirstChild );
Preorder( pNode->pNextBrother );
}
//中序遍历
void CTree::Inorder( pSTreeNode pNode )
{
if ( pNode == NULL )
return;
Inorder( pNode->pFirstChild );
cout << " " << pNode->data << " ";
Inorder( pNode->pNextBrother );
}
//后序遍历
void CTree::postorder( pSTreeNode pNode )
{
if ( pNode == NULL )
return;
postorder( pNode->pFirstChild );
postorder( pNode->pNextBrother );
cout << " " << pNode->data << " ";
}
//主函数
int main()
{
CTree* pTree = new CTree( 1 );
pTree->Insert( 1, 2 );
pTree->Insert( 1, 3 );
pTree->Insert( 1, 4 );
pTree->Insert( 1, 5 );
pTree->Insert( 1, 6 );
pTree->Insert( 1, 7 );
pTree->Insert( 4, 8 );
pTree->Insert( 5, 9 );
pTree->Insert( 5, 10 );
pTree->Insert( 6, 11 );
pTree->Insert( 6, 12 );
pTree->Insert( 6, 13 );
pTree->Insert( 10, 14 );
pTree->Insert( 10, 15 );
cout << "前序遍历:" << endl;
pTree->Preorder( pTree->pRoot );
cout << endl;
cout << "中序遍历:" << endl;
pTree->Inorder( pTree->pRoot );
cout << endl;
cout << "后序遍历:" << endl;
pTree->postorder( pTree->pRoot );
cout << endl;
delete pTree;
pTree = NULL;
return 0;
}
c++树及树与二叉树的转换的更多相关文章
- 哈夫曼树【最优二叉树】【Huffman】
[转载]只为让价值共享,如有侵权敬请见谅! 一.哈夫曼树的概念和定义 什么是哈夫曼树? 让我们先举一个例子. 判定树: 在很多问题的处理过程中,需要进行大量的条件判断,这些判断结构的设 ...
- 树(二叉树 & 二叉搜索树 & 哈夫曼树 & 字典树)
树:n(n>=0)个节点的有限集.有且只有一个root,子树的个数没有限制但互不相交.结点拥有的子树个数就是该结点的度(Degree).度为0的是叶结点,除根结点和叶结点,其他的是内部结点.结点 ...
- Atitit 常见的树形结构 红黑树 二叉树 B树 B+树 Trie树 attilax理解与总结
Atitit 常见的树形结构 红黑树 二叉树 B树 B+树 Trie树 attilax理解与总结 1.1. 树形结构-- 一对多的关系1 1.2. 树的相关术语: 1 1.3. 常见的树形结构 ...
- 以AVL树为例理解二叉树的旋转(Rotate)操作
树旋转是在二叉树中的一种子树调整操作, 每一次旋转并不影响对该二叉树进行中序遍历的结果. 树旋转通常应用于需要调整树的局部平衡性的场合. 树旋转包括两个不同的方式, 分别是左旋转和右旋转. 两种旋转呈 ...
- 数据结构(一)二叉树 & avl树 & 红黑树 & B-树 & B+树 & B*树 & R树
参考文档: avl树:http://lib.csdn.net/article/datastructure/9204 avl树:http://blog.csdn.net/javazejian/artic ...
- C# 表达式树 创建、生成、使用、lambda转成表达式树~表达式树的知识详解
笔者最近学了表达式树这一部分内容,为了加深理解,写文章巩固知识,如有错误,请评论指出~ 表达式树的概念 表达式树的创建有 Lambda法 和 组装法. 学习表达式树需要 委托.Lambda.Func& ...
- php数据结构课程---5、树(树的 存储方式 有哪些)
php数据结构课程---5.树(树的 存储方式 有哪些) 一.总结 一句话总结: 双亲表示法:data parent:$tree[1] = ["B",0]; 孩子表示法:data ...
- 字符串 --- KMP Eentend-Kmp 自动机 trie图 trie树 后缀树 后缀数组
涉及到字符串的问题,无外乎这样一些算法和数据结构:自动机 KMP算法 Extend-KMP 后缀树 后缀数组 trie树 trie图及其应用.当然这些都是比较高级的数据结构和算法,而这里面最常用和最熟 ...
- 【查找结构5】多路查找树/B~树/B+树
在前面专题中讲的BST.AVL.RBT都是典型的二叉查找树结构,其查找的时间复杂度与树高相关.那么降低树高自然对查找效率是有所帮助的.另外还有一个比较实际的问题:就是大量数据存储中,实现查询这样一个实 ...
- 【Todo】字符串相关的各种算法,以及用到的各种数据结构,包括前缀树后缀树等各种树
另开一文分析字符串相关的各种算法,以及用到的各种数据结构,包括前缀树后缀树等各种树. 先来一个汇总, 算法: 本文中提到的字符串匹配算法有:KMP, BM, Horspool, Sunday, BF, ...
随机推荐
- 更改placeholder样式
/*不要将选择器进行组合*/ /* IE 10-11 */ :-ms-input-placeholder { color: #aaa; } /* webkit */ ::-webkit-input-p ...
- 微软高性能缓存AppFabric (一) 安装
博客原文链接:http://www.cnblogs.com/Qbit/p/6088703.html AppFabric 缓存功能的前身是VeloCity ,它是基于windows平台的一个高速内存缓存 ...
- 页面中插入视频兼容ie8以上的浏览器
有时候页面中需要插入视频,如果不考虑ie8的话:就是直接用h5标签<video></video>就可以了: 但是有的时候需求是需要考虑ie8,这样我们就可以用插件,这种vide ...
- java Vamei快速教程19 嵌套类
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 到现在为止,我们都是在Java文件中直接定义类.这样的类出现在包(package) ...
- 【挖坑】2019年JAVA安全总结:SQL注入——新项目的开发与老项目的修复
如何在项目中有效的防止SQL注入 写给需要的人,所有的问题源自我们的不重视. 本章略过"什么是SQL注入","如何去利用SQL注入"的讲解,仅讲如何去防御 PS ...
- IOS 移除栈顶的控制器
- (IBAction)back2Two:(id)sender { // 移除当前栈顶的控制器 [self.navigationController popViewControllerAnimated ...
- 异常:System.InvalidOperationException: This implementation is not part of the Windows Platform FIPS validated cryptographic algorithms 这个实现是不是Windows平台FIPS验证的加密算法。解决方法
遇见这个问题是在使用了MD5加密算法后报错的,可能的原因如下: 1.FIPS不兼容MD5,此时需要修改注册表 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\C ...
- ERR_FAILED 浏览器访问
我是针对上一篇的问题 继续的探究 ,我百度了 看了这 https://zhidao.baidu.com/question/1175643597811783659.html 之后我就用 电脑管家进行系 ...
- Debug与Release版本的区别详解
原文链接 Debug 和 Release 并没有本质的区别,他们只是VC预定义提供的两组编译选项的集合,编译器只是按照预定的选项行动.如果我们愿意,我们完全可以把Debug和Release的行为完全颠 ...
- SpringBoot学习3:springboot整合filter
整合方式一:通过注解扫描完成 Filter 组件的注册 1.编写filter package com.bjsxt.filter; import javax.servlet.*; import java ...