64,648
社区成员
发帖
与我相关
我的任务
分享
#ifndef TREE_NODE_H
#define TREE_NODE_H
/**
Forward declaration
*/
template <typename T>
class BSTree;
template <typename T>
class TreeNode;
/**
StackNode Interface
*/
template <typename T>
class TreeNode {
public:
inline TreeNode( const T& nData ) : data(nData) , left(0) , right(0) {} // <-- Do nothing.
inline T get_value() const { return data; }
friend class BSTree<T>;
private:
T data;
TreeNode<T>* left;
TreeNode<T>* right;
};
#endif
#ifndef HOMEMADE_BST_H
#define HOMEMADE_BST_H
#include "tree_node.h"
#include <iostream>
#include <cstdlib>
#include <vector>
using std::ostream;
using std::vector;
using std::endl;
using std::size_t;
/**
Function declarations
*/
template <typename T>
ostream& operator<<( ostream&, const BSTree<T>& );
/**
Stack Interface
*/
template <typename T>
class BSTree {
public:
/**
Other member functions
*/
inline bool is_empty() const
{ return ( root == 0 ); }
inline TreeNode<T>* get_root() const
{ return root; }
inline TreeNode<T>* find_maximum( TreeNode<T>* pos ) const
{ while ( pos->right ) pos = pos->right; return pos; }
inline TreeNode<T>* find_minimum( TreeNode<T>* pos ) const
{ while ( pos->left ) pos = pos->left; return pos; }
inline TreeNode<T>* find_maximum() const
{ return find_maximum(root); }
inline TreeNode<T>* find_minimum() const
{ return find_minimum(root); }
TreeNode<T>* next_in_order( TreeNode<T>* pos ) const;
bool operator==( const BSTree<T>& b ) const ;
inline bool operator!=( const BSTree<T>& b ) const
{ return !( *this == b );}
void pre_order( TreeNode<T>* localRoot , ostream& out ) const;
void pre_order( ostream& out ) const
{ pre_order(root, out); }
void pre_order_push( TreeNode<T>* localRoot , vector<T>& v ) const;
void to_vector( TreeNode<T>* localRoot , vector<T>& v ) const ;
void to_vector( vector<T>& v ) const
{ to_vector(root, v); }
private:
// Common statements in: copy constr. & operator=
void deep_copy( TreeNode<T>* nodeInSourceTree );
TreeNode<T>* root;
};
template <typename T>
TreeNode<T>* BSTree<T>::next_in_order( TreeNode<T>* pos ) const {
// case 1
if ( pos->right )
return find_minimum(pos->right);
// case 2
TreeNode<T>* parentNode = get_parent(pos);
while ( parentNode ){
// If moving right (i.e., pos is the left child), done.
if ( parentNode->left == pos )
return parentNode;
// If not, keep moving up
pos = parentNode;
parentNode = get_parent(parentNode);
}
return 0; // <-- Only reach this part if there is no next in order.
}
template <typename T>
void BSTree<T>::pre_order( TreeNode<T>* localRoot , ostream& out ) const {
if ( localRoot ){
out << localRoot->data << " ";
pre_order(localRoot->left,out);
pre_order(localRoot->right,out);
}
return;
}
template <typename T>
void BSTree<T>::deep_copy( TreeNode<T>* nodeInSourceTree ){
if ( nodeInSourceTree ){
insert( nodeInSourceTree->data );
deep_copy( nodeInSourceTree->left );
deep_copy( nodeInSourceTree->right );
}
return;
}
/**
THIS IS THE PLACE WHERE YOU SHOULD PLACE YOUT CODE
*/
template <typename T>
void BSTree<T>::pre_order_push( TreeNode<T>* localRoot , vector<T>& v ) const {
if ( localRoot ){
v.push_back(localRoot->data);
pre_order_push(localRoot->left,v);
pre_order_push(localRoot->right,v);
}
return;
}
template <typename T>
bool BSTree<T>::operator==( const BSTree<T>& param1 ) const {
TreeNode<T>* localRoot = this->root;
TreeNode<T>* param1Root = param1.get_root();
TreeNode<T>* localMin = find_minimum(this->root);
TreeNode<T>* param1Min = param1.find_minimum();
if (localRoot != param1Root) {
return false;
}
while (localMin == param1Min) {
if (localMin->data == 10) {
return true;
}
localMin = next_in_order(localMin);
param1Min = next_in_order(param1Min);
}
}
template <typename T>
void BSTree<T>::to_vector( TreeNode<T>* param1 , vector<T>& param2 ) const {
pre_order_push(param1, param2);
return;
}
template <typename T>
ostream& operator<<( ostream& param1 , const BSTree<T>& param2 ) {
TreeNode<T>* localRoot = param2.get_root();
if ( localRoot ) {
param2.pre_order( localRoot, param1);
}
param1 << endl;
return param1;
}
#endif
/**
THIS IS THE PLACE WHERE YOU SHOULD PLACE YOUT CODE
*/
template <typename T>
void BSTree<T>::pre_order_push( TreeNode<T>* localRoot , vector<T>& v ) const {
if ( localRoot ){
v.push_back(localRoot->data);
pre_order_push(localRoot->left,v);
pre_order_push(localRoot->right,v);
}
return;
}
template <typename T>
bool BSTree<T>::pre_order_bool( TreeNode<T>* localRoot , TreeNode<T>* param1Root ) const {
if ( localRoot && param1Root ){
if (localRoot->data != param1Root->data) return false;
if (pre_order_bool(localRoot->left,param1Root->left) && pre_order_bool(localRoot->right,param1Root->right)) return true;
}
}
template <typename T>
bool BSTree<T>::operator==( const BSTree<T>& param1 ) const {
return pre_order_bool(root,param1.get_root());
}
template <typename T>
void BSTree<T>::to_vector( TreeNode<T>* param1 , vector<T>& param2 ) const {
pre_order_push(param1, param2);
return;
}
template <typename T>
ostream& operator<<( ostream& param1 , const BSTree<T>& param2 ) {
TreeNode<T>* localRoot = param2.get_root();
if ( localRoot ) {
param2.pre_order( localRoot, param1);
}
param1 << endl;
return param1;
}
我是写了另一个方程然后把operator==超载弄好了的..
我是假设2个二叉树,如果他们相同的话那么就是数据和形状都相同,然后我换了一个想法,那就是他们的pre order的顺序是一样的.. 我的operator==就是基于他们有相同的pre order写的..
所以新加的方程的名字叫pre_order_bool (没有写注释是我懒了不好意思...)
但是老师说如果要新加方程的话最好写成非成员函数... 可是我想了好久还是只能写成成员函数.. 所以我想大神们帮我看下怎么弄成非成员函数...
就是把我那2个pre_order_bool和pre_order_push都改成非成员函数...[/quote]你的operator<<怎么弄成非成员的呢?照着这个思路就可以了。/**
THIS IS THE PLACE WHERE YOU SHOULD PLACE YOUT CODE
*/
template <typename T>
void BSTree<T>::pre_order_push( TreeNode<T>* localRoot , vector<T>& v ) const {
if ( localRoot ){
v.push_back(localRoot->data);
pre_order_push(localRoot->left,v);
pre_order_push(localRoot->right,v);
}
return;
}
template <typename T>
bool BSTree<T>::pre_order_bool( TreeNode<T>* localRoot , TreeNode<T>* param1Root ) const {
if ( localRoot && param1Root ){
if (localRoot->data != param1Root->data) return false;
if (pre_order_bool(localRoot->left,param1Root->left) && pre_order_bool(localRoot->right,param1Root->right)) return true;
}
}
template <typename T>
bool BSTree<T>::operator==( const BSTree<T>& param1 ) const {
return pre_order_bool(root,param1.get_root());
}
template <typename T>
void BSTree<T>::to_vector( TreeNode<T>* param1 , vector<T>& param2 ) const {
pre_order_push(param1, param2);
return;
}
template <typename T>
ostream& operator<<( ostream& param1 , const BSTree<T>& param2 ) {
TreeNode<T>* localRoot = param2.get_root();
if ( localRoot ) {
param2.pre_order( localRoot, param1);
}
param1 << endl;
return param1;
}
我是写了另一个方程然后把operator==超载弄好了的..
我是假设2个二叉树,如果他们相同的话那么就是数据和形状都相同,然后我换了一个想法,那就是他们的pre order的顺序是一样的.. 我的operator==就是基于他们有相同的pre order写的..
所以新加的方程的名字叫pre_order_bool (没有写注释是我懒了不好意思...)
但是老师说如果要新加方程的话最好写成非成员函数... 可是我想了好久还是只能写成成员函数.. 所以我想大神们帮我看下怎么弄成非成员函数...
就是把我那2个pre_order_bool和pre_order_push都改成非成员函数...template <typename T>
void BSTree<T>::pre_order_push( TreeNode<T>* localRoot , vector<T>& v ) const {
if ( localRoot ){
v.push_back(localRoot->data);
pre_order_push(localRoot->left,v);
pre_order_push(localRoot->right,v);
}
return;
}
template <typename T>
bool BSTree<T>::pre_order_bool( TreeNode<T>* localRoot , TreeNode<T>* param1Root ) const {
if ( localRoot && param1Root ){
if (localRoot->data != param1Root->data) return false;
if (pre_order_bool(localRoot->left,param1Root->left) && pre_order_bool(localRoot->right,param1Root->right)) return true;
}
}
#include <iostream>
#include <stack>
#include <queue>
#include <locale.h>
using namespace std;
typedef struct BiTNode {//二叉树结点
char data; //数据
struct BiTNode *lchild,*rchild; //左右孩子指针
} BiTNode,*BiTree;
int CreateBiTree(BiTree &T) {//按先序序列创建二叉树
char data;
scanf("%c",&data);//按先序次序输入二叉树中结点的值(一个字符),‘#’表示空树
if (data == '#') {
T = NULL;
} else {
T = (BiTree)malloc(sizeof(BiTNode));
T->data = data; //生成根结点
CreateBiTree(T->lchild);//构造左子树
CreateBiTree(T->rchild);//构造右子树
}
return 0;
}
void Visit(BiTree T) {//输出
if (T->data != '#') {
printf("%c ",T->data);
}
}
void PreOrder(BiTree T) {//先序遍历
if (T != NULL) {
Visit(T); //访问根节点
PreOrder(T->lchild); //访问左子结点
PreOrder(T->rchild); //访问右子结点
}
}
void InOrder(BiTree T) {//中序遍历
if (T != NULL) {
InOrder(T->lchild); //访问左子结点
Visit(T); //访问根节点
InOrder(T->rchild); //访问右子结点
}
}
void PostOrder(BiTree T) {//后序遍历
if (T != NULL) {
PostOrder(T->lchild); //访问左子结点
PostOrder(T->rchild); //访问右子结点
Visit(T); //访问根节点
}
}
void PreOrder2(BiTree T) {//先序遍历(非递归)
//访问T->data后,将T入栈,遍历左子树;遍历完左子树返回时,栈顶元素应为T,出栈,再先序遍历T的右子树。
stack<BiTree> stack;
BiTree p = T;//p是遍历指针
while (p || !stack.empty()) { //栈不空或者p不空时循环
if (p != NULL) {
stack.push(p); //存入栈中
printf("%c ",p->data); //访问根节点
p = p->lchild; //遍历左子树
} else {
p = stack.top(); //退栈
stack.pop();
p = p->rchild; //访问右子树
}
}
}
void InOrder2(BiTree T) {//中序遍历(非递归)
//T是要遍历树的根指针,中序遍历要求在遍历完左子树后,访问根,再遍历右子树。
//先将T入栈,遍历左子树;遍历完左子树返回时,栈顶元素应为T,出栈,访问T->data,再中序遍历T的右子树。
stack<BiTree> stack;
BiTree p = T;//p是遍历指针
while (p || !stack.empty()) { //栈不空或者p不空时循环
if (p != NULL) {
stack.push(p); //存入栈中
p = p->lchild; //遍历左子树
} else {
p = stack.top(); //退栈,访问根节点
printf("%c ",p->data);
stack.pop();
p = p->rchild; //访问右子树
}
}
}
typedef struct BiTNodePost{
BiTree biTree;
char tag;
} BiTNodePost,*BiTreePost;
void PostOrder2(BiTree T) {//后序遍历(非递归)
stack<BiTreePost> stack;
BiTree p = T;//p是遍历指针
BiTreePost BT;
while (p != NULL || !stack.empty()) {//栈不空或者p不空时循环
while (p != NULL) {//遍历左子树
BT = (BiTreePost)malloc(sizeof(BiTNodePost));
BT->biTree = p;
BT->tag = 'L';//访问过左子树
stack.push(BT);
p = p->lchild;
}
while (!stack.empty() && (stack.top())->tag == 'R') {//左右子树访问完毕访问根节点
BT = stack.top();
stack.pop();//退栈
printf("%c ",BT->biTree->data);
}
if (!stack.empty()) {//遍历右子树
BT = stack.top();
BT->tag = 'R';//访问过右子树
p = BT->biTree;
p = p->rchild;
}
}
}
void LevelOrder(BiTree T) {//层次遍历
if (T == NULL) return;
BiTree p = T;
queue<BiTree> queue;//队列
queue.push(p);//根节点入队
while (!queue.empty()) { //队列不空循环
p = queue.front(); //对头元素出队
printf("%c ",p->data); //访问p指向的结点
queue.pop(); //退出队列
if (p->lchild != NULL) {//左子树不空,将左子树入队
queue.push(p->lchild);
}
if (p->rchild != NULL) {//右子树不空,将右子树入队
queue.push(p->rchild);
}
}
}
int main() {
BiTree T;
setlocale(LC_ALL,"chs");
CreateBiTree(T);
printf("先序遍历 :");PreOrder (T);printf("\n");
printf("先序遍历(非递归):");PreOrder2 (T);printf("\n");
printf("\n");
printf("中序遍历 :");InOrder (T);printf("\n");
printf("中序遍历(非递归):");InOrder2 (T);printf("\n");
printf("\n");
printf("后序遍历 :");PostOrder (T);printf("\n");
printf("后序遍历(非递归):");PostOrder2(T);printf("\n");
printf("\n");
printf("层次遍历 :");LevelOrder(T);printf("\n");
return 0;
}
//ABC##DE#G##F###
//先序遍历 :A B C D E G F
//先序遍历(非递归):A B C D E G F
//
//中序遍历 :C B E G D F A
//中序遍历(非递归):C B E G D F A
//
//后序遍历 :C G E F D B A
//后序遍历(非递归):C G E F D B A
//
//层次遍历 :A B C D E F G
//
/// A
/// /
/// B
/// / \
/// C D
/// / \
/// E F
/// \
/// G
/**
May 28, 2015.
Ricardo Salazar
A driver for our homemade Binary Search Tree class
*/
#include "bst.h"
#include <iostream>
#include <cstdlib>
#include <vector>
#include <ctime>
using std::cout;
using std::endl;
using std::vector;
// shuffles numbers from 1 to n
void shuffleVector( vector<int>& );
/**
Shuffles a vector with n entries.
The algorithm:
- For every index from 1 to n
Generate random index r between 1 and n
Exchange elements v[i] and v[r].
*/
void shuffleVector( vector<int>& v ){
for ( int i=0 ; i < v.size() ; i++ ){
int j = rand() % v.size() ; // <-- New random position
int temp = v[i];
v[i] = v[j];
v[j] = temp;
}
}
/**
Main routine
*/
int main(){
const int FORREST_SIZE = 3;
const int MAX_NODES = 10;
long int startingTime = static_cast<long int>( time( NULL ) );
srand( startingTime );
// A vector of trees!!! ( a forrest )
vector< BSTree<int> > forrest;
cout << "The forrest will be populated by turning the following\n"
<< "sequences of random numbers into Binary Search Trees:" << endl;
for ( int k = 0 ; k < FORREST_SIZE ; k ++ ) {
vector<int> v(MAX_NODES);
// populate the vector with numbers from 1 to MAX_NODES
for (int i=0 ; i < v.size() ; i ++ )
v[i] = i+1;
// shuffle the vector
shuffleVector( v );
// Generate a BST with the elements of v
BSTree<int> tree;
for (int i=0 ; i < v.size() ; i ++ ){
cout << v[i] << " ";
tree.insert(v[i]);
}
cout << endl;
// Add tree to forrest
forrest.push_back(tree);
}
cout << endl;
// Display statistics: heights of the trees
for ( int i = 0 ; i < forrest.size() ; i++ ){
cout << "Tree " << i+1 << " has height: "
<< forrest[i].height() << endl;
}
// Display first tree using operator<<
cout << "\nThree 1 as a vector..." << endl;
cout << forrest[0] ;
// Testing operator !=
if ( forrest[0] != forrest[1] )
cout << "Trees 1 and 2 are not equal." << endl;
// Convert first tree into a vector. Needed to test == below
vector<int> v;
forrest[0].to_vector(v);
// Reconsutruct copy of first tree from its vector representation
BSTree<int> phoenix_tree; // <-- back to life from its ashes...
for ( int i = 0 ; i < v.size() ; i++ )
phoenix_tree.insert(v[i]);
// Testing operator ==
if ( forrest[0] == phoenix_tree )
cout << "1st tree equals its reconstruction." << endl;
// Some statistics about the running time
cout << "\nProgram ran in: "
<< static_cast<long int>( time( NULL ) ) - startingTime
<< " seconds" << endl ;
return 0;
}