1. 程式人生 > >C++資料結構之 --二叉樹簡單實現和4種遍歷

C++資料結構之 --二叉樹簡單實現和4種遍歷

實驗目的:實現簡單的二叉樹!

標頭檔案:

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