二叉树链表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体系架构的源代码:第二个是 ...
随机推荐
- Windows store app[Part 1]:读取U盘数据
Windows 8系统下开发App程序,对于.NET程序员来说,需要重新熟悉下类库. 关于WinRT,引用一张网上传的很多的结构图: 图1 针对App的开发,App工作在系统划定的安全沙箱内,所以通过 ...
- CentOS下Docker与.netcore(一) 之 安装
CentOS下Docker与.netcore(一) 之 安装 CentOS下Docker与.netcore(二) 之 Dockerfile CentOS下Docker与.netcore(三)之 三剑客 ...
- Commons包详解
Apache Commons包含了很多开源的工具,用于解决平时编程经常会遇到的问题,减少重复劳动.项目地址http://commons.apache.org/ Commons BeanUtils 提供 ...
- python学习之路 二 :基本数据类型
本节重点 理解什么是变量? 掌握各种数据类型 理解可变类型和不可变类型 一.变量和常量 变量: 作用:存贮程序的中间结果在内存里,以备后边的程序调用 定义规范: 变量名只能是 字母.数字活下划线的任意 ...
- 读取xml文件内容到数据库
前言 前言不搭后语·················· 内容 听某个大牛说他们的公司常常会涉及到从xml文件中读数据到写入到数据库,序列化的时候会遇到这这个问题,将要持久化的数据到xml文件存储起来, ...
- 简易 PHP 教程小记
一.简介: 1.用处广 2.免费 3.PHP Hypertext Preprocessor 二.语法: 1.<?php coders ?> 2.注释:"#" " ...
- jxl读取excel
String path=""; String path2=""; File file = new File(path); File file2 = new Fi ...
- npm淘宝镜像和默认镜像切换
1.得到原本的镜像地址 npm get registry > https://registry.npmjs.org/ 设成淘宝的 npm config set registry http://r ...
- nginx高性能WEB服务器系列之四配置文件详解
nginx系列友情链接:nginx高性能WEB服务器系列之一简介及安装https://www.cnblogs.com/maxtgood/p/9597596.htmlnginx高性能WEB服务器系列之二 ...
- 2019.2.15 t3 平均值
#include <cstdio> #include <iostream> #include <cstring> #include <cmath> #i ...