- // BiTree_02.cpp : Defines the entry point for the console application.
- //
- #include "stdafx.h"
- /****************************************************************************/
- /* 1、问题描述:很多涉及二叉树的操作的算法都是以二叉树的遍历操作为基础的。*/
- /* 编写程序,对一棵给定的二叉树进行先、中、后三种次序的遍历。 */
- /* 2、基本要求:以二叉链表为存储结构,实现二叉树的先、中、后三种次序的递 */
- /* 归和非递归遍历。 */
- /* 3、测试数据:以教科书图6.9的二叉树为例。 */
- /* 4、实现提示: */
- /* (1)、设二叉树的结点不超过30个,且每个结点的数据均为字符,这样可 */
- /* 利用先序遍历序列作为输入顺序创建二叉树链表存储结构。 */
- /* (2)、也可利用完全二叉树在顺序存储中的特性,创建二叉树的存储结构,*/
- /* 此时,二叉树中结点数据的类型不受限制。 */
- /* 5、选作内容: */
- /* (1)、借助队列,实现二叉树的层序遍历。 */
- /* (2)、按凹入表或树形打印所遍历的二叉树。 */
- /****************************************************************************/
- #include<iostream>
- #include<fstream>
- #include<string>
- #include<stack>
- #include<stdlib.h>
- //#include<stdio.h>
- //#include<malloc.h>
- using namespace std;
- //--------------------------------------------------
- #define OK 1
- #define ERROR 0
- #define OVERFLOW -2
- typedef char TElemtype;
- const int MaxLength = 30;//二叉树的结点不超过30个
- typedef struct BiTNode{//二叉树结点结构
- TElemtype data;
- struct BiTNode *lchild,*rchild;
- }BiTNode,*BiTree;
- //--------------------------------------------------
- class BinaryTree{
- private:
- BiTree T;
- public:
- int CreateBiTree(BiTree &T,ifstream &in);
- //递归遍历
- void PreOrder(BiTree &T);
- void InOrder(BiTree &T);
- void PostOrder(BiTree &T);
- //层序遍历
- void LevelOrder(BiTree T);
- //非递归遍历
- void RePreOrder(BiTree &T);
- void ReInOrder(BiTree &T);
- void RePostOrder(BiTree &T);
- bool Complete(BiTree T);
- int Depth(BiTree T);
- int Countleaf(BiTree T);
- int Countleafs(BiTree T);
- };//BinaryTree
- //--------------------------------------------------
- void main(){
- ofstream out("data.txt");
- /* if(out){
- for(char i = 65; i < 70; i++)
- out << i;// << '#' << char(i + 7);
- out << "###############";
- }
- */
- // out << "AB##C##";
- // out << "ABC##D##EF##G##";
- // out << "ABCD##E##FG##H##IJK##L##MN##O##";
- out << "ABCD##E##FG##H##IJK##L##MN####";
- out.close();
- cout<<"按先序序列输入二叉树中结点的值,如:\n-+a##*b##-c##d##/e##f##\n";
- ifstream in("data.txt");
- BinaryTree bt;
- BiTree tree;
- bt.CreateBiTree(tree,in);
- in.close();
- cout<<"二叉树创建完成!\n";
- cout<<"----------------\n";
- cout<<"递归遍历:\n";
- cout<<"先序遍历二叉树:\n";
- bt.PreOrder(tree);
- cout<<endl;
- cout<<"中序遍历二叉树:\n";
- bt.InOrder(tree);
- cout<<endl;
- cout<<"后序遍历二叉树:\n";
- bt.PostOrder(tree);
- cout<<endl;
- cout<<"----------------\n";
- cout<<"非递归遍历:\n";
- cout<<"先序遍历二叉树:\n";
- bt.RePreOrder(tree);
- cout<<endl;
- cout<<"中序遍历二叉树:\n";
- bt.ReInOrder(tree);
- cout<<endl;
- cout<<"后序遍历二叉树:\n";
- bt.RePostOrder(tree);
- cout<<endl;
- cout<<"----------------\n";
- cout<<"层序遍历二叉树是否为完全二叉树:";
- if(bt.Complete(tree))
- cout<<"是\n";
- else
- cout<<"不是\n";
- cout<<"此二叉树的深度为:"<<bt.Depth(tree)<<endl;
- cout<<"此二叉树的总结点个数为:"<<bt.Countleafs(tree)<<endl;
- cout<<"此二叉树的叶子结点个数为:"<<bt.Countleaf(tree)<<endl;
- }
- //--------------------------------------------------
- int BinaryTree::CreateBiTree(BiTree &T,ifstream &in){
- //按先序序列输入二叉树中结点的值,空格字符表示空树,
- //构造二叉树表表示的二叉树T;
- char ch;
- in>>ch;
- if(ch == '#') T = NULL;
- else{
- T = (BiTNode*)malloc(sizeof(BiTNode));
- if(T == NULL) return ERROR;//*/if(!(T = new BiTNode)) exit(OVERFLOW);
- T -> data = ch;//生成根节点
- int temp = CreateBiTree(T -> lchild,in) + CreateBiTree(T -> rchild,in);//构造右子树
- // CreateBiTree(T -> lchild,in)//构造左子树
- // CreateBiTree(T -> rchild,in);//构造右子树
- }//else
- return OK;
- }//CreateBiTree
- //--------------------------------------------------
- void BinaryTree::PreOrder(BiTree &T){//递归函数:先序遍历以T为根的二叉树
- if(T != NULL){//递归结束条件
- cout<<T -> data<<" ";//访问根节点
- PreOrder(T -> lchild);//先序遍历根节点的左子树
- PreOrder(T -> rchild);//先序遍历根节点的右子树
- }
- }//PreOrder
- //--------------------------------------------------
- void BinaryTree::InOrder(BiTree &T){//递归函数:中序遍历以T为根的二叉树
- if(T != NULL){//递归结束条件
- InOrder(T -> lchild);//中序遍历根节点的左子树
- cout<<T -> data<<" ";//访问根节点
- InOrder(T -> rchild);//中序遍历根节点的右子树
- }
- }//InOrder
- //--------------------------------------------------
- void BinaryTree::PostOrder(BiTree &T){//递归函数:后序遍历以T为根的二叉树
- if(T != NULL){//递归结束条件
- PostOrder(T -> lchild);//后序遍历根节点的左子树
- PostOrder(T -> rchild);//后序遍历根节点的右子树
- cout<<T -> data<<" ";//访问根节点
- }
- }//PostOrder
- //--------------------------------------------------
- void BinaryTree::RePreOrder(BiTree &T){//非递归函数:先序遍历以T为根的二叉树
- stack<BiTree> s;
- s.push(T);//根指针进栈
- while(!s.empty()){
- BiTree b = s.top();
- if(!s.empty()){//访问结点
- b = s.top();
- s.pop();
- if(b -> data == NULL) cout<<"error";
- else
- cout<<b -> data<<" ";
- }//if
- if(b -> rchild) s.push(b -> rchild); //若右孩子存在,则入栈
- if(b -> lchild) s.push(b -> lchild); //若左孩子存在,则入栈
- }//while
- }//RePreOrder
- //--------------------------------------------------
- void BinaryTree::ReInOrder(BiTree &T){//非递归函数:中序遍历以T为根的二叉树
- stack<BiTree> s;
- s.push(T);//根指针进栈
- while(!s.empty()){
- BiTree b = s.top();
- while(b){//向左走到尽头
- s.push(b -> lchild);
- b = s.top();
- }//while
- s.pop();//空指针退栈
- if(!s.empty()){//访问结点,向右一步
- b = s.top();
- s.pop();
- if(b -> data == NULL) cout<<"error";
- else
- cout<< b -> data<<" ";
- s.push(b -> rchild);
- }//if
- }//while
- }//ReInOrder
- //--------------------------------------------------
- void BinaryTree::RePostOrder(BiTree &T){//非递归函数:后序遍历以T为根的二叉树
- stack<BiTree> s;
- BiTree r,p;//使用r标记访问过的右子树
- p = T;
- while(p||!s.empty())
- {
- if(p)
- {
- s.push(p);
- p = p -> lchild;
- }//if
- else
- {
- p = s.top();
- if(p -> rchild && p -> rchild != r)
- {
- p = p -> rchild;
- s.push(p);
- p = p-> lchild;
- }
- else
- {
- s.pop();
- cout<<p->data<<" ";
- r = p;
- p = NULL;
- }
- }//else
- }//while
- }//RePostOrder
- //--------------------------------------------------
- void BinaryTree::LevelOrder(BiTree T){//借助队列,层序遍历
- BiTree Q[MaxLength];
- int front = 0;
- int rear = 0;
- BiTree p;
- if(T){//根节点入队
- Q[rear] = T;
- rear = (rear + 1) % MaxLength;
- }
- while(front != rear){
- p = Q[front];
- cout<<p -> data<<" ";
- front = (front + 1) % MaxLength;//队头元素出队
- if(p -> lchild){//左孩子不为空,入队
- Q[rear] = p -> lchild;
- rear = (rear + 1) % MaxLength;
- }
- if(p -> rchild){//右孩子不为空,入队
- Q[rear] = p -> rchild;
- rear = (rear + 1) % MaxLength;
- }
- }//while
- }//LevelOrder
- //--------------------------------------------------
- bool BinaryTree::Complete(BiTree T){//是否为完全二叉树
- BiTree Q[MaxLength];
- int front = 0;
- int rear = 0;
- BiTree p;
- if(T == NULL)return true;//!T 即T == NULL
- else{
- Q[rear] = T;//根节点入队
- rear = (rear + 1) % MaxLength;
- while(front != rear){//队列不空
- p = Q[front];
- front = (front + 1) % MaxLength;//队头元素出队
- if(p){
- Q[rear] = p -> lchild;//左孩子入队
- rear = (rear + 1) % MaxLength;
- Q[rear] = p -> rchild;//右孩子入队
- rear = (rear + 1) % MaxLength;
- }//if
- else{
- while(front != rear){//队列不空
- p = Q[front];
- if(p) return false;
- return true;
- }//while
- }//else
- }//while
- return true;//队列空则返回是
- }//else
- }//Complete
- //--------------------------------------------------
- int BinaryTree::Depth(BiTree T){
- int depthval,depthleft,depthright;
- if(T == NULL) depthval = 0;
- else{
- depthleft = Depth(T -> lchild);
- depthright = Depth(T -> rchild);
- depthval = 1 + (depthleft > depthright ? depthleft : depthright);
- }//else
- return depthval;
- }//Depth
- //--------------------------------------------------
- int BinaryTree::Countleaf(BiTree T){//二叉树的叶子结点个数
- int m,n;
- if(!T) return 0;
- if(!T -> lchild && !T -> rchild) return 1;
- else {
- m = Countleaf(T -> lchild);
- n = Countleaf(T -> rchild);
- return(m + n);
- }//else
- }//Countleaf
- //--------------------------------------------------
- int BinaryTree::Countleafs(BiTree T){//二叉树的总结点个数
- int m,n;
- if(!T) return 0;
- if(!T -> lchild && !T -> rchild) return 1;
- else {
- m = Countleafs(T -> lchild);
- n = Countleafs(T -> rchild);
- return(m + n + 1);
- }//else
- }//Countleafs