一直以来对树稍微存在一点儿恐惧感,最近打算好好顺一顺数据结构,于是从二叉树开始对树进行研究。这个方法主要参考殷人昆第二版的数据结构(清华大学出版社第二版)。实现也都是用模板,后来的实例是用char型。其中涉及到友员函数和操作符重载的使用,这一块有点儿忘了,就当复习了一下。
/*********************************
date:2014.5.10
author:andrew
**********************************/
//BinTree.h
#include<iostream>
using namespace std;
template<class T>
//definition of the node of binary tree
struct BinTreeNode
{
T data; //data
BinTreeNode<T>* lChild, *rChild; //pointer points to left child and right child
BinTreeNode() :lChild(NULL), rChild(NULL){};//constructor
BinTreeNode(T d, BinTreeNode<T> *l=NULL, BinTreeNode<T>*r=NULL)
{
data = d;
lChild = l;
rChild=r;
}
};
template<class T>
//class definition
class BinTree
{
public:
BinTree() :root(NULL){}
BinTree(T data)
{
value = data;
root = NULL;
}
~BinTree()
{
destroy(root);
}
int Size()
{
return Size(root);
}
bool isEmpty()
{
return (root == NULL) ? true : false;
}
BinTreeNode<T> *Parent(BinTreeNode<T> *current)
{
return (root == NULL || current == root) ? NULL : Parent(root,current);
}
BinTree<T> *LeftChild(BinTreeNode<T> *current)
{
return (current != NULL) ? current->lChild : NULL;
}
BinTree<T> *RightChild(BinTreeNode<T> *current)
{
return (current != NULL) ? current->rChild : NULL;
}
BinTreeNode<T> *getRoot()
{
return root;
}
void CreateBinTree(istream& in,BinTreeNode<char> *subtree);
private:
BinTreeNode<T> *root;
T value;
void destroy(BinTreeNode<T> *subTree);
BinTreeNode<T> *Parent(BinTreeNode<T>*subTree,BinTreeNode<T>*current);
public:
void Traverse(BinTreeNode<T> *subTree, ostream& out);
friend istream& operator>>(istream& in,BinTree<char>& Tree);
friend ostream& operator<<(ostream& out, BinTree<char>& Tree);
};
//BinTree.cpp
#include"BinTree.h"
#include<iostream>
#include<stack>
using namespace std;
template<class T>
void BinTree<T>::destroy(BinTreeNode<T> *subTree)
{
if (subTree != NULL)
{
destroy(subTree->lChild); //delete left subTree recucively
destroy(subTree->rChild); //delete right subTree recucively
delete subTree;
}
}
template<class T>
BinTreeNode<T> *BinTree<T>::Parent(BinTreeNode<T> *subTree, BinTreeNode<T> *current)
{
if (subTree == NULL)
return NULL;
if (subTree->lChild == current || subTree->rChild == current)
return subTree;
return Parent(subTree->lChild, current);
return Parent(subTree->rChild, current);
}
//create binary tree using generalized list
void CreateBinTree(istream& in, BinTreeNode<char> *&subTree)
{
stack<BinTreeNode<char> *>s;
subTree = NULL;
BinTreeNode<char> *p, *t;
int k; //tag,1 for left,2 for right
int count = 0; //index of string,point to the current handling
char ch;
in >> ch;
while (ch != '#')
{
switch (ch)
{
case '(':
{
s.push(p);
k = 1;
break;
}
case ')':
{
t = s.top();
s.pop();
break;
}
case ',':
{
k = 2;
break;
}
default:
{
p = new BinTreeNode<char>(ch);
if (subTree == NULL)
subTree = p;
else if (k == 1)
{
t = s.top();
t->lChild = p;
}
else
{
t = s.top();
t->rChild = p;
}
}
}
in >> ch;
}
cout << "Create successfully!" << endl;
}
template<class T>
void BinTree<T>::Traverse(BinTreeNode<T>*subTree, ostream&out)
{
if (subTree != NULL)
{
out << subTree->data << " ";
Traverse(subTree->lChild, out);
Traverse(subTree->rChild, out);
}
}
//template<class T>
istream& operator>>(istream& in, BinTree<char>&Tree)
{
CreateBinTree(in, Tree.root);
return in;
}
//template<class T>
ostream& operator<< (ostream&out, BinTree<char>&Tree)
{
out << "Traverse the binary tree:" << endl;
Tree.Traverse(Tree.root, out);
out << endl;
return out;
}
int main()
{
BinTree<char> bintree;
BinTreeNode<char> *bTreeNode = NULL;
cout << "Input generalized list,end with#:" << endl;
cin >> bintree;
cout << bintree;
return 0;
}
测试结果: