关于二叉树的基本知识还是有必要去了解的,比如根据二叉树写出三种遍历,以及根据给出的遍历写出其他方式的遍历和重构二叉树等,这些知识点还是很有意思的大笑,下面的代码很多都是参考网上的,我这里贴出来主要是作为我学习数据结构的一些总结吧
首先是树节点的定义:
[cpp] view plain copy
template<class Entry>
struct Binary_node
{
Entry data;
Binary_node<Entry>* left;
Binary_node<Entry>* right;
Binary_node();
Binary_node(const Entry &x);
};
这个没啥说的,一看就懂
下面是二叉树的类函数
[cpp] view plain copy
template<class Entry>
class Binary_tree
{
public:
Binary_tree():root(NULL){};
~Binary_tree();
/* Binary_tree();*/
bool empty() const;
void preorder(void (*visit)(Entry &));
void inorder(void (*visit)(Entry &));
void postorder(void (*visit)(Entry &));
//Binary_tree大小
int size() const;
int height() const;
void clear();
void insert(const Entry& x);
void reverse();
Binary_tree(const Binary_tree<Entry>&original);
Binary_tree & operator=(const Binary_tree<Entry>&original);
const Binary_node<Entry>* get_root() const;
//一些递归辅助函数
private:
int recursive_size(const Binary_node<Entry>*root) const;
int recursive_height(const Binary_node<Entry>*root) const;
void equal(Binary_node<Entry>*&sub_root,const Binary_node<Entry>*orig_node);
void recursive_reverse(Binary_node<Entry> * & sub_root);
void recursive_clear(Binary_node<Entry> * & sub_root);
void recursive_insert(Binary_node<Entry> * & sub_root, const Entry& x);
void recursive_inorder(Binary_node<Entry> * sub_root, void (*visit)(Entry &));
void recursive_preorder(Binary_node<Entry> * sub_root, void (*visit)(Entry &));
void recursive_postorder(Binary_node<Entry> * sub_root, void (*visit)(Entry &));
protected:
Binary_node<Entry>* root;
};
操作二叉树的一个显著特点就是大量使用了递归,基本上每个操作都编写了相应的递归函数并将其声明为private,这样可以获得更好的封装性
注意到有三个函数传递的指针的引用
void recursive_reverse(Binary_node<Entry> * & sub_root);
void recursive_clear(Binary_node<Entry> * & sub_root);
void recursive_insert(Binary_node<Entry> * & sub_root, const Entry& x);
这些函数都是要修改protected保护下的 root,传递引用于直接传地址的区别是,引用传递的就是root本身;传递Binary_node<Entry> * sub_root
其实传递的是root的副本,如果只是要读取数据那么这样做没问题,比如遍历函数。
下面继续贴代码吐舌头
[cpp] view plain copy
#ifndef BINARY_TREE_CPP_X
#define BINARY_TREE_CPP_X
#include "Binary_tree.h"
//结点构造函数
template<class Entry>
Binary_node<Entry>::Binary_node()
{
left = right = NULL;
}
template<class Entry>
Binary_node<Entry>::Binary_node(const Entry &x)
{
left = right = NULL;
data = x;
}
template<class Entry>
Binary_tree<Entry>::Binary_tree(const Binary_tree<Entry>&original)
{
root = original.get_root();
}
template<class Entry>
void Binary_tree<Entry>::recursive_inorder(Binary_node<Entry>*sub_root, void(*visit)(Entry&))
{//中序遍历的递归函数
if(sub_root!=NULL)
{
recursive_inorder(sub_root->left, visit);
(*visit)(sub_root->data);
recursive_inorder(sub_root->right, visit);
}
}
template<class Entry>
void Binary_tree<Entry>::inorder(void (*visit)(Entry&))
{//中序遍历
recursive_inorder(root, visit);
}
template<class Entry>
void Binary_tree<Entry>::recursive_postorder(Binary_node<Entry>*sub_root, void (*visit)(Entry&))
{//后序遍历的递归函数
if (sub_root!=NULL)
{
recursive_postorder(sub_root->left, visit);
recursive_postorder(sub_root->right, visit);
(*visit)(sub_root->data);
}
}
template<class Entry>
void Binary_tree<Entry>::postorder(void (*visit)(Entry&))
{//后序遍历
recursive_postorder(root, visit);
}
template<class Entry>
void Binary_tree<Entry>::recursive_preorder(Binary_node<Entry>*sub_root, void (*visit)(Entry&))
{//先序遍历的递归函数
if (sub_root!=NULL)
{
(*visit)(sub_root->data);
recursive_preorder(sub_root->left, visit);
recursive_preorder(sub_root->right, visit);
}
}
template<class Entry>
void Binary_tree<Entry>::preorder(void (*visit)(Entry&))
{//先序遍历
recursive_preorder(root, visit);
}
//return tree height, if only one node then return 1
template<class Entry>
int Binary_tree<Entry>::height() const
{
return recursive_height(root);
}
#define max MAX
template<class Comparable>
Comparable MAX(const Comparable& a, const Comparable& b)
{
return a > b ? a : b;
}
template<class Entry>
int Binary_tree<Entry>::recursive_height(const Binary_node<Entry>*root) const
{
if(root == NULL)
return 0;
else
return 1 + max(recursive_height(root->left) , recursive_height(root->right)) ;
}
#undef max
//return the size of tree
template<class Entry>
int Binary_tree<Entry>::size() const
{
return recursive_size(root);
}
template<class Entry>
int Binary_tree<Entry>::recursive_size(const Binary_node<Entry>*root) const
{
if(root == NULL)
return 0;
else
return 1 + recursive_size(root->left) + recursive_size(root->right) ;
}
//the tree is empty ?
template<class Entry>
bool Binary_tree<Entry>::empty() const
{
return root == NULL;
}
//insert x to the tree
template<class Entry>
void Binary_tree<Entry>::insert(const Entry& x)
{
recursive_insert(root, x);
}
//the recursive function of insert,
//insert x in the less height side,
//if both sides are same height then insert to the left
//第一个参数必须使用引用否则插入失败,而其他不涉及数据改动的函数则不需要
//引用传参时不会发生值拷贝,如果不加引用,会先在函数的栈空间拷贝一个root,但当函数
//结束时这个拷贝就会被销毁,所以会导致插入失败
template<class Entry>
void Binary_tree<Entry>::recursive_insert(Binary_node<Entry>*&sub_root, const Entry& x)
{
if(sub_root == NULL)
{
Binary_node<Entry>* ins_data = new Binary_node<Entry>(x);
sub_root = ins_data;
return;
}
else
{
if(recursive_height(sub_root->left) > recursive_height(sub_root->right))
recursive_insert(sub_root->right, x);
else
recursive_insert(sub_root->left, x);
}
}
//destuctor
template<class Entry>
Binary_tree<Entry>::~Binary_tree()
{
clear();
}
template<class Entry>
void Binary_tree<Entry>::clear()
{
recursive_clear(root);
}
//recursive function for destroy tree
template<class Entry>
void Binary_tree<Entry>::recursive_clear(Binary_node<Entry>*&sub_root)
{//两个版本都OK
#if 0
if(sub_root != NULL)
{
recursive_clear(sub_root->left);
recursive_clear(sub_root->right);
delete sub_root;
sub_root = NULL;
}
#else
if(sub_root->left!=NULL)
recursive_clear(sub_root->left);
if(sub_root->right!=NULL)
recursive_clear(sub_root->right);
delete sub_root;
sub_root = NULL;
#endif
}
//get the root
template<class Entry>
const Binary_node<Entry>* Binary_tree<Entry>::get_root() const
{
return root;
}
//deep copy
template<class Entry>
Binary_tree<Entry>& Binary_tree<Entry>::operator =(const Binary_tree<Entry>&original)
{
equal(root, original.get_root());
return *this;
}
template<class Entry>
void Binary_tree<Entry>::equal(Binary_node<Entry>*&sub_root,const Binary_node<Entry>*orig_node)
{
if(empty())
sub_root = new Binary_node<Entry>(orig_node->data);
if(orig_node->left!=NULL)
{
sub_root->left = new Binary_node<Entry>(orig_node->left->data);
equal(root->left, orig_node->left);
}
if(orig_node->right!=NULL)
{
sub_root->right = new Binary_node<Entry>(orig_node->right->data);
equal(root->right, orig_node->right);
}
}
//reverse the binary tree, exchange left and right
template<class Entry>
void Binary_tree<Entry>::reverse()
{
recursive_reverse(root);
}
template<class Entry>
void Binary_tree<Entry>::recursive_reverse(Binary_node<Entry> * & sub_root)
{
if(sub_root!=NULL)
{
Binary_node<Entry>* temp = NULL;
temp = sub_root->left;
sub_root->left = sub_root->right;
sub_root->right = temp;
recursive_reverse(sub_root->left);
recursive_reverse(sub_root->right);
}
}
#endif
要说明一下insert和reverse这两个函数,
insert的规则是:如果root为空,新元素插入到根节点,否则把它插入到两颗子树中较短的一颗,
如果两颗子树具有同样的高度就插入到左子树中
reverse的规则如下图:
最后是测试代码:
[cpp] view plain copy
#include <iostream>
#include "Binary_tree.h"
using namespace std;
void print( int& x);
int main()
{
Binary_tree<int> dd;
dd.insert(3);
dd.insert(2);
dd.insert(5);
dd.insert(8);
dd.insert(9);
dd.insert(1);
Binary_tree<int> ww;
ww = dd;
ww.insert(10);
ww.insert(7);
cout<<"preorder:";
dd.preorder(print);
cout<<endl;
cout<<"preorder:";
ww.preorder(print);
cout<<endl;
dd.reverse();
cout<<"preorder:";
dd.preorder(print);
cout<<endl;
system("pause");
return 0;
}
void print( int& x)
{
cout<<x<<" ";
}
二叉树的基本知识
最新推荐文章于 2020-09-15 17:40:50 发布