二叉树链表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体系架构的源代码:第二个是 ...
随机推荐
- Visual Studio Error
Visual Studio Error 注意:文中所有“系统”用词,均指Windows Console操作系统IO Debug Error 错误类型 #0表示调用约定错误 可以考虑在指针前面加上_st ...
- mysql用户增删改
MySql中添加用户,新建数据库,用户授权,删除用户,修改密码(注意每行后边都跟个;表示一个命令语句结束): 1.新建用户 1.1 登录MYSQL: @>mysql -u root -p @&g ...
- python 特性:height-->while
""" 出题:height 女生找对象 男生在1米-1.5米之间 小强你在哪里? 男生在1.5-1.7米之间 没有安全感 男生在1.7 - 1.8米之间 帅哥 留个电话 ...
- [Objective-C语言教程]变量(6)
变量是程序可以操作的存储区域的名称. Objective-C中的每个变量都有一个特定的类型,它决定了变量内存的大小和布局; 可存储在内存中的值的范围; 以及可以应用于变量的操作集. 变量的名称可以由字 ...
- Flink学习笔记:Operators串烧
本文为<Flink大数据项目实战>学习笔记,想通过视频系统学习Flink这个最火爆的大数据计算框架的同学,推荐学习课程: Flink大数据项目实战:http://t.cn/EJtKhaz ...
- 解决myeclipse打开.form文件报错
症状: 打开AutoEKPMainFrm.form文件的时候出现如下问题:
- [Shell]如何获取Maven工程的project.version信息
问题: 今天遇到Shell中如何能获取Maven项目工程中的project.version信息的问题 解决方案: 使用Maven的Exec 插件 #! /bin/bash MVN_VERSION=$( ...
- spring切面拦截实现
1.建立业务类(英雄战斗实现类) package com.g2.api; public interface Weapon { int attack(); String getName(); } pac ...
- C语言字符串的操作
C语言字符串操作函数 1. 字符串反转 - strRev2. 字符串复制 - strcpy3. 字符串转化为整数 - atoi4. 字符串求长 - strlen5. 字符串连接 - strcat6. ...
- extjs--combo动态获取数据
<!DOCTYPE html> <html> <head> <link href="https://cdnjs.cloudflare.com/aja ...