树和二叉树


树和二叉树

//树的表示

//儿子-兄弟表示法
// Element-FirstChild-NextSibling
//n个结点,2n个指针域,n-1个指针域非空 
//向右旋转45°->二叉树
//Element Left Right

//二叉树

//链表存储
 
typedef struct TreeNode *BinTree;
typedef BinTree Position
struct TreeNode{
	ElementType Data;
	BinTree Left;
	BinTree Right;
};

//二叉树的遍历——递归 

//1.先序遍历 

void PreOrderTraversal(BinTree BT)
{
	if(BT){
		printf("%d",BT->Data);//如果非空,先访问根结点 
		PreOrderTraversal(BT->Left);//对左子树递归 
		PreOrderTraversal(BT->Right);//对右子树递归 
	}
}

//2.中序遍历 

void PreOrderTraversal(BinTree BT)
{
	if(BT){
		PreOrderTraversal(BT->Left);//对左子树递归 
		printf("%d",BT->Data); 
		PreOrderTraversal(BT->Right);//对右子树递归 
	}
}

//3.后序遍历 

void PreOrderTraversal(BinTree BT)
{
	if(BT){
		PreOrderTraversal(BT->Left);//对左子树递归 
		PreOrderTraversal(BT->Right);//对右子树递归 
		printf("%d",BT->Data); 
	}
}

//先序,中序和后序遍历过程:遍历过程中经过结点的路线
//一样,只是访问各结点的时机不同 ->此处有个黑科技 

//二叉树的非递归遍历 

//中序遍历非递归遍历算法
//基本思路:使用堆栈
//遇到一个结点,把它压栈,并去遍历它的左子树 
//当左子树遍历结束后,从栈顶弹出这个结点并访问它 
//然后按其右指针在取中序遍历该节点的右子树

void InOrderTraversal(BinTree BT)
{
	BinTree T=BT;
	Stack S=CreatStack(MaxSize);//创建并初始化堆栈S 
	while(T||!IsEmpty(S)){//树或堆栈不空 
		while(T){//树不空 一直向左并将沿途结点压入堆栈 
			push(S,T);//(1)
			T=T->Left;
		}
		if(!IsEmpty(S)){//堆栈不空 
			T=Pop(S);//结点弹出堆栈 (2)
			printf("%5d",T->Data);//访问打印结点 
			T=t->Right;//转向右子树 
		}
	}
}


//先序遍历 把printf语句调整到(1)处 
void PreOrderTraversal(BinTree BT)
{
	BinTree T=BT;
	Stack S=CreatStack(MaxSize);//创建并初始化堆栈S 
	while(T||!IsEmpty(S)){//树或堆栈不空 
		while(T){//树不空 一直向左并将沿途结点压入堆栈 
			push(S,T);//(1)
			printf("%5d",T->Data);//访问打印结点 
			T=T->Left;
		}
		if(!IsEmpty(S)){//堆栈不空 
			T=Pop(S);//结点弹出堆栈 (2)
			T=t->Right;//转向右子树 
		}
	}
}

//后序遍历怎么实现?

//层序遍历:队列实现
//基本过程:先根结点入队,然后 
//1.从队列中取出一个元素
//2.访问该元素所指结点
//3.若该元素所指结点的左、右孩子结点非空,
//则将其左、右孩子的指针顺序入队

void LevelOrderTraversal(BinTree BT) 
{
	Queue Q;
	BinTree T;
	if(!BT)//若是空树直接返回 
		return;
		Q=CreateQueue(MaxSize);//创建并初始化队列Q 
		AddQ(Q,BT);
		while(!IsEmptyQ(Q)){
			T=DeleteQ(Q);
			printf("%d\n",T->Data);//访问取出队列的结点 
			if(T->Left)
				AddQ(Q,T->Left);
			if(T->Right)
				AddQ(Q,T->Right);
		}
}

//遍历二叉树的应用:输出二叉树中的叶子结点
//在二叉树遍历算法中增加检测结点的“左右子树是否都为空”

//改造先序遍历 
void PreOrderPrintLeaves(BinTree BT)
{
	if(BT){
		if(!BT->Left&&!BT->Right)
			printf("%d",BT->Data);
		PreOrderPrintLeaves(BT->Left);
		PreOrderPrintLeaves(BT->Right);
	}
}

//求二叉树的高度
//Height=Max{Hl,Hr}+1 

//改造后序遍历
int PostOrderGetHeight(BinTree BT)
{
	int HL,HR,MaxH;
	if(BT){
		HL=PostOrderGetHeight(BT->Left);//求左子树的深度 
		HR=PostOrderGetHeight(BT->Right);//求右子树的深度 
		MaxH=(HL>HR)?HL:HR;//取左右子树较大的深度 
		return(MaxH+1);//返回树的深度 
	}
	else 
		return 0;//空树深度为0 
} 

//二元运算表达式树及其遍历
//先序遍历得到前缀表达式
//中序遍历得到中缀表达式/中缀表达式会受到运算符优先级的影响 ->加括号解决 
//后序遍历得到后序表达式 

//由两种遍历序列确定二叉树:必须要有中序遍历才可以 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值