实验目的:实现简单的二叉树!
头文件:
二叉树.h
#ifndef 二叉树_h__
#define 二叉树_h__
#include <iostream>
#include <queue>
template<class T> class BinaryTree;//二叉树的声明
/*树的节点*/
template<class T>
class TreeNode{
public:
TreeNode<T> *leftChild;
TreeNode<T> *rightChild;
T data;
public:
TreeNode(){
leftChild = NULL;
rightChild = NULL;
}
};
//二叉树的定义
template<class T>
class BinaryTree{
public:
TreeNode<T> *root;//头节点
public:
void InOrder();//中序遍历
void InOrder(TreeNode<T> *currentNode);
void PreOrder();//先序遍历
void PreOrder(TreeNode<T> *currentNode);
void EndOrder();//后序遍历
void EndOrder(TreeNode<T> *currentNode);
void LevelOrder();//层序遍历
void LevelOrder(TreeNode<T> *currentNode);
void Visit(TreeNode<T> *currentNode);//访问当前节点
};
template<class T>
void BinaryTree<T>::LevelOrder(){
std::cout << "层序遍历:" << std::endl;
LevelOrder(root);
}
template<class T>
void BinaryTree<T>::LevelOrder(TreeNode<T> *currentNode){
//创建一个队列
std::queue<TreeNode<T>*> q;
while(currentNode)
{
Visit(currentNode);
if (currentNode->leftChild)
{
q.push(currentNode->leftChild);
}
if (currentNode->rightChild)
{
q.push(currentNode->rightChild);
}
if (q.empty())
{
return;
}
//在弹出一个节点时,我们要先把它的左右孩子先放进队列里
currentNode = q.front();//取队首的节点,
q.pop();
}
}
template<class T>
void BinaryTree<T>::Visit(TreeNode<T> *currentNode){
std::cout << currentNode->data << " ";
}
template<class T>
void BinaryTree<T>::EndOrder(){
std::cout << "后序遍历:" << std::endl;
EndOrder(root);
}
template<class T>
void BinaryTree<T>::EndOrder(TreeNode<T> *currentNode)
{
if (currentNode)
{
EndOrder(currentNode->leftChild);
EndOrder(currentNode->rightChild);
Visit(currentNode);
}
}
template<class T>
void BinaryTree<T>::PreOrder(){
std::cout << "先序遍历:" << std::endl;
PreOrder(root);
}
template<class T>
void BinaryTree<T>::PreOrder(TreeNode<T> *currentNode){
if (currentNode)
{
Visit(currentNode);
PreOrder(currentNode->leftChild);
PreOrder(currentNode->rightChild);
}
}
template<class T>
void BinaryTree<T>::InOrder(){
std::cout << "中序遍历:" << std::endl;
InOrder(root);
}
template<class T>
void BinaryTree<T>::InOrder(TreeNode<T> *currentNode){
if (currentNode)
{
InOrder(currentNode->leftChild);
//显示当前节点
Visit(currentNode);
InOrder(currentNode->rightChild);
}
}
#endif // 二叉树_h__
/* 遍历的规则:
中序遍历:左子树-节点-右子树
先序遍历:节点-左子树-右子树
后序遍历:左子树-右子树-节点
层序遍历:一层一层遍历
*/
实验的二叉树图
源文件
main.cpp
#include <iostream>
#include "二叉树.h"
using namespace std;
int main(int argc,const char* argv[]){
cout << "你好,每一天" << endl;
/*构造二叉树*/
TreeNode<int> a1;
a1.data = 1;
TreeNode<int> b2;
b2.data = 2;
TreeNode<int> c3;
c3.data = 3;
TreeNode<int> d4;
d4.data = 4;
TreeNode<int> e5;
e5.data = 5;
TreeNode<int> f6;
f6.data = 6;
TreeNode<int> g7;
g7.data = 7;
TreeNode<int> h8;
h8.data = 8;
TreeNode<int> i9;
i9.data = 9;
/*创建二叉树*/
BinaryTree<int> binaryTree;
binaryTree.root = &a1;
a1.leftChild = &b2;
a1.rightChild = &c3;
b2.leftChild = &d4;
b2.rightChild = &e5;
e5.leftChild = &g7;
e5.rightChild = &h8;
c3.leftChild = &f6;
f6.rightChild = &i9;
/*先序遍历*/
binaryTree.PreOrder();
cout <<endl;
/*中序遍历*/
binaryTree.InOrder();
cout <<endl;
/*后序遍历*/
binaryTree.EndOrder();
cout << endl;
/*层序遍历*/
binaryTree.LevelOrder();
system("pause");
return 0;
}
实验结果:
总结:
二叉树:只要有头节点(root),就可以确定一个二叉树了。
节点:每一个节点,都有 value,leftfchild,rightchild.
层序遍历时需要借助队列。
第二篇:二叉树的简单实现和4种遍历操作
#pragma once
#ifndef NODE_H
#define NODE_H
class Node
{
public:
friend class BinaryTree;
Node();
Node(int item);
~Node();
//设置Value
void setData(int item);
int getData();
//设置leftChild
void setLeft(Node* left);
Node* getLeft();
//设置rightChild
void setRight(Node* right);
Node* getRight();
private:
Node* left;
Node* right;
int data;
};
#endif
#include "Node.h"
Node::Node(){}
Node::Node(int item)
{
this->data = item;
this->left = nullptr;
this->right = nullptr;
}
Node::~Node(){}
void Node::setData(int item){
this->data = item;
}
int Node::getData(){
return this->data;
}
void Node::setLeft(Node* left){
this->left = left;
}
Node* Node::getLeft(){
return this->left;
}
void Node::setRight(Node* right){
this->right = right;
}
Node* Node::getRight(){
return this->right;
}
#pragma once
#ifndef BinaryTree_h__
#define BinaryTree_h__
#include "Node.h"
class BinaryTree
{
public:
//构造器
BinaryTree();
~BinaryTree();
//获取根节点
Node* getRoot();
//创建一棵二叉树
void CreatBinaryTree();
//添加节点函数
void addNode(Node* newNode,Node* itemroot);
//先根遍历
void preOrder(Node* t);
//中根遍历
void inOrder(Node* t);
//后根遍历
void postOrder(Node* t);
//层序遍历
void levelOrder(Node* t);
//寻找data为item的节点
Node* findData(Node* t, int item);
//寻找给定节点的父节点
Node* returnFather(Node* t, Node *p);
//删除t节点及其左右子树
void deleteSubTree(Node* t);
private:
//判断添加节点是否比根小
bool toLeft(int a, int b);
//判断添加的节点是否比根大
bool toRight(int a, int b);
//删除节点和节点的左右子树
void deletAll(Node* t);
//头节点
Node* root;
};
#endif // BinaryTree_h__
#include "BinaryTree.h"
#include <iostream>
#include <queue>
using namespace std;
BinaryTree::BinaryTree(){ root = nullptr; }
BinaryTree::~BinaryTree(){}
//获取根节点
Node* BinaryTree::getRoot(){ return root; }
void BinaryTree::CreatBinaryTree() //创建一棵二叉树
{
cout << "以此输入number(按“字母”退出)" << endl;
int intValue;
Node* current;
while (cin >> intValue)
{
current = new Node(intValue);//构造新的节点
if (root==nullptr)
root = current;
else
addNode(current,root);
}
}
//添加节点函数
void BinaryTree::addNode(Node* newNode, Node* root)
{
//判断是否添加到左子树
if (toLeft(newNode->data, root->data))
{
if (root->left == nullptr)
{
root->left = newNode;
}
else
{
addNode(newNode, root->left);
}
}
else if (toRight(newNode->data, root->data))
{
if (root->right == nullptr)
{
root->right = newNode;
}
else
{
addNode(newNode, root->right);
}
}
}
void BinaryTree::preOrder(Node* t)//先根遍历
{
if (t!=nullptr)
{
cout << t->getData() <<" ";
preOrder(t->getLeft());
preOrder(t->getRight());
}
}
void BinaryTree::inOrder(Node* t)//中根遍历
{
if (t!=nullptr)
{
inOrder(t->getLeft());
cout << t->getData() << " ";
inOrder(t->getRight());
}
}
void BinaryTree::postOrder(Node* t)//后根遍历
{
if (t!=nullptr)
{
postOrder(t->getLeft());
postOrder(t->getRight());
cout << t->getData() << " ";
}
}
//层序遍历
void BinaryTree::levelOrder(Node* t){
//先创建一个队列
queue<Node*> myQueue;
while (t!=nullptr)
{
cout << t->data << " ";//先打印它的值
//把左孩子放进去
if (t->left!=nullptr)
{
myQueue.push(t->left);
}
//把有孩子放进去
if (t->right!=nullptr)
{
myQueue.push(t->right);
}
if (myQueue.empty())
{
return;
}
//获取当前的节点
t = myQueue.front();
myQueue.pop();
}
}
//寻找data为item的节点
Node* BinaryTree::findData(Node* t, int item)
{
Node* p;
if (t==nullptr)
{
return nullptr;
}else if (t->getData()==item)
{
return t;
}else if ((p=findData(t->getLeft(),item))!=nullptr)
{
return p;
}
else
{
return findData(t->getRight(), item);
}
}
//寻找给定节点的父节点
Node* BinaryTree::returnFather(Node* t, Node *p)
{
Node* q;
if (t==nullptr || p==nullptr)
{
return nullptr;
}
else if (t->getLeft()==p || t->getRight()==p)
{
return t;
}else if ((q=returnFather(t->getLeft(),p))!=nullptr)
{
return q;
}
else
{
return returnFather(t->getRight(),p);
}
}
//删除t节点及其左右子树
void BinaryTree::deleteSubTree(Node* t)
{
if (t==nullptr)
{
return;
}else if (t==root)
{
deletAll(t);
root = nullptr;
return;
}
Node* p, *q;
p = t;
q = returnFather(root, p);
if (q)
{
if ((q->getLeft())==p)
{
q->setLeft(nullptr);
}
else
{
q->setRight(nullptr);
}
}
deletAll(p);
}
//判断添加节点是否比根小
bool BinaryTree::toLeft(int newItemValue, int rootValue)
{
if (newItemValue<rootValue)
{
return true;
}
else
{
return false;
}
}
//判断添加的节点是否比根大
bool BinaryTree::toRight(int newItemValue, int rootValue)
{
if (newItemValue>rootValue)
{
return true;
}
else
{
return false;
}
}
//无情干掉子节点和左右子树
void BinaryTree::deletAll(Node* t)
{
if (t!=nullptr)
{
deletAll(t->getLeft());
deletAll(t->getRight());
delete t;
}
}
#include <iostream>
#include "BinaryTree.h"
using namespace std;
int main(){
BinaryTree binaryTree;
binaryTree.CreatBinaryTree();
cout << "先序遍历结果:" <<" ";
binaryTree.preOrder(binaryTree.getRoot());
cout << endl;
cout << "中序遍历结果:" << " ";
binaryTree.inOrder(binaryTree.getRoot());
cout << endl;
cout << "后序遍历结果:" << " ";
binaryTree.postOrder(binaryTree.getRoot());
cout << endl;
cout << "层序遍历结果:" << " ";
binaryTree.levelOrder(binaryTree.getRoot());
cout << endl;
Node* test;
test = binaryTree.findData(binaryTree.getRoot(), 2);
Node* test2;
test2 = binaryTree.returnFather(binaryTree.getRoot(), test);
cout << test2->getData() << endl;
binaryTree.deleteSubTree(test);
cout << "删除后中根遍历结果:" << " ";
binaryTree.inOrder(binaryTree.getRoot());
cout << endl;
system("pause");
return 0;
}