c++二叉树的建立、前序中序后序深搜、宽搜、宽搜带行号
来源:互联网 发布:微信小程序php实例 编辑:程序博客网 时间:2024/04/29 22:46
c++中用模板类建立树的抽象结构要注意c++中的类模板不能实现分离编译,即定义在.h文件,实现在.cpp文件,因此要将定义和实现都写在.h文件中
原因见:http://blog.csdn.net/pongba/article/details/19130
输入的树形为:
输入文件内容为:
A B D G # # H # # E # # C K # # F I # J # # #
输出的结果为:(前序,中序,后序,层序,以及按层号输出)
A B D G H E C K F I J
G D H B E A K C I J F
G H D E B K J I F C A
A B C D E K F G H I J
A
B C
D E K F
G H I
J
.h文件中代码如下,都是非递归的方式实现宽搜和深搜:
//
// Created by Alina on 16/3/11.
//
#ifndef FORJOB_BINARYTREE_H
#define FORJOB_BINARYTREE_H
#include <iostream>
#include <fstream>
#include <queue>
#include <stack>
// Created by Alina on 16/3/11.
//
#ifndef FORJOB_BINARYTREE_H
#define FORJOB_BINARYTREE_H
#include <iostream>
#include <fstream>
#include <queue>
#include <stack>
using namespace std;
//freopen("/Users/Alina/ClionProjects/Tree/input/tree","r",stdin);
template <class T>class BinaryTree;
template <class T>
class BinaryTreeNode{
T data;
BinaryTreeNode<T> * leftchild;
BinaryTreeNode<T> * rightchild;
friend class BinaryTree<T>;//设置友元类,可以访问当前类的私有成员
public:
BinaryTreeNode(T d,BinaryTreeNode<T> *l,BinaryTreeNode<T> *r):data(d),leftchild(l),rightchild(r){}
BinaryTreeNode();
};
template <class T>
class BinaryTree {
BinaryTreeNode<T> *root;
int size;
public:
BinaryTree();
BinaryTree(BinaryTreeNode<T> *curnode);//用前序扩展树的方式读入,空孩子用#代替
~BinaryTree();
const BinaryTreeNode<T> & GetRoot() const;
T * PreOrderVisit();//前序遍历,非递归
T * MidOrderVisit();//中序遍历,非递归
T * PostOrderVisit();//后序遍历,非递归
T * LevelOrder();//层序遍历,非递归
T * LevelOrderWithLineNum();//层序遍历并按层输出,非递归
void PrintTree();
int GetNodeNum();//树中非空的节点个数
int GetTreeDepth();//获得树深度
private:
void CreateTree(BinaryTreeNode<T> *&curnode);
void DropTree(BinaryTreeNode<T> *&curnode);
void PrintNode(BinaryTreeNode<T> *& curnode);
int CalculateDepth(BinaryTreeNode<T> *curnode);
};
template <class T>
BinaryTree<T>::BinaryTree() {
template <class T>
class BinaryTreeNode{
T data;
BinaryTreeNode<T> * leftchild;
BinaryTreeNode<T> * rightchild;
friend class BinaryTree<T>;//设置友元类,可以访问当前类的私有成员
public:
BinaryTreeNode(T d,BinaryTreeNode<T> *l,BinaryTreeNode<T> *r):data(d),leftchild(l),rightchild(r){}
BinaryTreeNode();
};
template <class T>
class BinaryTree {
BinaryTreeNode<T> *root;
int size;
public:
BinaryTree();
BinaryTree(BinaryTreeNode<T> *curnode);//用前序扩展树的方式读入,空孩子用#代替
~BinaryTree();
const BinaryTreeNode<T> & GetRoot() const;
T * PreOrderVisit();//前序遍历,非递归
T * MidOrderVisit();//中序遍历,非递归
T * PostOrderVisit();//后序遍历,非递归
T * LevelOrder();//层序遍历,非递归
T * LevelOrderWithLineNum();//层序遍历并按层输出,非递归
void PrintTree();
int GetNodeNum();//树中非空的节点个数
int GetTreeDepth();//获得树深度
private:
void CreateTree(BinaryTreeNode<T> *&curnode);
void DropTree(BinaryTreeNode<T> *&curnode);
void PrintNode(BinaryTreeNode<T> *& curnode);
int CalculateDepth(BinaryTreeNode<T> *curnode);
};
template <class T>
BinaryTree<T>::BinaryTree() {
// ifstream cin("/Users/Alina/ClionProjects/Tree/input/tree");
size = 0;
CreateTree(root);
}
template <class T>
BinaryTree<T>::BinaryTree(BinaryTreeNode<T> *curnode) {
root = curnode;
}
template <class T>
void BinaryTree<T>::CreateTree(BinaryTreeNode<T> *&curnode) {
T data;
if(cin>>data){
if(data != "#") {
size++;
curnode = new BinaryTreeNode<T>(data, NULL, NULL);
if (curnode) {
CreateTree(curnode->leftchild);
CreateTree(curnode->rightchild);
}
else {
cerr << "tree node initialize error!" << endl;
}
}
}
}
template <class T>
BinaryTree<T>::~BinaryTree() {
DropTree(root);
}
template <class T>
void BinaryTree<T>::DropTree(BinaryTreeNode<T> *&curnode) {
if(curnode){
DropTree(curnode->leftchild);
DropTree(curnode->rightchild);
delete curnode;
}
}
template <class T>
const BinaryTreeNode<T> & BinaryTree<T>::GetRoot() const {
return *root;
}
template <class T>
T * BinaryTree<T>::LevelOrder() {//弹出对头节点,如果当前节点有孩子就把孩子入队
T * result = new T[size+1];
queue<BinaryTreeNode<T>*> q;
if(!root){
return NULL;
}else {
BinaryTreeNode<T>* cur;
int i = 0;
q.push(root);
while (!q.empty()) {
cur = q.front();
if (cur->leftchild) {
q.push(cur->leftchild);
}
if (cur->rightchild) {
q.push(cur->rightchild);
}
q.pop();
result[i] = cur->data;
i++;
}
return result;
}
}
template <class T>
T* BinaryTree<T>::LevelOrderWithLineNum() {
//和上面的区别在于需要两个指针记录当前层的最后一个,以及更新下一层的最后一个节点
//当当前层的最后一个节点被弹出时,该节点的右孩子就是下一层的最后一个节点,此时将当前层last指针指向下一层的last指针
int depth = GetTreeDepth();
T * result = new T[size+depth];
queue<BinaryTreeNode<T> *> q;
if(!root){
return NULL;
}else{
BinaryTreeNode<T> * cur;
BinaryTreeNode<T> * levellast;
BinaryTreeNode<T> * templevellast;
q.push(root);
levellast = root;
int i = 0;
while(!q.empty()){
cur = q.front();
result[i] = cur->data;
i++;
if(cur->leftchild){
q.push(cur->leftchild);
templevellast = cur->leftchild;
}
if(cur->rightchild){
q.push(cur->rightchild);
templevellast = cur->rightchild;
}
if(cur == levellast){
result[i] = "#";
i++;
levellast = templevellast;
}
q.pop();
}
return result;
}
}
template <class T>
T * BinaryTree<T>::PreOrderVisit() {//弹出栈顶节点,如果有右孩子,右孩子进栈,指针指向左孩子
if(!root){
return NULL;
}else{
T * result = new T[size+1];
stack<BinaryTreeNode<T> *> s;
BinaryTreeNode<T> * cur;
s.push(root);
int i = 0;
while(!s.empty()){
cur = s.top();
s.pop();
while(cur){
result[i] = cur->data;
i++;
if(cur->rightchild){
s.push(cur->rightchild);
}
if (cur->leftchild){
cur = cur->leftchild;
}else{
cur = NULL;
}
}
}
return result;
}
}
template <class T>
T * BinaryTree<T>::MidOrderVisit() {//不断将当前节点入栈,深入左子树,左不下去时弹出栈顶元素,深入右子树
if(!root){
return NULL;
}else{
T *result = new T[size+1];
stack<BinaryTreeNode<T>*> s;
BinaryTreeNode<T> * cur;
cur = root;
int i = 0;
while(cur||!s.empty()){
while(cur){
s.push(cur);
cur = cur->leftchild;
}
if(!s.empty()){
cur = s.top();
s.pop();
result[i] = cur->data;
i++;
cur = cur->rightchild;
}
}
return result;
}
}
template <class T>
T * BinaryTree<T>::PostOrderVisit() {
}
template <class T>
int BinaryTree<T>::CalculateDepth(BinaryTreeNode<T> *curnode) {
if(!curnode){
return 0;
}else{
int leftdepth = CalculateDepth(curnode->leftchild);
int rightdepth = CalculateDepth(curnode->rightchild);
return (leftdepth>rightdepth?leftdepth:rightdepth)+1;
}
}
template <class T>
void BinaryTree<T>::PrintTree() {
PrintNode(root);
cout<<endl;
}
template <class T>
void BinaryTree<T>::PrintNode(BinaryTreeNode<T> *& curnode) {
if(curnode) {
cout << curnode->data << " ";
if(curnode->leftchild){
PrintNode(curnode->leftchild);
}
if(curnode->rightchild){
PrintNode(curnode->rightchild);
}
}
}
template <class T>
int BinaryTree<T>::GetNodeNum() {
return size;
}
CreateTree(root);
}
template <class T>
BinaryTree<T>::BinaryTree(BinaryTreeNode<T> *curnode) {
root = curnode;
}
template <class T>
void BinaryTree<T>::CreateTree(BinaryTreeNode<T> *&curnode) {
T data;
if(cin>>data){
if(data != "#") {
size++;
curnode = new BinaryTreeNode<T>(data, NULL, NULL);
if (curnode) {
CreateTree(curnode->leftchild);
CreateTree(curnode->rightchild);
}
else {
cerr << "tree node initialize error!" << endl;
}
}
}
}
template <class T>
BinaryTree<T>::~BinaryTree() {
DropTree(root);
}
template <class T>
void BinaryTree<T>::DropTree(BinaryTreeNode<T> *&curnode) {
if(curnode){
DropTree(curnode->leftchild);
DropTree(curnode->rightchild);
delete curnode;
}
}
template <class T>
const BinaryTreeNode<T> & BinaryTree<T>::GetRoot() const {
return *root;
}
template <class T>
T * BinaryTree<T>::LevelOrder() {//弹出对头节点,如果当前节点有孩子就把孩子入队
T * result = new T[size+1];
queue<BinaryTreeNode<T>*> q;
if(!root){
return NULL;
}else {
BinaryTreeNode<T>* cur;
int i = 0;
q.push(root);
while (!q.empty()) {
cur = q.front();
if (cur->leftchild) {
q.push(cur->leftchild);
}
if (cur->rightchild) {
q.push(cur->rightchild);
}
q.pop();
result[i] = cur->data;
i++;
}
return result;
}
}
template <class T>
T* BinaryTree<T>::LevelOrderWithLineNum() {
//和上面的区别在于需要两个指针记录当前层的最后一个,以及更新下一层的最后一个节点
//当当前层的最后一个节点被弹出时,该节点的右孩子就是下一层的最后一个节点,此时将当前层last指针指向下一层的last指针
int depth = GetTreeDepth();
T * result = new T[size+depth];
queue<BinaryTreeNode<T> *> q;
if(!root){
return NULL;
}else{
BinaryTreeNode<T> * cur;
BinaryTreeNode<T> * levellast;
BinaryTreeNode<T> * templevellast;
q.push(root);
levellast = root;
int i = 0;
while(!q.empty()){
cur = q.front();
result[i] = cur->data;
i++;
if(cur->leftchild){
q.push(cur->leftchild);
templevellast = cur->leftchild;
}
if(cur->rightchild){
q.push(cur->rightchild);
templevellast = cur->rightchild;
}
if(cur == levellast){
result[i] = "#";
i++;
levellast = templevellast;
}
q.pop();
}
return result;
}
}
template <class T>
T * BinaryTree<T>::PreOrderVisit() {//弹出栈顶节点,如果有右孩子,右孩子进栈,指针指向左孩子
if(!root){
return NULL;
}else{
T * result = new T[size+1];
stack<BinaryTreeNode<T> *> s;
BinaryTreeNode<T> * cur;
s.push(root);
int i = 0;
while(!s.empty()){
cur = s.top();
s.pop();
while(cur){
result[i] = cur->data;
i++;
if(cur->rightchild){
s.push(cur->rightchild);
}
if (cur->leftchild){
cur = cur->leftchild;
}else{
cur = NULL;
}
}
}
return result;
}
}
template <class T>
T * BinaryTree<T>::MidOrderVisit() {//不断将当前节点入栈,深入左子树,左不下去时弹出栈顶元素,深入右子树
if(!root){
return NULL;
}else{
T *result = new T[size+1];
stack<BinaryTreeNode<T>*> s;
BinaryTreeNode<T> * cur;
cur = root;
int i = 0;
while(cur||!s.empty()){
while(cur){
s.push(cur);
cur = cur->leftchild;
}
if(!s.empty()){
cur = s.top();
s.pop();
result[i] = cur->data;
i++;
cur = cur->rightchild;
}
}
return result;
}
}
template <class T>
T * BinaryTree<T>::PostOrderVisit() {
//节点入栈顺序为父节点,右孩子节点,左孩子节点//出栈的条件:1.当前节点没有孩子.2.上一次弹出的元素和当前节点是父子关系if (!root){ return NULL;}else{ stack<BinaryTreeNode<T>*> s; BinaryTreeNode<T>* cur,*pre; T * result = new T[size+1]; cur = root; int i = 0; s.push(root); pre = NULL; while(!s.empty()){ cur = s.top(); if((cur ->rightchild == NULL && cur->leftchild == NULL) || (pre!=NULL && (pre==cur->leftchild || pre == cur->rightchild))){ s.pop(); result[i++] = cur->data; pre = cur; } else { if (cur->rightchild != NULL) s.push(cur->rightchild); if (cur->leftchild != NULL) s.push(cur->leftchild); } } return result;}
}
template <class T>
int BinaryTree<T>::CalculateDepth(BinaryTreeNode<T> *curnode) {
if(!curnode){
return 0;
}else{
int leftdepth = CalculateDepth(curnode->leftchild);
int rightdepth = CalculateDepth(curnode->rightchild);
return (leftdepth>rightdepth?leftdepth:rightdepth)+1;
}
}
template <class T>
void BinaryTree<T>::PrintTree() {
PrintNode(root);
cout<<endl;
}
template <class T>
void BinaryTree<T>::PrintNode(BinaryTreeNode<T> *& curnode) {
if(curnode) {
cout << curnode->data << " ";
if(curnode->leftchild){
PrintNode(curnode->leftchild);
}
if(curnode->rightchild){
PrintNode(curnode->rightchild);
}
}
}
template <class T>
int BinaryTree<T>::GetNodeNum() {
return size;
}
#endif //FORJOB_BINARYTREE_H
main所在.cpp中代码:
#include <iostream>
#include "BinaryTree.h"
#include <stdio.h>
#include <queue>
using namespace std;
int main() {
freopen("/Users/Alina/ClionProjects/ForJob/input/tree","r",stdin);
BinaryTree<string> tree;
string *r ;
r = tree.PreOrderVisit();
for(int i=0;i<tree.GetNodeNum();i++){
cout<<r[i]<<" ";
}
cout<<endl;
r = tree.MidOrderVisit();
for(int i=0;i<tree.GetNodeNum();i++){
cout<<r[i]<<" ";
}
cout<<endl;
r = tree.PostOrderVisit();
for(int i=0;i<tree.GetNodeNum();i++){
cout<<r[i]<<" ";
}
cout<<endl;
r = tree.LevelOrder();
for(int i=0;i<tree.GetNodeNum();i++){
cout<<r[i]<<" ";
}
cout<<endl;
r = tree.LevelOrderWithLineNum();
for(int i=0;i<tree.GetNodeNum()+tree.GetTreeDepth();i++){
if(r[i]=="#"){
cout<<endl;
}else{
cout<<r[i]<<" ";
}
}
cout<<endl;
return 0;
}
#include "BinaryTree.h"
#include <stdio.h>
#include <queue>
using namespace std;
int main() {
freopen("/Users/Alina/ClionProjects/ForJob/input/tree","r",stdin);
BinaryTree<string> tree;
string *r ;
r = tree.PreOrderVisit();
for(int i=0;i<tree.GetNodeNum();i++){
cout<<r[i]<<" ";
}
cout<<endl;
r = tree.MidOrderVisit();
for(int i=0;i<tree.GetNodeNum();i++){
cout<<r[i]<<" ";
}
cout<<endl;
r = tree.PostOrderVisit();
for(int i=0;i<tree.GetNodeNum();i++){
cout<<r[i]<<" ";
}
cout<<endl;
r = tree.LevelOrder();
for(int i=0;i<tree.GetNodeNum();i++){
cout<<r[i]<<" ";
}
cout<<endl;
r = tree.LevelOrderWithLineNum();
for(int i=0;i<tree.GetNodeNum()+tree.GetTreeDepth();i++){
if(r[i]=="#"){
cout<<endl;
}else{
cout<<r[i]<<" ";
}
}
cout<<endl;
return 0;
}
0 0
- c++二叉树的建立、前序中序后序深搜、宽搜、宽搜带行号
- 二叉树的建立
- 二叉树的建立
- 二叉树的建立
- 二叉树的建立
- 二叉树的建立
- 二叉树的建立
- 二叉树的建立
- 二叉树的建立
- 二叉树的建立
- 【二叉树的建立】
- 二叉树的建立
- 二叉树的建立
- 二叉树的建立
- 二叉树的建立
- 二叉树的建立
- 二叉树的建立
- 二叉树的建立
- cocos2dx将资源目录(Resources)文件拷贝到可写路径
- Activity生命周期再分析
- [快速配置]RedisCluster
- 从命令行运行程序
- android 触控
- c++二叉树的建立、前序中序后序深搜、宽搜、宽搜带行号
- 自动化测试:k8s环境下,通过检测文件是否存在来自动启停tomcatapp的方法_20160316_七侠镇莫尛貝
- 千亿级SaaS市场:企业级服务的必争之地
- iOS面试题十
- pillow pil 图像处理
- The total number of locks exceeds the lock table size错误(已纠正)
- ceph故障【pgs inconsistent;scrub errors】解决方法
- 决策树,ID3算法
- .Net Zookeeper 学习目录