此算法中的树结构为“左儿子有兄弟链接结构”

在这样的一个二叉树中,一个节点的左分支是他的大儿子节点,右分支为他的大兄弟节点。

这里讲的树有递归前根,中根,后根遍历,插入节点,插入兄弟节点,查找结点,释放内存这些功能。

重点说一下查找节点这一算法:

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++树及树与二叉树的转换的更多相关文章

  1. 哈夫曼树【最优二叉树】【Huffman】

    [转载]只为让价值共享,如有侵权敬请见谅! 一.哈夫曼树的概念和定义 什么是哈夫曼树? 让我们先举一个例子. 判定树:         在很多问题的处理过程中,需要进行大量的条件判断,这些判断结构的设 ...

  2. 树(二叉树 & 二叉搜索树 & 哈夫曼树 & 字典树)

    树:n(n>=0)个节点的有限集.有且只有一个root,子树的个数没有限制但互不相交.结点拥有的子树个数就是该结点的度(Degree).度为0的是叶结点,除根结点和叶结点,其他的是内部结点.结点 ...

  3. Atitit 常见的树形结构 红黑树  二叉树   B树 B+树  Trie树 attilax理解与总结

    Atitit 常见的树形结构 红黑树  二叉树   B树 B+树  Trie树 attilax理解与总结 1.1. 树形结构-- 一对多的关系1 1.2. 树的相关术语: 1 1.3. 常见的树形结构 ...

  4. 以AVL树为例理解二叉树的旋转(Rotate)操作

    树旋转是在二叉树中的一种子树调整操作, 每一次旋转并不影响对该二叉树进行中序遍历的结果. 树旋转通常应用于需要调整树的局部平衡性的场合. 树旋转包括两个不同的方式, 分别是左旋转和右旋转. 两种旋转呈 ...

  5. 数据结构(一)二叉树 & avl树 & 红黑树 & B-树 & B+树 & B*树 & R树

    参考文档: avl树:http://lib.csdn.net/article/datastructure/9204 avl树:http://blog.csdn.net/javazejian/artic ...

  6. C# 表达式树 创建、生成、使用、lambda转成表达式树~表达式树的知识详解

    笔者最近学了表达式树这一部分内容,为了加深理解,写文章巩固知识,如有错误,请评论指出~ 表达式树的概念 表达式树的创建有 Lambda法 和 组装法. 学习表达式树需要 委托.Lambda.Func& ...

  7. php数据结构课程---5、树(树的 存储方式 有哪些)

    php数据结构课程---5.树(树的 存储方式 有哪些) 一.总结 一句话总结: 双亲表示法:data parent:$tree[1] = ["B",0]; 孩子表示法:data ...

  8. 字符串 --- KMP Eentend-Kmp 自动机 trie图 trie树 后缀树 后缀数组

    涉及到字符串的问题,无外乎这样一些算法和数据结构:自动机 KMP算法 Extend-KMP 后缀树 后缀数组 trie树 trie图及其应用.当然这些都是比较高级的数据结构和算法,而这里面最常用和最熟 ...

  9. 【查找结构5】多路查找树/B~树/B+树

    在前面专题中讲的BST.AVL.RBT都是典型的二叉查找树结构,其查找的时间复杂度与树高相关.那么降低树高自然对查找效率是有所帮助的.另外还有一个比较实际的问题:就是大量数据存储中,实现查询这样一个实 ...

  10. 【Todo】字符串相关的各种算法,以及用到的各种数据结构,包括前缀树后缀树等各种树

    另开一文分析字符串相关的各种算法,以及用到的各种数据结构,包括前缀树后缀树等各种树. 先来一个汇总, 算法: 本文中提到的字符串匹配算法有:KMP, BM, Horspool, Sunday, BF, ...

随机推荐

  1. 【作业留存】根据IATF框架,设计的一种中小型企业安全拓扑

  2. codeforce Gym 100425E The Street Escalator(期望,线性递推)

    算数学期望,每个人都可以分开来考虑.Xi表示第i个人跑到另外一边的次数. Xi服从二项分布.概率的和是个二项式,(p+1-p)^T,把二项式展开,p的偶次项是留在原来那一边的概率. 可以用((a+b) ...

  3. Go - 环境安装

    目录 你好,Go语言 环境安装 目录结构 命令 开发工具 学习网址 小结 你好,Go语言 Go 是一个开源的编程语言,它能让构造简单.可靠且高效的软件变得容易. 因工作需要,准备入坑,先从环境安装开始 ...

  4. python_58_装饰器1

    装饰器:定义:本质是函数,(装饰其他函数),就是为其它函数添加附加功能原则:1.不能修改被饰的函数的源代码 2.不能修改被饰的函数的调用方式实现装饰器知识储备: 1.函数即“变量” 2.高阶函数 3. ...

  5. java基础——线程池

    第2章 线程池 2.1 线程池概念 线程池,其实就是一个容纳多个线程的容器,其中的线程可以反复使用,省去了频繁创建线程对象的操作,无需反复创建线程而消耗过多资源. 我们详细的解释一下为什么要使用线程池 ...

  6. JS中进行浮点数计算式,遇到的问题

    今天在做项目时,需要在页面进行计算,但是当两个数都是小数时,计算的结果却不是想象中的: 比如1371.3-0.9算出来却是1370.39999999,后来上网搜一下,原来js是弱类型语言,没有那么高的 ...

  7. 定位设备--llseek实现

    /** 如果llseek实现lseek和llseek系统调用,如果未定义llseek方法, 内核默认修改file结构体中的f_pos成员来实现定位,如果是操作一个 设备,则需提供自己的llseek方法 ...

  8. MySql学习笔记01

    MySql01 课程介绍 数据库简介 之前通过流操作文件的方式存储数据弊端: 1. 效率低 2. 不管是存还是取都比较麻烦 3. 一般只能存储小量数据 4. 只能存储文本数据 什么是DB DataBa ...

  9. 四、MySQL 连接

    MySQL 连接 使用mysql二进制方式连接 您可以使用MySQL二进制方式进入到mysql命令提示符下来连接MySQL数据库. 实例 以下是从命令行中连接mysql服务器的简单实例: [root@ ...

  10. CSS+JS实现流星雨动画

    引言 平常会做一些有意思的小案例练手,通常都会发到codepen上,但是codepen不能写分析.        所以就在博客上开个案例分享系列,对demo做个剖析.目的以分享为主,然后也希望各路大神 ...