二叉树的创建,及遍历 操作

递归创建二叉树

利用括号嵌套的字符串建立二叉链表(递归,与非递归)

先序遍历二叉树的递归实现

中序遍历二叉树的递归实现

后序遍历二叉树的递归实现

先序遍历二叉树的非递归实现

中序遍历二叉树的非递归实现

后序遍历二叉树的非递归实现

二叉树的层次遍历

销毁二叉树操作

二叉树的左插入操作

二叉树的右插入操作

查找元素值为e的结点的指针

返回二叉树的左右孩子结点元素值操作

二叉树的左(右)删除操作

计算二叉树的深度,叶子节点个数

#include <iostream>
#include <string.h>
#include <stdio.h>
typedef char DataType;
#define MaxSize 100
using namespace std;
typedef struct Node				//二叉链表存储结构类型定义
{
	DataType data;			 	//数据域
	struct Node *lchild; 			//指向左孩子结点
	struct Node *rchild; 			//指向右孩子结点
}*BiTree,BitNode;


void InitBitTree(BiTree *T)
//二叉树的初始化操作
{
	*T=NULL;
}

void DestroyBitTree(BiTree *T)
//销毁二叉树操作
{
	if(*T) 							//如果是非空二叉树
	{
		if((*T)->lchild)
			DestroyBitTree(&((*T)->lchild));
		if((*T)->rchild)
			DestroyBitTree(&((*T)->rchild));
		free(*T);
		*T=NULL;
	}
}
void CreateBitTree(BiTree *T)
//递归创建二叉树
{
    DataType ch;
    scanf("%c",&ch);
    if(ch=='#')
        *T=NULL;
    else
    {
        *T=(BiTree)malloc(sizeof(BitNode)); 		//生成根结点
        if(!(*T))
        {
            exit(-1);
        }
        (*T)->data=ch;
        CreateBitTree(&((*T)->lchild)); 			//构造左子树
        CreateBitTree(&((*T)->rchild)); 			//构造右子树
    }
}
int InsertLeftChild(BiTree p,BiTree c)
//二叉树的左插入操作
{
    if(p) 									//如果指针p不空
    {
        c->rchild=p->lchild; 					//p的原来的左子树成为c的右子树
        p->lchild=c; 						//子树c作为p的左子树
        return 1;
    }
    return 0;
}
int InsertRightChild(BiTree p,BiTree c)
//二叉树的右插入操作
{
	if(p) 									//如果指针p不空
    {
        c->rchild=p->rchild; 					//p的原来的右子树作为c的右子树
        p->rchild=c; 						//子树c作为p的右子树
        return 1;
    }
    return 0;
}
BiTree Point(BiTree T,DataType e)
//查找元素值为e的结点的指针
{
	BiTree Q[MaxSize]; 			//定义一个队列,用于存放二叉树中结点的指针
	int front=0,rear=0; 			//初始化队列
    BitNode *p;
    if(T) 						//如果二叉树非空
    {
        Q[rear]=T;
        rear++;
		
        while(front!=rear) 		//如果队列非空
        {
            p=Q[front]; 			//取出队头指针
            front++;			//将队头指针出队
            if(p->data==e)
				return p;
            if(p->lchild) 			//如果左孩子结点存在,将左孩子指针入队
            {
                Q[rear]=p->lchild;	//左孩子结点的指针入队
                rear++;
            }
            if(p->rchild)			//如果右孩子结点存在,将右孩子指针入队
            {
                Q[rear]=p->rchild; //右孩子结点的指针入队
                rear++;
            }
		}
    }
    return NULL;
}
DataType LeftChild(BiTree T,DataType e)
//返回二叉树的左孩子结点元素值操作
{
    BiTree p;
    if(T)										//如果二叉树不空
    {
        p=Point(T,e); 							//p是元素值e的结点的指针
        if(p&&p->lchild)							//如果p不为空且p的左孩子结点存在
            return p->lchild->data; 					//返回p的左孩子结点的元素值
    }
    return 0;
}
DataType RightChild(BiTree T,DataType e)
//返回二叉树的右孩子结点元素值操作
{
    BiTree p;
    if(T)										//如果二叉树不空
    {
        p=Point(T,e); 							//p是元素值e的结点的指针
        if(p&&p->rchild)							//如果p不为空且p的右孩子结点存在
            return p->rchild->data; 				//返回p的右孩子结点的元素值
    }
    return 0;
}
int DeleteLeftChild(BiTree p)
//二叉树的左删除操作
{
    if(p) 										//如果p不空
    {
        DestroyBitTree(&(p->lchild)); 				//删除左子树
        return 1;
    }
    return 0;
}
int DeleteRightChild(BiTree p)
//二叉树的左删除操作
{
    if(p) 										//如果p不空
    {
        DestroyBitTree(&(p->rchild)); 				//删除右子树
        return 1;
    }
    return 0;
    
}
void Queue(BiTree T)
{
    BiTree queue[100];
    BiTree p;
    int front=0,rear=0;
    if(T==NULL)
    {
        return;
    }
    queue[rear++]=T;
    while (front!=rear)
    {
        p=queue[front++];
        printf("%c ",p->data);
        if(p->lchild)
        {
            queue[rear++]=p->lchild;
        }
        if(p->rchild)
        {
            queue[rear++]=p->rchild;
        }
    }
}
//函数的声明
void PreOrderTraverse(BiTree T);	//二叉树的先序遍历的递归函数声明
void InOrderTraverse(BiTree T);		//二叉树的中序遍历的递归函数声明
void PostOrderTraverse(BiTree T);	//二叉树的后序遍历的递归函数声明
void PreOrderTraverse2(BiTree T);	//二叉树的先序遍历的非递归函数声明
void InOrderTraverse2(BiTree T);	//二叉树的中序遍历的非递归函数声明
void PostOrderTraverse2(BiTree T);	//二叉树的后序遍历的非递归函数声明
void CreateBitTree2(BiTree *T,char str[]);	//利用括号嵌套的字符串建立二叉树的函数声明
void QueueTraverse(BiTree T);       //二叉树的层次序遍历函数声明
int GetHeight(BiTree T);            //二叉树深度函数声明
int CountLeaf(BiTree T);            //二叉树叶子结点个数函数声明
int NotLeafCount(BiTree T);         //统计二叉树中非叶子结点数目
int main()
{
    char str[]="A(B(D(,H(J,)),E(,I)),C(F,G))";
	BiTree T,root;
	InitBitTree(&T);
	printf("根据输入二叉树的先序序列创建二叉树('#'表示结束):\n");
	CreateBitTree(&T);
	printf("二叉树的先序序列:\n");
	printf("递归:\t");
	PreOrderTraverse(T);
	printf("\n");
	printf("非递归:");
	PreOrderTraverse2(T);
	printf("\n");
	printf("二叉树的中序序列:\n");
	printf("递归:\t");
	InOrderTraverse(T);
	printf("\n");
	printf("非递归:");
	InOrderTraverse2(T);
	printf("\n");
	printf("二叉树的后序序列:\n");
	printf("递归:\t");
	PostOrderTraverse(T);
	printf("\n");
	printf("非递归:");
	PostOrderTraverse2(T);
	printf("\n");
	printf("根据括号嵌套的字符串建立二叉树:\n");
	CreateBitTree2(&root,str);
	printf("二叉树的先序序列:\n");
	PreOrderTraverse(root);
	printf("\n");
	printf("二叉树的中序序列:\n");
	InOrderTraverse(root);
	printf("\n");
	printf("二叉树的后序序列:\n");
	PostOrderTraverse(root);
	printf("\n");
    printf("二叉树的层次遍历序列:\n");
    QueueTraverse(root);
    printf("\n");
    printf("二叉树的深度:\n");
    printf("%2d\n",GetHeight(root));
    printf("二叉树叶子结点个数:\n");
    printf("%2d\n",CountLeaf(root));
	printf("非叶子结点个数:\n%2d\n",NotLeafCount(root));
	DestroyBitTree(&T);
	DestroyBitTree(&root);
    return 0;
}

void  CreateBitTree2(BiTree *T,char str[])
//利用括号嵌套的字符串建立二叉链表
{
	char ch;
	BiTree stack[MaxSize];			//定义栈,用于存放指向二叉树中结点的指针
	int top=-1;						//初始化栈顶指针
	int flag=-1,k;
	BitNode *p=NULL;
	*T=NULL,k=0;
	ch=str[k];
	while(ch!='\0')					//如果字符串没有结束
	{
		switch(ch)
		{
            case '(':
                stack[++top]=p;
                flag=1;
                break;
            case ')':
                top--;
                break;
            case ',':
                flag=2;
                break;
            default:
                p=(BiTree)malloc(sizeof(BitNode));
                p->data=ch;
                p->lchild=NULL;
                p->rchild=NULL;
                if(*T==NULL)		//如果是第一个结点,表示是根结点
                    *T=p;
                else
                {
                    switch(flag)
                    {
                        case 1:
                            stack[top]->lchild=p;
                            break;
                        case 2:
                            stack[top]->rchild=p;
                            break;
                    }
                }
		}
		ch=str[++k];
	}
	
}
void PreOrderTraverse(BiTree T)
//先序遍历二叉树的递归实现
{
    if(T)								//如果二叉树不为空
    {
        printf("%2c",T->data); 				//访问根结点
        PreOrderTraverse(T->lchild);		//先序遍历左子树
        PreOrderTraverse(T->rchild); 		//先序遍历右子树
    }
}
void InOrderTraverse(BiTree T)
//中序遍历二叉树的递归实现
{
    if(T)								//如果二叉树不为空
	{
		InOrderTraverse(T->lchild);			//中序遍历左子树
        printf("%2c",T->data); 				//访问根结点
        InOrderTraverse(T->rchild); 		//中序遍历右子树
    }
}
void PostOrderTraverse(BiTree T)
//后序遍历二叉树的递归实现
{
    if(T)								//如果二叉树不为空
	{
		PostOrderTraverse(T->lchild);		//后序遍历左子树
        PostOrderTraverse(T->rchild); 		//后序遍历右子树
		printf("%2c",T->data); 				//访问根结点
    }
}

void PreOrderTraverse2(BiTree T)
//先序遍历二叉树的非递归实现
{
	BiTree stack[MaxSize]; 				//定义一个栈,用于存放结点的指针
	int top; 							//定义栈顶指针
	BitNode *p; 						//定义一个结点的指针
	top=0;							//初始化栈
	p=T;
	while(p!=NULL||top>0)
	{
		while(p!=NULL) 					//如果p不空,访问根结点,遍历左子树
		{
			printf("%2c",p->data); 			//访问根结点
			stack[top++]=p; 				//将p入栈
			p=p->lchild; 				//遍历左子树
		}
		if(top>0) 						//如果栈不空
		{
			p=stack[--top]; 				//栈顶元素出栈
			p=p->rchild;					//遍历右子树
		}
	}
}
void InOrderTraverse2(BiTree T)
//中序遍历二叉树的非递归实现
{
	BiTree stack[MaxSize]; 				//定义一个栈,用于存放结点的指针
	int top; 							//定义栈顶指针
	BitNode *p; 						//定义一个结点的指针
	top=0;							//初始化栈
	p=T;
	while(p!=NULL||top>0)
	{
		while(p!=NULL) 					//如果p不空,访问根结点,遍历左子树
		{
			stack[top++]=p; 				//将p入栈
			p=p->lchild; 				//遍历左子树
		}
		if(top>0) 						//如果栈不空
		{
			p=stack[--top]; 				//栈顶元素出栈
			printf("%2c",p->data); 			//访问根结点
			p=p->rchild;					//遍历右子树
		}
	}
}

void PostOrderTraverse2(BiTree T)
//后序遍历二叉树的非递归实现
{
	BiTree stack[MaxSize]; 				//定义一个栈,用于存放结点的指针
	int top; 							//定义栈顶指针
	BitNode *p,*q; 						//定义结点的指针
	top=0;								//初始化栈
	p=T,q=NULL; 						//初始化结点的指针
	while(p!=NULL||top>0)
	{
		while(p!=NULL) 						//如果p不空,访问根结点,遍历左子树
		{
			stack[top++]=p; 				//将p入栈
			p=p->lchild; 					//遍历左子树
		}
		if(top>0) 							//如果栈不空
		{
			p=stack[top-1]; 					//取栈顶元素
			if(p->rchild==NULL||p->rchild==q) 	//如果p没有右孩子结点,或右孩子结点已经访问过
			{
				printf("%2c",p->data); 			//访问根结点
				q=p;
				p=NULL;
				top--;
			}
			else
				p=p->rchild;
		}
	}
}
void QueueTraverse(BiTree T)
{
    BiTree queue[MaxSize];                   //定义一个队列,用于存放结点的指针
    int front=-1,rear=-1;                      //定义队列头,尾指针
    BiTree p;
    if(T==NULL)
    {
        return;
    }
    rear=(rear+1)%MaxSize;
    queue[rear]=T;                        //如果根结点不为空,则根结点先入队列
    while (front!=rear)
    {
        front=(front+1)%MaxSize;
        p=queue[front];                   //如果队列不为空,则出队一个节点
        printf("%2c",p->data);
        if(p->lchild)
        {
            rear=(rear+1)%MaxSize;
            queue[rear]=p->lchild;        //当前结点的左孩子不为空则入队
        }
        if(p->rchild)
        {
            rear=(rear+1)%MaxSize;
            queue[rear]=p->rchild;        //当前结点的右孩子不为空则入队
        }
    }
}
int GetHeight(BiTree T)
{
    int lh,rh;
    if(T==NULL)
    {
        return 0;                            //空树,深度0
    }
    lh=GetHeight(T->lchild);                 //递归调用获得左子树的深度
    rh=GetHeight(T->rchild);                 //递归调用获得右子树的深度
    if(lh>=rh)                               //取左右字树深度最大者,作为字树的深度,这个树的深度是字树深度加1
    {
        return lh+1;
    }
    return rh+1;
}
int CountLeaf(BiTree T)
{
    int lnum,rnum;
    if(T==NULL)
    {
        return 0;
    }
    lnum=CountLeaf(T->lchild);     //递归求左子树叶子结点个数
    rnum=CountLeaf(T->rchild);     //递归求右子树叶子结点个数
    if(lnum+rnum==0)
    {
        return 1;                  //如果左右字树叶子的和为0,说明是叶子结点返回1,否则返回左右子树叶子结点的和
    }
    else
    {
        return lnum+rnum;
    }
}
int NotLeafCount(BiTree T)
{
    if(T==NULL)
    {
        return 0;
    }
    if(!T->rchild && !T->lchild)    //如果是叶子结点,返回0
    {
        return 0;
    }
    return NotLeafCount(T->lchild)+NotLeafCount(T->rchild)+1;     //左右子树的非叶子结点数目加上根结点的个数
}

根据括号方式递归创建二叉树:

#include <iostream>
using namespace std;
struct BTree
{
    char ch;
    BTree *lchild,*rchild;
    BTree()
    {
        lchild=rchild=NULL;
    }
};
void PreOrder(BTree *root)
{
    if(root==NULL)
    {
        return;
    }
    printf("%c ",root->ch);
    PreOrder(root->lchild);
    PreOrder(root->rchild);
}

void PostOrder(BTree *root)
{
    if(root==NULL)
    {
        return;
    }
    
    PostOrder(root->lchild);
    PostOrder(root->rchild);
    printf("%c ",root->ch);
}
int cnt;
void CreatBinaryTree(BTree *&root,char *str)
{
    if(str[cnt]>='a' && str[cnt]<='z')//创建结点
    {
        root=new BTree;
        root->ch=str[cnt++];
    }
    if(str[cnt]=='(') //准备创建左右孩子
    {
        cnt++;
        CreatBinaryTree(root->lchild, str);
        CreatBinaryTree(root->rchild, str);
        
    }
    if(str[cnt]==',') //右子树创建完毕,返回
    {
        cnt++;
        return;
    }
    if(str[cnt]==')') //左右子树创建完毕,返回
    {
        cnt++;
        return;
    }
    
}
int main()
{
    BTree *root;
    cnt=0;
    char str[]="a(b(c,d),e(f,g))";
    char str2[]="a(b(d,e(h,)),c(f(,i),g(j,k)))";
    CreatBinaryTree(root, str2);
    PreOrder(root);
    printf("\n");
    PostOrder(root);
}



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值