二叉树链表C++实现
结点的构造

#pragma once
#ifndef NODE_H
#define NODE_H class Node
{
public:
Node();
Node *SearchNode(int nodeIndex);
void DeleteNode();
void PreorderTraversal();
void InorderTraversal();
void PostorderTraversal(); int index;
int data;
Node *pLChild;
Node *pRChild;
Node *pParent;
}; #endif // !NODE_H
需要实现的方法
#pragma once
#ifndef TREE_H
#define TREE_H
#include"Node.h"
class Tree
{
public:
Tree();//创建树
~Tree();//销毁树
Node *SearchNode(int nodeIndex);//搜索结点
bool AddNode(int nodeIndex, int direction, Node* pNode);//添加结点
bool DeleteNode(int nodeIndex, Node* pNode);//删除结点
void PreorderTraversal();//前序遍历
void InorderTraversal();//中序遍历
void PostorderTraversal();//后序遍历
private:
Node * m_pRoot;
}; #endif // ! TREE_H
创建树
申请一段内存
Tree::Tree()
{
m_pRoot = new Node();
};
创建结点
Node::Node()
{
index = ;
data = ;
pLChild = NULL;
pRChild = NULL;
pParent = NULL;
}
销毁树
调用Node的DeleteNode方法
Tree::~Tree()
{
m_pRoot->DeleteNode();
}
如果当前Node对象(this)的pLChild不为空,递归调用DeleteNode方法,this->pLChild变成了新的this,直到delete this销毁掉
如果当前Node对象(this)的pRChild不为空,递归调用DeleteNode方法,this->pRChild变成了新的this,直到delete this销毁掉
如果当前Node对象(this)的pParent不为空,如果父节点的左子节点等于当前Node对象,将当前结点置空
如果当前Node对象(this)的pParent不为空,如果父节点的右子节点等于当前Node对象,将当前结点置空
思路:指定索引向下搜索从最底层子节点开始删除,再往上回到指定索引并删除,删除的顺序是后序

void Node::DeleteNode()
{
if (this->pLChild != NULL)
{
this->pLChild->DeleteNode();
}
if (this->pRChild != NULL)
{
this->pRChild->DeleteNode();
}
if (this->pParent != NULL)
{
if (this->pParent->pLChild == this)
{
this->pParent->pLChild = NULL;
}
if (this->pParent->pRChild == this)
{
this->pParent->pRChild = NULL;
}
} delete this;
}
搜索结点
传入索引,调用Node的SearchNode方法
Node *Tree::SearchNode(int nodeIndex)
{
return m_pRoot->SearchNode(nodeIndex);
}
Node的SearchNode()
如果索引和传入索引相等,返回当前Node对象
当this对象的左子节点不为空,当左子节点索引等于传入索引,返回当前对象的子节点
否则继续对当前对象的左子节点搜索,搜索结果赋值给temp,当temp不为空,返回temp
对右子节点的逻辑同上
否则返回为空
思路:从上向下搜索,顺序为前序
Node *Node::SearchNode(int nodeIndex)
{
if (this->index == nodeIndex)
{
return this;
} Node *temp = NULL;
if (this->pLChild != NULL)
{
if (this->pLChild->index == nodeIndex)
{
return this->pLChild;
}
else
{
temp = this->pLChild->SearchNode(nodeIndex);
if (temp != NULL)
{
return temp;
}
}
} if (this->pRChild != NULL)
{
if (this->pRChild->index == nodeIndex)
{
return this->pRChild;
}
else
{
temp = this->pRChild->SearchNode(nodeIndex);
if (temp != NULL)
{
return temp;
}
}
} return NULL;
}
添加结点
传入索引,direction=0添加左子节点,direction=1添加右子节点,传入pNode参数
先搜索结点并保存在temp中,temp为空返回错误
申请内存给node,为空返回错误
将pNode的index和data分别赋值给node的index和data
node的pParent指针指向temp,temp为指定索引的父节点
direction=0,将temp的pLChild指针指向node
direction=1,将temp的pRChild指针指向node
bool Tree::AddNode(int nodeIndex, int direction, Node* pNode)
{
Node *temp = SearchNode(nodeIndex);
if (temp == NULL)
{
return false;
} Node *node = new Node();
if (node == NULL)
{
return false;
}
node->index = pNode->index;
node->data = pNode->data;
node->pParent = temp; if (direction == )
{
temp->pLChild = node;
} if (direction == )
{
temp->pRChild = node;
} return true;
}
删除结点
传入nodeIndex,pNode参数
搜索结点保存在temp
temp为空,返回错误
pNode不为空,将的temp的data赋值给pNode的data,做返回值使用
调用Node的DeleteNode方法,参见销毁树
bool Tree::DeleteNode(int nodeIndex, Node* pNode)
{
Node *temp = SearchNode(nodeIndex);
if (temp == NULL)
{
return false;
} if (pNode != NULL)
{
pNode->data = temp->data;
} temp->DeleteNode();
return true;
}
前序遍历
调用了Node的PreorderTraversal()
void Tree::PreorderTraversal()
{
m_pRoot->PreorderTraversal();
}
Node的PreorderTraversal()
先输出根节点
左子结点不为空递归,输入当前结点
右子节点不为空递归,输入当前结点
递归的算法最好对着源码打断点,就能看懂了
void Node::PreorderTraversal()
{
cout << this->index<<" "<<this->data << endl;
if (this->pLChild != NULL)
{
this->pLChild->PreorderTraversal();
}
if (this->pRChild != NULL)
{
this->pRChild->PreorderTraversal();
}
}
中序遍历和后序遍历
中序遍历:左根右
后序遍历:左右根
void Tree::InorderTraversal()
{
m_pRoot->InorderTraversal();
} void Tree::PostorderTraversal()
{
m_pRoot->PostorderTraversal();
}
逻辑与前序遍历代码相似
this->index和this->data就是根节点的内容
左右结点进行递归
void Node::InorderTraversal()
{
if (this->pLChild != NULL)
{
this->pLChild->InorderTraversal();
}
cout << this->index << " " << this->data << endl;
if (this->pRChild != NULL)
{
this->pRChild->InorderTraversal();
}
} void Node::PostorderTraversal()
{
if (this->pLChild != NULL)
{
this->pLChild->PostorderTraversal();
}
if (this->pRChild != NULL)
{
this->pRChild->PostorderTraversal();
}
cout << this->index << " " << this->data << endl;
}
补充
根据前序和中序推断出二叉的结构
前序遍历为ABDEGCFH
后序遍历为DBGEACHF

二叉树链表C++实现的更多相关文章
- 【二叉树->链表】二叉树结构转双向线性链表结构(先序遍历)
二叉树存储结构属于非线性链表结构,转化成线性链表结构,能简化操作和理解.然而由非线性转线性需要对整个树遍历一次,不同的遍历方式转化结果页不一样.下面以先序为例. 方法一: 递归法.递归遍历二叉树,因为 ...
- 二叉树、栈、队列、链表的Java代码实现
这是我的学习总结. 如有文章存在谬误,欢迎指出,有其他意见或者建议,也欢迎留言 二叉树链表 前序遍历:先访问根节点,然后访问左子树.右子树 中序遍历:先访问左子树,然后访问根节点.右子树 后序遍历:先 ...
- 二叉树3种递归和非递归遍历(Java)
import java.util.Stack; //二叉树3种递归和非递归遍历(Java) public class Traverse { /******************一二进制树的定义*** ...
- JAVA实现二叉树(简易版--实现了二叉树的各种遍历)
1,个人感觉二叉树的实现主要还是如何构造一颗二叉树.构造二叉树函数的设计方法多种多样,本例采用 addNode 方法实现.以下程序通过定义内部类来表示二叉树的结点,然后再实现了二叉树这种数据结构的一些 ...
- C#数据结构-二叉树-链式存储结构
对比上一篇文章"顺序存储二叉树",链式存储二叉树的优点是节省空间. 二叉树的性质: 1.在二叉树的第i层上至多有2i-1个节点(i>=1). 2.深度为k的二叉树至多有2k- ...
- LeetCode刷题知识点总结——二叉树
二叉树 一.二叉树理论基础 1.满二叉树:如果一棵二叉树只有度为0的结点和度为2的结点,并且度为0的结点在同一层上,则这棵二叉树为满二叉树.通俗话理解:从底层开始到顶部的所有节点都全部填满的二叉树.深 ...
- NOIP2016初赛总结(提高组)
题目:https://www.zhihu.com/question/51865837/answer/127892121 注:我是HE的,不是JS的,照片是ZYJ神犇的 单选 一.单项选择题(共15 题 ...
- Java中二叉树存储结构实现
一.二叉树 二叉树指的是每个节点最多只能有两个子树的有序树.通常左边的子树被称为“左子树”(left subtree),右边的子树被称为右子树. 二叉树的每个节点最多只有2棵子树,二叉树的子树次序不能 ...
- 2017-2018-1 20179205《Linux内核原理与设计》第四周作业
<Linux内核原理与分析> 视频学习及实验操作 Linux内核源代码 视频中提到了三个我们要重点专注的目录下的代码,一个是arch目录下的x86,支持不同cpu体系架构的源代码:第二个是 ...
随机推荐
- ajax 解析
1.通过适当的Ajax应用达到更好的用户体验; 2.把以前的一些服务器负担的工作转嫁到客户端,利于客户端闲置的处理能力来处理,减轻服务器和带宽的负担,从而达到节约ISP的空间及带宽租用成本的目的. 二 ...
- C#文件和目录的操作
根据文件名获取文件 /// <summary> /// 根据文件名获取文件 /// </summary> /// <param name="directory& ...
- javascript实现俄罗斯方块游戏
观摩一下<编程之美>:“程序虽然很难写,却很美妙.要想把程序写好,需要写好一定的基础知识,包括编程语言.数据结构与算法.程序写得好,需要缜密的逻辑思维能力和良好的梳理基础,而且熟悉编程环境 ...
- “全栈2019”Java第四十章:this关键字
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- 【SSO单点系列】开篇
年底将至,忙碌了好几个月的项目也接近尾声了.在这个项目中,由于要和其他外系统做单点登录(SSO),整合其他系统的功能.在网上查询了相关资料后,最终选取了Yale大学发起的一个开源项目 CAS, 作为项 ...
- 8,Phaser__并发且多阶段任务
使用场景 考选武状元 10 个 武生 参加考试 ,第一个关 靠耐力, 坚持最久的5个人进入第二关, 第二关考 力气,力气最大的 3个人进入第二关,第三关考兵法,兵法最好的当选武状元
- Postman使用手册3——环境变量
一.环境变量 当使用API的时候,你可能经常需要使用不同的设置.环境设置可以让你使用变量自定义request.这个方法可以让你轻松的在不同的设置之间改变而不用改变你的request.你不需要担心要记住 ...
- python difflib详解
difflib -帮助进行差异化比较 这个模块提供的类和方法用来进行差异化比较,它能够生成文本或者html格式的差异化比较结果,如果需要比较目录的不同,可以使用filecmp模块. class dif ...
- 通过Maven简单搭建SSM框架
创建Maven就不用多说了,下面直接看Pom.xml里面的依赖吧 <properties> <!-- spring版本号 --> <spring.version>5 ...
- leetcode-118-Pascal's Triangle(生成具有n行的帕斯卡三角形)
题目描述: Given a non-negative integer numRows, generate the first numRows of Pascal's triangle. Example ...