[iuud8]数据结构算法之二叉树操作
来源:互联网 发布:显卡数据怎么看 编辑:程序博客网 时间:2024/05/13 04:50
定义:有且只有一个被称为根的节点,由若干个互不相交的字数,这些字数本身也是一棵树。
专业术语:节点 父节点 子节点
子孙 堂兄弟
深度:从根节点到最底层节点的层数 根节点是第一层
叶子节点:没有子节点的节点
非终端节点:存在一个或多个子节点的节点
度:节点拥有的最大子节点的个数
树的分类:一般树 :任意一个节点的子节点的个数都不受限制
二叉树 :任意一个节点的子节点的个数最多两个,且子节点的位置不可更改
二叉树分类:一般二叉树 满二叉树(当一个k层的二叉树存在2的k次方减1个节点时叫做满二叉树) 完全二叉树(如果只是删除了满二叉树最底层最右边的连续若干个节点,这样形成的二叉树就是完全二叉树)
森林 : n个互不相交的树的集合
树的存储:
二叉树的存储
连续存储【完全二叉树 】
优点:查找某个节点的父节点和子节点速度快(也包括判断是否存在子节点)
缺点:耗费内存空间过大
链式存储
一般树的存储
双亲表示法 求父节点方便
孩子表示法 求子节点方便
双亲孩子表示法 兼顾双亲表示法与孩子表示法的优点
二叉树表示法 把一个普通树转化为二叉树来存储
具体转换方式:左指针域指向它的第一个孩子
右指针域指向它的下一个堂兄弟
森林的存储
除第一棵树之外,其他树的根节点作为第一棵树根节点的堂兄弟然后再根据上面的转换方法进行转换。
二叉树操作
遍历
先序遍历
先访问根节点 再先序访问左子树 再先序访问右子树
中序遍历
中序遍历左子树 再访问根节点 再中序遍历右子树
后序遍历
后序遍历左子树 再后序遍历右子树 再访问根节点
已知两种遍历序列求原始二叉树
通过先序和中序 或者 中序和后序可以还原出原始的二叉树
但是先序和后序这种组合是无法还原出原始的二叉树的
树的应用
树是数据库中数据组织的一种重要形式
操作系统子进程与父进程的关系本身就是一棵树
面向对象语言中类的继承关系
赫夫曼树
代码区
#include<iostream>
#include<stdlib.h>
#include<stack>
#include<queue>
typedefstruct BTNode
{
char data;
structBTNode *pLchild; //左孩子
structBTNode *pRchild; //右孩子
} *Tree;
//动态创建一棵树
Tree CreateBTree(Tree &root)
{
char data;
std::cout<<"请输入节点内容:"<<std::endl;
std::cin>>data;
if(data =='#')
{
root = NULL;
}
else
{
root = (Tree)malloc(sizeof(BTNode));
root->data = data;
CreateBTree(root->pLchild);
CreateBTree(root->pRchild);
}
return root;
}
//先序遍历一棵树
void PreTraverseBTree(Tree pT)
{
if(pT !=NULL)
{
std::cout<<pT->data<<" "; //先输出根节点
if(pT->pLchild !=NULL)
{
PreTraverseBTree(pT->pLchild); //再先序遍历左子树
}
if(pT->pRchild !=NULL)
{
PreTraverseBTree(pT->pRchild); //再先序遍历右子树
}
}
}
//中序遍历一棵树
void InTraverseBTree(Tree pT)
{
if(pT !=NULL)
{
if(pT->pLchild !=NULL)
{
InTraverseBTree(pT->pLchild);
}
std::cout<<pT->data<<" ";
if(pT->pRchild !=NULL)
{
InTraverseBTree(pT->pRchild);
}
}
}
//后序遍历一棵树
void PostTraverseBTree(Tree pT)
{
if(pT !=NULL)
{
if(pT->pLchild !=NULL)
{
PostTraverseBTree(pT->pLchild);
}
if(pT->pRchild !=NULL)
{
PostTraverseBTree(pT->pRchild);
}
std::cout<<pT->data<<" ";
}
}
//深度优先遍历
void depthFirstSearch(Tree root){
std::stack<Tree> nodeStack; //使用C++的STL标准模板库
nodeStack.push(root);
Tree node;
while(!nodeStack.empty()){
node = nodeStack.top();
std::cout<<node->data<<" "; //遍历根结点
nodeStack.pop();
if(node->pRchild){
nodeStack.push(node->pLchild); //先将右子树压栈
}
if(node->pLchild){
nodeStack.push(node->pLchild); //再将左子树压栈
}
}
}
//广度优先遍历
voidbreadthFirstSearch(Tree root)
{
std::queue<Tree> nodeQueue; //使用C++的STL标准模板库
nodeQueue.push(root);
Tree node;
while(!nodeQueue.empty()){
node = nodeQueue.front();
nodeQueue.pop();
std::cout<<node->data<<" ";
if(node->pLchild){
nodeQueue.push(node->pLchild); //先将左子树入队
}
if(node->pRchild){
nodeQueue.push(node->pRchild); //再将右子树入队
}
}
}
int main()
{
Tree pT;
CreateBTree(pT);
std::cout<<"先序遍历:"<<std::endl;
PreTraverseBTree(pT);
std::cout<<std::endl;
std::cout<<"中序遍历:"<<std::endl;
InTraverseBTree(pT);
std::cout<<std::endl;
std::cout<<"后序遍历:"<<std::endl;
PostTraverseBTree(pT);
std::cout<<std::endl;
std::cout<<"深度优先遍历:"<<std::endl;
depthFirstSearch(pT);
std::cout<<std::endl;
std::cout<<"广度优先遍历:"<<std::endl;
breadthFirstSearch(pT);
std::cout<<std::endl;
return0;
}
- [iuud8]数据结构算法之二叉树操作
- 数据结构与算法学习之二叉树及二叉树的相关操作
- C++数据结构之二叉树递归操作
- 数据结构之二叉树的基本操作
- 数据结构之二叉树递归操作
- 数据结构C语言版之二叉树操作
- 数据结构之排序二叉树操作
- 数据结构之二叉树的简单操作
- 数据结构与算法之二叉树遍历
- 数据结构查找算法之二叉查找树
- 算法导论------------基本数据结构之二叉树
- 数据结构与算法之二叉树
- 算法与数据结构之二叉树
- 数据结构和算法系列之 二叉树
- 数据结构与算法之二叉树
- 《数据结构和算法》之二叉树
- 数据结构与算法04 之二叉树
- 数据结构与算法之二叉树
- hibernate 的inverse 属性和cascade 属性
- LVM FS NFS CIFS NAS 等存储概念解析
- 关于lua 5.1源码分析与相关有用摘要
- 三种冒泡排序
- 第三天,盒子的生活
- [iuud8]数据结构算法之二叉树操作
- Matlab中的矩阵用法2
- Hadoop平台上Oozie调度系统的安装配置
- arcgis js api和openlayer在处理大数据的表现
- 2014/4/18 结合easyui的省市区查询 小结
- 社会化营销的三个小贴士
- R Programming -- data frames
- 《深入网站开发和运维》
- javascript变量作用域、作用域链