您的位置:首页 > 理论基础 > 数据结构算法

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

2016-02-29 14:11 886 查看
实验目的:实现简单的二叉树!

头文件:

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

}







内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: