#ifndef _H_BIN_TREE_H_
#define _H_BIN_TREE_H_
#include <stack>
#include <queue>
#include <iostream>
#include <fstream>
using namespace std;
#include "ADTBinTree.h"
template <class T>
class BinTree : public ADTBinTree<T>
{
public:
BinTree(const char *file=0);
~BinTree()
{
if(root)
{
clear();
root = 0;
}
}
void clear() // 清空
{
if(root)
{
clear(root); //递归
// clear(0); //迭代
root = 0;
}
}
bool empty() const { return !root; } // 判空
int height() const // 二叉树的高度
{
return root ? height(root) : 0; //递归
// return root ? height(0) : 0; //迭代
}
int size() const // 二叉树的结点总数
{
return root ? size(root) : 0; //递归
// return root ? size(0) : 0; //迭代
}
int leaf() const // 二叉树的叶节点总数
{
return root ? leaf(root) : 0; //递归
// return root ? leaf(0) : 0; //迭代
}
void preOrderTraverse() const // 前序遍历
{
if(root)
preOrderTraverse(root); //递归
// preOrderTraverse(0); //迭代
else cout<<"这是一棵空树";
cout<<endl;
}
void midOrderTraverse() const // 中序遍历
{
if(root)
midOrderTraverse(root); //递归
// midOrderTraverse(0); //迭代
else cout<<"这是一棵空树";
cout<<endl;
}
void postOrderTraverse() const // 后序遍历
{
if(root)
postOrderTraverse(root); //递归
// postOrderTraverse(0); //迭代
else cout<<"这是一棵空树";
cout<<endl;
}
void levelOrderTraverse() const;// 层次遍历
private:
struct Node{
T data;
Node *left;
Node *right;
Node() : left(0), right(0) { }
Node(const T &val, Node *l=0, Node *r=0) : left(l), right(r)
{
data = val;
}
};
struct QElem{
Node *node;
int level;
QElem(Node *p=0, int k=1)
: node(p), level(k) { }
};
//定义区分左右孩子的枚举类型
enum CHILD{
LCHILD, RCHILD
};
//声明栈的元素类型
struct SElem{
Node *node;
CHILD type;
SElem(Node *p=0, CHILD t=LCHILD)
: node(p), type(t) {}
};
void clear(const Node *p); // 清空, 递归
int height(const Node *p) const; // 二叉树的高度, 递归和迭代
int size(const Node *p) const; // 二叉树的结点总数, 递归和迭代
int leaf(const Node *p) const; // 二叉树的叶节点总数
void preOrderTraverse(const Node *p) const; // 前序遍历, 递归和迭代
void midOrderTraverse(const Node *p) const; // 中序遍历, 递归和迭代
void postOrderTraverse(const Node *p) const; // 后序遍历, 递归和迭代
Node *root;
};
template <class T>
//m为最后一个叶结点的编号,n为节点数量
BinTree<T>::BinTree(const char *file): root(0)
{
if(file)
{
ifstream fin(file);
//m为最后一个叶结点的编号,n为节点数量
int m, n, i, j;
T val;
fin>>m>>n;
int *idx = new int[m+1];
Node **node = new Node*[n];
for(i=0; i<=m; i++) idx[i] = -1;
for(i=0; i<n; i++) node[i] = 0;
for(i=0; i<n; i++)
{
fin>>j;
idx[j] = i;
fin>>val;
node[i] = new Node(val);
}
i = 1;
while(2*i<=m)
{
if(-1 != idx[i])
{
if(-1!=idx[2*i])node[idx[i]]->left = node[idx[2*i]];
if(2*i<m && -1!=idx[2*i+1]) node[idx[i]]->right = node[idx[2*i+1]];
}
i++;
}
root = node[idx[1]];
delete [] idx;
delete [] node;
}
}
template <class T>
void BinTree<T>::preOrderTraverse(const Node *p) const
{
if(p) //递归
{
cout<<p->data<<' ';
preOrderTraverse(p->left);
preOrderTraverse(p->right);
}
else if(root) //迭代
{
//递归消除需要使用辅助的栈对象
stack<Node*> s;
s.push(root);
while(!s.empty())
{
//注意:stack的pop不返回栈顶元素
//所以要用top函数首先获取栈顶元素
Node *q = s.top();
s.pop();
cout<<q->data<<'\t';
if(q->right) s.push(q->right);
if(q->left) s.push(q->left);
}
}
}
template <class T>
void BinTree<T>::midOrderTraverse(const Node *p) const
{
if(p) //递归
{
midOrderTraverse(p->left);
cout << p->data << ' ';
midOrderTraverse(p->right);
}
else if(root) //迭代
{
//递归消除需要使用辅助的栈对象
stack<Node*> s;
Node *q = root;
while(!s.empty() || q)
{
if(q)
{
s.push(q);
//如果有左孩子,让左孩子先入栈进行中序遍历
q = q->left;
}
//否则,输出子树根节点,再将右孩子入栈进行中序遍历
else
{
q = s.top();
s.pop();
cout<<q->data<<'\t';
q = q->right;
}
}
}
}
template <class T>
void BinTree<T>::postOrderTraverse(const Node *p) const
{
if(p) //递归
{
postOrderTraverse(p->left);
postOrderTraverse(p->right);
cout << p->data << ' ';
}
else if(root) //迭代
{
// //定义区分左右孩子的枚举类型
// enum CHILD{
// LCHILD, RCHILD
// };
// //声明栈的元素类型
// struct SElem{
// Node *node;
// CHILD type;
// SElem(Node *p=0, CHILD t=LCHILD)
// : node(p), type(t) {}
// };
//递归消除需要使用辅助的栈对象
stack<SElem> s;
s.push(SElem(root));
while(!s.empty())
{
//注意:stack的pop不返回栈顶元素
//所以要用top函数首先获取栈顶元素
SElem q = s.top();
if(LCHILD==q.type)
if(q.node->left) s.push(SElem(q.node->left));
else
{
s.top().type = RCHILD;
if(q.node->right) s.push(SElem(q.node->right));
}
else
{
cout<<q.node->data<<'\t';
s.pop();
q = s.top();
if(!s.empty() && LCHILD == q.type)
{
q.type = RCHILD;
if(q.node->right)
s.push(SElem(q.node->right));
}
}
}
}
}
template <class T>
void BinTree<T>::levelOrderTraverse() const
{
if(root)
{
queue<Node*>que;
Node* q = root;
if (q) que.push(q);
while (!que.empty()) {
q = que.front();
que.pop();
cout << q->data << ' ';
if (q->left != NULL) que.push(q->left);
if (q->right != NULL) que.push(q->right);
}
}
else cout<<"这是一棵空树";
cout<<endl;
}
template <class T>
void BinTree<T>::clear(const Node *p) // 清空
{
if(p) //递归
{
if(p->left) clear(p->left);
if (p->right) clear(p->right);
delete p;
}
else if(root) //迭代,类似前序遍历
{
//递归消除需要使用辅助的栈对象
stack<Node *> s;
s.push(root);
while(!s.empty())
{
//注意:stack的pop不返回栈顶元素
//所以要用top函数首先获取栈顶元素
Node *p = s.top();
s.pop();
if(p->right) s.push(p->right);
if(p->left) s.push(p->left);
delete p;
}
}
}
template <class T>
int BinTree<T>::height(const Node *p) const
{
if(p) //递归
{
int lh=height(p->left),rh=height(p->right);
return 1 + ((lh > rh) ? lh : rh);
}
else if(root) //迭代,类似广度优先算法,也可以用前序遍历
{
// struct QElem{
// Node *node;
// int level;
// QElem(Node *p=0, int k=1)
// : node(p), level(k) { }
// };
int k = 1, t;
queue<QElem> que;
que.push(QElem(root, k));
while(!que.empty())
{
QElem q = que.front();
que.pop();
t = q.level + 1;
if(q.node->left) que.push(QElem(q.node->left, t));
if(q.node->right) que.push(QElem(q.node->right, t));
if(que.back().level > k) k = t;
}
return k;
}
else return 0;
}
template <class T>
int BinTree<T>::size(const Node *p) const
{
if(p) //递归
{
return 1+size(p->left)+size(p->right);
}
else if(root) // 迭代,类似前序遍历
{
int num = 0;
stack<Node *> s;
s.push(root);
while(!s.empty())
{
//注意:stack的pop不返回栈顶元素
//所以要用top函数首先获取栈顶元素
Node *p = s.top();
s.pop();
num ++;
if(p->right) s.push(p->right);
if(p->left) s.push(p->left);
}
return num;
}
else return 0;
}
template <class T>
int BinTree<T>::leaf(const Node *p) const
{
if(p) //递归
{
if ((p->left == NULL) && (p->right == NULL))return 1;
else return leaf(p->left) + leaf(p->right);
}
else if(root) // 迭代,类似前序遍历
{
int num = 0;
stack<Node *> s;
s.push(root);
while(!s.empty())
{
//注意:stack的pop不返回栈顶元素
//所以要用top函数首先获取栈顶元素
Node *p = s.top();
s.pop();
if(!p->right && !p->left) num++;
else
{
if(p->right) s.push(p->right);
if(p->left) s.push(p->left);
}
}
return num;
}
else return 0;
}
#endif
这得调试代码才知道了。你点击重试看看断点在哪,要找到断点的根源,根源就是指到底指向你的哪行代码
内存异常啦。你看看哪里指针内存收回了,但是程序还在操作这个地址。