【C++/数据结构】二叉树

1)【实现二叉树的各种基本运算的算法】 

问题描述:该算法的设计,要求运行结果如下所示: 

二叉树的基本运算如下:

  (1)创建二叉树 

  (2)输出二叉树:A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))

  (3)H 结点:左孩子为 J 右孩子为 K

  (4)二叉树 bt 的高度:7

  (5)释放二叉树 bt

2)【实现二叉树的 3 种遍历算法】 

问题描述:该算法的设计,要求运行结果如下所示: 

二叉树 bt:A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))

***层次遍历序列:A B C D E F G H I J K L M N

先序遍历序列:

递归算法:A B D E H J K L M N C F G I   

非递归算法:A B D E H J K L M N C F G I

中序遍历序列:

递归算法:D B J H L K M N E A F C G

非递归算法:D B J H L K M N E A F C G I

后序遍历序列:

递归算法:D J L N M K H E B F I G C A

  ***非递归算法:D J L N M K H E B F I G C A

3)【查找与定位算法】

 问题描述:定位二叉树 bt 中结点值为 x 的结点及其所在的层次 

4)【路径问题】 

问题描述:采用先序遍历方法输出所有从叶子结点到根结点的逆路径。 

二叉树 b:A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))

先序遍历方法:

   D 到根结点逆路径: D->B->A

   J 到根结点逆路径: J->H->E->B->A

   L 到根结点逆路径: L->K->H->E->B->A

   N 到根结点逆路径: N->M->K->H->E->B->A

   F 到根结点逆路径: F->C->A

   I 到根结点逆路径: I->G->C->A    

   第一条最长逆路径长度:7

   第一条最长逆路径:N M K H E B A

 

二叉树

 

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <queue>
#include <stack>
using namespace std;
//采用先序遍历方法输出所有从叶子结点到根结点的逆路径。 

typedef struct BiTNode{
	char data;
	struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
int depth=0;//全局变量 树深  
char longestpath[50];



void CreateBiTree(BiTree &T);//按先序次序输入二叉树中结点的值,构造二叉链表表示的二叉树T。
void BiTreeLevelOrder(BiTree t);
void Print(BiTree T );//输出二叉树
void Child(BiTree T,char e);//H 结点:左孩子为J 右孩子为K 
int BiTreeDepth(BiTree T);// 二叉树bt 的高度:7

void PreOrderTraverse(BiTree T);//先序遍历 
void PreOrderTraverse_NonRecursion(BiTree T);//先序遍历 非递归 

void InOrderTraverse(BiTree T);//中序遍历 
void InOrderTraverse_NonRecursion(BiTree T);//中序遍历 非递归 
void PostOrderTraverse(BiTree T);//后序遍历 
void PostOrderTraverse_NonRecursion(BiTree T);//后序遍历 非递归 
void Assign(BiTree T,char e) ;//定位二叉树 bt 中结点值为 x 的结点及其所在的层次。 
void pathBiTree(BiTree T);//采用先序遍历方法输出所有从叶子结点到根结点的逆路径。
void BiTreeDestroy(BiTree &T);//释放二叉树
int BiTreeDepth(BiTree T);// 二叉树bt 的高度:7

int main(int argc, char** argv) {
	BiTree bt;
	CreateBiTree(bt);
	
	printf("输出二叉树:\n");
	Print(bt); printf("\n");
	
	Child(bt,'H');
	
	cout<<"depth:"<<BiTreeDepth(bt)<<endl;

	printf("层次遍历:\n");
	BiTreeLevelOrder(bt);
		
	printf("\n\n先序遍历:\n");
	PreOrderTraverse(bt);
	printf("\n\n先序遍历非递归算法:\n");
	PreOrderTraverse_NonRecursion(bt);
	
	printf("\n\n中序遍历:\n");
	InOrderTraverse(bt);
	printf("\n\n中序遍历非递归算法:\n");
	InOrderTraverse_NonRecursion(bt);//中序遍历 非递归 
	
	printf("\n\n后序遍历:\n");
	PostOrderTraverse(bt);
	printf("\n\n后序遍历非递归:\n");
	PostOrderTraverse_NonRecursion(bt);
	
	
	Assign(bt ,'E') ;
		
	pathBiTree(bt);
	printf("\n\n第一条最长逆路径长度为:%d ",depth);
	printf("\n\n第一条最长逆路径为:");
	for(int j=depth;j>=1;j--)
	printf(" %c ",longestpath[j]);


	BiTreeDestroy(bt);
	return 0;
}


void CreateBiTree(BiTree &T)
{
    //  按先序次序输入二叉树中结点的值
    //  构造二叉链表表示的二叉树T。
    char	ch;
    static	int	i = 0;
    int j=0;
    char pch[ ]="ABD$$EHJ$$KL$$M$N$$$CF$$G$I$$";	// 欲产生的 先序序列。
    //printf("\n静态变量i的值分别为:%d\n", i);
    //scanf("%c",&ch);
    ch = pch[i++];

    if(ch == '$') 										// 空树
        T = NULL;
    else {
        T = (BiTree)malloc(sizeof(BiTNode));
        if(!T)											// 检测是否申请结点成功
        exit(-1);
        T->data = ch; 									// 生成根结点
        CreateBiTree(T->lchild); 						// 构造左子树
        CreateBiTree(T->rchild); 						// 构造右子树
    }
}

void BiTreeLevelOrder(BiTree t)
{//用队列实现
    queue<BiTNode*>tq;//创建队列tq,队列的每个元素都是结点指针
    BiTNode* p=t;//p为一个指针,初始时指向根节点 
    if(p!=NULL)
    {
        tq.push(p);//根节点入队 
    }
    while(!tq.empty())//树不为空时 
    {
        p = tq.front();//出队 
        cout << p->data;
        tq.pop();
        cout<<" ";
        if(p->lchild)
        {
			tq.push(p->lchild);
		}
        if(p->rchild)
        {
			tq.push(p->rchild);
		}
    }
}

void PreOrderTraverse(BiTree T)//先序遍历 
{
	if(T!=NULL)
	{
		printf("%c ",T->data);
		PreOrderTraverse(T->lchild);
		PreOrderTraverse(T->rchild);
	}
	else return;
}


void PreOrderTraverse_NonRecursion(BiTree T)//先序遍历 非递归 
{
	BiTree stack[50];
	int top=-1;
	while((top!=-1)||T) 
	{
		while(T)
		{
			printf("%c ",T->data);
			stack[++top]=T;
			T=T->lchild; //遍历左子树 
			
		}
		if(top!=-1)
		{
			T=stack[top--];
			T=T->rchild;//遍历右子树 
		}
	}
}


void InOrderTraverse(BiTree T)//中序遍历 
{
	if(T!=NULL)
	{
		InOrderTraverse(T->lchild);
		printf("%c ",T->data);
		InOrderTraverse(T->rchild);
	}
	else return;
}


void InOrderTraverse_NonRecursion(BiTree T)//中序遍历 非递归 
{
	BiTree stack[50];
	int top=-1;
	while(top!=-1||T) 
	{
		while(T)
		{
			stack[++top]=T;
			T=T->lchild; //遍历左子树 
		}
		
		if(top!=-1)
		{
			T=stack[top--];
			printf("%c ",T->data);
			T=T->rchild;//遍历右子树 
		}
	}
}



void PostOrderTraverse(BiTree T)//后序遍历 
{
	if(T!=NULL)
	{
		PostOrderTraverse(T->lchild);
		PostOrderTraverse(T->rchild);
		printf("%c ",T->data);
	}
	else return;
}

void PostOrderTraverse_NonRecursion(BiTree T)//后序遍历 非递归 
{
    stack<BiTree>S;
    BiTree p=T;
    BiTree last=T;
    S.push(p);
    while(!S.empty())
    {
        p=S.top();
        if((p->lchild==NULL && p->rchild==NULL) ||
            (p->rchild==NULL && last==p->lchild) ||
            (last==p->rchild))
        {
            cout<<p->data<<" ";
            last=p;
            S.pop();
        }
        else
        {

            if(p->rchild)
                S.push(p->rchild);
            if(p->lchild)
                S.push(p->lchild);
        }
    }
}

void Assign(BiTree T,char e) //定位二叉树 bt 中结点值为 x 的结点及其所在的层次
{
	static int i=0;
	if(T!=NULL)
	{
		i++;
		if(T->data==e)
		{
			printf("\n\n结点值为 %c 处在第 %d 层 。",e,i);
			return; 
		}
		Assign(T->lchild,e);
		Assign(T->rchild,e);
 		i--;
	}
} 
void pathBiTree(BiTree T)
{
	static char path[50];
	static int i=0;
	if(T)
	{		
		if(T->lchild==NULL&&T->rchild==NULL)
		{
			printf("\n\n %c的路径为: %c",T->data,T->data);
			for(int j=i;j>0;j--)
			printf("->%c",path[j]);
			if((i+1)>depth)
			{
				depth=i+1;
				longestpath[depth]=T->data;
				for(int j=1;j<=i;j++)
				longestpath[j]=path[j];
			}
			return;
		}		
		else
		{
			i++;
			path[i]=T->data;
			pathBiTree(T->lchild);
			pathBiTree(T->rchild);	
			i--;
		}				
	}
}

void Print(BiTree T )//输出二叉树:A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I))) 中序遍历 
{
	if(T)
	{
		
		if(!T->lchild&&!T->rchild)
		{
			printf("%c",T->data);
			return;
		}
		printf("%c",T->data);
		printf("(");
		Print(T->lchild);
		if(T->rchild)
		{
			printf(",");
			Print(T->rchild);
		}
		printf(")");	
	}
	
}

void Child(BiTree T,char e)//H 结点:左孩子为J 右孩子为K 
{
	if(T==NULL)
	return ;
	if(T->data==e)
	{
		if(T->lchild)
		{
			printf("left child :%c\n",T->lchild->data);
		}
		else {
			printf("没有左孩子\n");
		}
		if(T->rchild)
		{
			printf("right child :%c\n",T->rchild->data);
		}
		else {
			printf("没有右孩子\n");
		}
		return ;
	}
	else
	{
		Child(T->lchild,e);
		Child(T->rchild,e);
	}
}

int BiTreeDepth(BiTree T)// 二叉树bt 的高度:7
{
	if(T==NULL)
	return 0;
	else if(T->lchild==NULL&&T->rchild==NULL)
	return 1;
	else 
	return 1+max(BiTreeDepth(T->lchild),BiTreeDepth(T->rchild));
}

void BiTreeDestroy(BiTree &T)//释放二叉树
{
	if(T!=NULL)
	{
		if(T->lchild) BiTreeDestroy(T->lchild);
		if(T->rchild) BiTreeDestroy(T->rchild);
		free(T);
		T=NULL;
	}
	
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值