数据结构————二叉树的基本应用

#include <stdio.h>
#include<string.h>
#include<stdlib.h>
#include<malloc.h>
#include <iostream>    
using namespace std;
#define OK 1
#define ERROR 0
#define OVERFLOW -1
typedef int Status;
typedef char  TElemType;

typedef struct BiNode{//树结点 
	TElemType data;
	struct BiNode*rchild,*lchild;
}BiNode ,*BiTree;

typedef struct QueueNode//队列结点 
{
	BiTree Qdata;
	struct QueueNode* next;
}QueueNode, *pQueueNode;

typedef struct Queue//队列 
{
	pQueueNode front,rear;
	
}Queue,*pQueue;

pQueue initQ(pQueue pq)//建立只有头结点的队列
{
	pq->front = (pQueueNode)malloc(sizeof(QueueNode));
	if (pq->front==NULL)//判断内存分配是否成功
	{
		printf("内存分配不成功!");
	}
	else
	{
		pq->front->next = NULL;//队列的front和rear的next初始化为空
		pq->rear = pq->front;
		return pq;
	}
}
void enqueue(pQueue pq, BiTree T)//把二叉树的数据取出放入队列
{
	pQueueNode pNew = new QueueNode;
	pNew->Qdata = T;//二叉树的数据存入队列
	pNew->next = NULL;
	pq->rear->next = pNew;//尾插法建立连接
	pq->rear = pNew;//rear更新
}

BiTree dequeue(pQueue pq)//出队:删除队列第一个元素
{
	pQueueNode pTemp= (pQueueNode)malloc(sizeof(QueueNode));
	pTemp = pq->front->next;
	if (pTemp->next == NULL)//只剩下1个节点(不含队列空的头结点)
	{
		pq->rear = pq->front;
	}
	else{
		pq->front->next = pTemp->next;//front+1(从指向第1个非空节点改为指向第2个节点)
	}
	BiTree x;
	x= pTemp->Qdata;//x为队列第一个元素的data
	free(pTemp);
	return x;
}

void levelorder(BiTree T)//层序遍历 
{
	pQueue pq= (pQueue)malloc(sizeof(Queue));
	pq = initQ(pq);
	enqueue(pq,T);//取出二叉树的根节点,子节点存入队列
	while (pq->rear != pq->front)//当队列不为空
	{
		BiTree x = dequeue(pq);//x用于输出队列弹出元素的数据
		printf("%c", x->data);
		if (x->lchild!=NULL)
		{
			enqueue(pq, x->lchild);//递归左节点
		}
		if (x->rchild!=NULL)
		{
			enqueue(pq, x->rchild);//递归右节点
		}
	}
}



//建立二叉树
Status CreateBiTree(BiTree &T)
{
	char ch;
	cin>>ch;
	if(ch=='#')
	T=NULL;
	else
	{
		T=new BiNode;
		T->data=ch;
		CreateBiTree(T->lchild);
		CreateBiTree(T->rchild);
	}
	return OK;
 } 
 //先序遍历
 Status perorder(BiTree T)
 {
 	if(T==NULL) return OK;
 	else
 	{
 	    printf("%c",T->data); //先序访问根结点 
 	    perorder(T->lchild);
 	    perorder(T->rchild);
	}
 }
 //中序遍历 
  Status inorder(BiTree T)
 {
 	if(T==NULL) return OK;
 	else
 	{
 	    inorder(T->lchild);
 	    printf("%c",T->data); //中序访问根结点 
 	    inorder(T->rchild);
	}
 }
 // 后序遍历 
 Status postorder(BiTree T)
 {
 	if(T==NULL) return OK;
 	else
 	{
 	    postorder(T->lchild);
 	    postorder(T->rchild);
 	    printf("%c",T->data);//后序访问根结点 
	}
 }
 
//二叉树的深度
int treehigh(BiTree T)
{
	if(T==NULL) 
 	return 0;
 	if(!T->lchild&&!T->rchild) 
 	return 1;
 	int lhigh=treehigh(T->lchild);
 	int rhigh=treehigh(T->rchild);
 	return 1+(lhigh>rhigh?lhigh:rhigh); //左右子树的最大深度加一,为树的深度 
}
//统计二叉树的结点
int treenodes(BiTree T)
{
	if(T==NULL) 
 	return 0;
 	if(!T->lchild&&!T->rchild)
 	return 1;
 	return 1+treenodes(T->lchild)+treenodes(T->rchild);
}
//统计二叉树叶结点
int treeleaves(BiTree T)
 {
 	if(T==NULL) 
 	return 0;
 	if(!T->lchild&&!T->rchild)
 	return 1;
 	return treeleaves(T->lchild)+treeleaves(T->rchild);
 }
//复制二叉树
 BiTree TreeClone(BiTree T)
{
	if(T== NULL)
	return 0;
	BiTree T1 ;	
	T1 = (BiTree)malloc(sizeof(T));
        T1->data = T->data;               //先复制根节点
	T1->lchild = TreeClone(T->lchild);  //再复制左子树
	T1->rchild = TreeClone(T->rchild);  //然后复制右子树
	return T1;
}
//将二叉树中每个结点的左右子树进行交换
BiTree swapSubTree(BiTree T) {
	if (!T) return NULL;
	else {
		//交换的过程
		BiTree tmp = T->lchild;
		T->lchild= T->rchild;
		T->rchild = tmp;
		swapSubTree(T->lchild);
		swapSubTree(T->rchild);
	}
	return T;
}

//判断两棵二叉树是否完全相同
bool isSameTree(BiTree T, BiTree B){
        if (T == NULL&& B==NULL){
            return true;
        }
        if (T==NULL || B==NULL){
            return false;
        }
        if (T->data != B->data){
            return false;
        }
        return isSameTree(T->lchild, B->lchild) && isSameTree(T->rchild,B->rchild);
    }
//统计二叉树单分支数
int CountSingle(BiTree T)
{
	int n1,n2,n;
	if(T==NULL) 
 	return 0;
 	if(!T->lchild&&!T->rchild)
 	return 1;
 	else{
 		n1=CountSingle(T->rchild);
 		n2=CountSingle(T->lchild);
 		if(T->rchild==NULL)
 		n=n2+1;
 		else if(T->lchild==NULL)
 		n=n1+1;
 		else
 		n=n1+n2;
	 }
	 return n;
}

 int main(){
	BiTree T,T1,B;
	TElemType ch;
	int choice,s,sum,high,t; 
	cout<<"创建一个二叉树T(例:AB##c##,AB#D##CE#F###):"<<"\n"<<endl;
	CreateBiTree(T); 
	
	do{
    	cout<<"\n\n==============================";
		cout<<"\n  	 二叉树的基本操作		";
    	cout<<"\n==============================";
		cout<<"\n  	 1:先序遍历";
    	cout<<"\n  	 2:中序遍历";
    	cout<<"\n  	 3:后序遍历"; 
		cout<<"\n  	 4:层序遍历"; 
		cout<<"\n  	 5:二叉树的深度"; 
		cout<<"\n  	 6:统计二叉树的结点";
		cout<<"\n  	 7:统计二叉树叶结点"; 
		cout<<"\n  	 8:将二叉树中每个结点的左右子树进行交换";
		cout<<"\n  	 9:复制二叉树";
		cout<<"\n  	 10:判断两棵二叉树是否完全相同"; 
		cout<<"\n         11:统计二叉树单分支数";
		cout<<"\n  	 0:退出"<<endl;
    	cin>>choice;
		switch (choice){
			case 1:cout<<"先序遍历的结果为:";
					perorder(T);				
					break; 
			case 2:cout<<"中序遍历的结果为:";
					inorder(T);
					break;
			case 3:cout<<"后序遍历的结果为:";
					postorder(T);
					break;
			case 4:cout<<"层序遍历的结果为:";
					levelorder(T);
					break;
			case 5:
					high=treehigh(T);
					cout<<"二叉树的深度为:"<<high;
					break; 
			case 6:
					sum=treenodes(T);
					cout<<"二叉树结点共有:"<<sum<<"个";
					break;
			case 7:
					s=treeleaves(T);
					cout<<"二叉树叶结点共有:"<<s<<"个";
					break;
			case 8:T1=swapSubTree(T);
					cout<<"交换的结果为:(用先序表示)";
					perorder(T1);
					break;
			case 9:T1=TreeClone(T);
					cout<< "复制的结果为 :(用先序表示)" ; 
					perorder(T1);
					break;
			case 10:cout<<"创建另一颗二叉树B:"; 
					CreateBiTree(B); 
					if(isSameTree(T,B)==true)
					cout<<"二叉树T和二叉树B相等!"<<endl;
					else
					cout<<"二叉树T和二叉树B不相等!"<<endl;
					break;
			case 11:t=CountSingle(T);
					cout<<"二叉树单分支数为:"<<t<<endl;
					break;
			case 0:
				break;
					}
	}while (choice);
	
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值