C++数据结构之 --二叉树简单实现和4种遍历

来源:互联网 发布:音频噪音消除软件 编辑:程序博客网 时间:2024/05/16 09:25

实验目的:实现简单的二叉树!


头文件:

二叉树.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;
}






0 0
原创粉丝点击