二叉树创建-- .cpp函数文件(无模板)
来源:互联网 发布:Python程序sleep 编辑:程序博客网 时间:2024/06/05 06:35
#include <iostream>#include <stack>#include <queue>#include "binarytree.h"istream& operator>>(istream &is,BinaryTree &BT){ BT.CreateBT(is,BT); return is;}ostream& operator<<(ostream &os,BinaryTree &BT){ os<<"按前序遍历的顺序输出二叉树:"; BT.Traverse(os,BT.root); os<<endl; return os;}void BinaryTree::CreateBT(istream &is,BinaryTree &BT){ cout<<"请以广义表的形式输入二叉树:"<<endl; cout<<"注意,左子女右子女有一个为空时,逗号不能省略,以#字符结束输入:"<<endl; stack<Node*> s; Node *p,*t; BT.root=NULL; char ch; int k=0; is>>ch; while(ch!=refvalue) { switch(ch) { case '(':s.push(p);k=1;break; //左括号,压入p即父母结点,同时k=1; case ')':s.pop();break; //右括号,退栈,即退出子树 case ',':k=2;break; //逗号,仅仅k=2, default: p=new Node(ch); //新建结点p保存刚刚输入的数据 if(BT.root==NULL) BT.root=p; //根结点赋值 else if(k==1) //链接左子树 { t=s.top(); t->lchild=p; } else if(k==2) //链接右子树 { t=s.top(); t->rchild=p; } } is>>ch; }}void BinaryTree::Traverse(ostream &os,Node *subtree){ if(subtree!=NULL) { os<<subtree->data<<" "; Traverse(os,subtree->lchild); Traverse(os,subtree->rchild); }}void PrintBT(Node *subtree){ if(subtree!=NULL) { cout<<subtree->data<<" "; if(subtree->lchild!=NULL||subtree->rchild!=NULL) { cout<<"("; PrintBT(subtree->lchild); cout<<","; PrintBT(subtree->rchild); cout<<")"; } }}//递归遍历//PreOrdervoid BinaryTree::PreOrder(Node *subtree){ if(subtree!=NULL) { cout<<subtree->data<<" "; PreOrder(subtree->lchild); PreOrder(subtree->rchild); }}//InOrdervoid BinaryTree::InOrder(Node *subtree){ if(subtree!=NULL) { InOrder(subtree->lchild); cout<<subtree->data<<" "; InOrder(subtree->rchild); }}//PostOrdervoid BinaryTree::PostOrder(Node *subtree){ if(subtree!=NULL) { PostOrder(subtree->lchild); PostOrder(subtree->rchild); cout<<subtree->data<<" "; }}int BinaryTree::Size(Node *subtree){ if(subtree==NULL) return 0; return 1+Size(subtree->lchild)+Size(subtree->rchild);}int BinaryTree::Height(Node *subtree){ if(subtree==NULL) return 0; int i=Height(subtree->lchild); int j=Height(subtree->rchild); return (i>j)?i+1:j+1;}BinaryTree::BinaryTree(const BinaryTree &s){ root=Copy(s.root);}Node* BinaryTree::Copy(Node *subtree){ if(subtree==NULL) return NULL; Node *t=new Node; t->data=subtree->data; t->lchild=Copy(subtree->lchild); t->rchild=Copy(subtree->rchild); return t;}void BinaryTree::destroy(Node *subtree){ if(subtree!=NULL) { destroy(subtree->lchild); destroy(subtree->rchild); delete subtree; }}//LevelOrder按层遍历void BinaryTree::LevelOrder(Node *subtree){ queue<Node *> q; q.push(subtree); Node *p; while(!q.empty()) //循环直到队列空,跳出循环,每次循环压根结点的左右子女 { p=q.front(); //得到队首结点指针, cout<<p->data<<" "; //输出元素值 q.pop(); //出队 if(p->lchild!=NULL) q.push(p->lchild); //左子女不为空,压左子女 if(p->rchild!=NULL) q.push(p->rchild); //右子女不为空,压右子女 }}<pre name="code" class="cpp">//非递归遍历 栈的应用//前序遍历 方法一 只压右子树void BinaryTree::PreOrder(Node *subtree){ stack<Node*> s; Node *p=subtree; s.push(NULL); while(p!=NULL) { cout<<p->data<<" "; if(p->rchild!=NULL) {s.push(p->rchild);} //右子树不为空,压右子树 if(p->lchild!=NULL) {p=p->lchild;} //左子树不为空,进入左子树,但不压栈 else {p=s.top();s.pop();} //左子树为空,退栈并得到栈顶元素 }}//前序遍历 方法二 先压右子树,再压左子树void BinaryTree::PreOrder(Node *subtree){ stack<Node*> s; s.push(subtree); Node *p=subtree; while(!s.empty()) { p=s.top(); s.pop(); cout<<p->data<<" "; if(p->rchild!=NULL) s.push(p->rchild); if(p->lchild!=NULL) s.push(p->lchild); }} //前序遍历 方法三 压根结点void BinaryTree::PreOrder(Node *subtree){ stack <Node *> s; Node *p=subtree; while(p!=NULL||!s.empty()) //当且仅当栈空且p指向最右下方的空树跳出循环 { if(p!=NULL) { cout<<p->data<<" "; //输出根结点 s.push(p); //根结点入栈 p=p->lchild; //访问左子树 } else { p=s.top(); //得到栈顶根节点指针 s.pop(); //根节点出栈 p=p->rchild; //访问右子树 } }}//中序遍历 方法一 压根结点void BinaryTree::InOrder(Node *subtree){ stack <Node *> s; Node *p=subtree; while(p!=NULL||!s.empty()) { if(p!=NULL) { s.push(p); p=p->lchild; } else { p=s.top(); s.pop(); cout<<p->data<<" "; p=p->rchild; } }}//中序遍历void BinaryTree::InOrder(Node *subtree){ stack<Node*> s; Node *p=subtree; do{ while(p!=NULL) { s.push(p); p=p->lchild; } if(!s.empty()) { p=s.top(); s.pop(); cout<<p->data<<" "; p=p->rchild; } }while(!s.empty()||p!=NULL); cout<<endl;}//后序遍历,需要判断从左子树退回还是右子树退回,新建节点结构体,含标记值struct stkNode //遍历时所用栈结点类定义{ Node *ptr; //指向树结点的指针 int tag; //该结点退栈的标记值,L代表从左子树退回,R代表从右子树退回 stkNode(Node *N=NULL):ptr(N),tag(0){} //构造函数,创建一个stkNode结点时,默认结点指针为NULL,标记值为L};void BinaryTree::PostOrder(Node *subtree){ stack<stkNode> s; stkNode w; Node *p=subtree; //p是遍历指针 do { while(p!=NULL) //向最左下方的结点循环下去,直到为空 { w.ptr=p; //左子树结点指针赋给w.ptr w.tag=0; //w.tag赋为L标记 s.push(w); //压栈 p=p->lchild; //向左下方结点走下去 } int continue1=1; //循环的标记,用于当从右子树退回时,需要循环退栈两或多次 while(continue1&&!s.empty()) //栈不空则退栈 { w=s.top(); s.pop(); p=w.ptr; switch(w.tag) //判断栈顶结点指针的标记值 { case 0:w.tag=1; //从左子树退回,则修改栈顶标记值后重新压栈 s.push(w); continue1=0; //不是右子树退回,则不用再循环退栈,continue1赋为0 p=p->rchild; //访问右子树,跳到大循环do while中,将其左下方结点一直压栈…… break; case 1:cout<<w.ptr->data<<" "; //从右子树退回,输出栈顶值,即根结点的值,继续循环退栈 break; } } }while(!s.empty()); //栈为空时退出循环}
0 0
- 二叉树创建-- .cpp函数文件(无模板)
- 二叉树创建---.h头文件 类声明(无模板)
- 【暂无】二叉树 二叉树的三种遍历(binary-tree.cpp)
- 【暂无】 二叉树 根据遍历结果建立二叉树(build-tree.cpp)
- 【暂无】 二叉树 扩展二叉树(add-tree.cpp)
- 【暂无】 二叉树 二叉树的计数(count-tree.cpp)
- 二叉树功能函数 BinTree.cpp
- VC6不支持模板函数在cpp文件中的实现
- VC6不支持模板函数在cpp文件中的实现
- C++ 在.h文件中声明,在.cpp文件中定义 模板函数和模板类
- 二叉树(类模板、函数模板、函数对象、函数指针)
- CPP二叉树
- 二叉树(模板)
- cpp--模板(1)
- 杜教模板(转载一篇cpp文件)
- 二叉树二叉链表存储结构 <函数实现:BiTreeFun.cpp>
- 二叉树的创建、打印、删除等函数(c)
- 为什么模板类与模板成员函数不能分文件写(.h与.cpp)
- Android学习 -- 《AndroidManifest》
- Activity的四种启动模式详解
- 二叉树创建---.h头文件 类声明(无模板)
- php的总结
- lua和php的基本数据类型
- 二叉树创建-- .cpp函数文件(无模板)
- The Struts dispatcher cannot be found. This is usually caused by using Struts tags without the asso
- 欢迎使用CSDN-markdown编辑器
- MySQL5.7.10解压版详细安装教程
- java基础(28)--泛型与类型擦除、泛型与继承
- 【Android基础】Android 高仿【优酷】圆盘旋转菜单的实现
- 欢迎使用CSDN-markdown编辑器
- Spring入门之HelloWorld
- MarkDown初试