二叉树及其操作

文章介绍了二叉树的基本概念,包括每个节点最多有两个孩子、树的深度、遍历顺序(先序、中序、后序)等。同时,提供了二叉树的创建方法,强调了输入处理以及用#表示空节点。文章还详细讲解了先序、中序和后序遍历的递归和非递归实现。
摘要由CSDN通过智能技术生成

二叉树:

首先了解一下树的概念:树是有n个节点的有限集,它可以为空树(n==0),而二叉树其具有以下性质:

1.二叉树是一种每个结点最多只有两个孩子的树。

2.每一个子集又是一颗树,叫做子树。

3.每一个可子树的根叫做根的孩子,而该子树又叫双亲。

4.具有相同双亲的结点称为兄弟。

5.树中结点的所在最大层次叫做树的深度。

6.树的访问顺序有先序,中序,后序,层次。

 先序就是中左右,中序就是左中右,后序就是左右中,层次就是逐层访问,从左到右。

二叉树基本操作:遍历二叉树

思想:二叉树通常以结构体形式来定义,主要包括三部分,节点存储的值,左孩子的节点,右孩子的节点。

对于先序遍历,就是来一个结点输出一个,所以是中左右,其实就是跟先序输入一样(创造二叉树

而对于中序遍历:就是找到一个最左的叶子结点,然后因为printf在中间,所以IN(l)没有,printf出来,IN(r)没有,会到上一个栈就是中间结点,他的printf在中间,所以他会先p再看IN(r)

5.2建立二叉树

重点:对于建立二叉树,对于每一个结点特别是叶子结点,要当没个结点度为二来输入,对于度为0当作(就是叶子结点)就要输入两个空,通常用‘#’来做标志。

 

//建立二叉树中每个子树结点 
struct TreeNode{
	int data;
	struct TreeNode*lchild;
	struct TreeNode*rchild;
}; BiNode,*BiTree;

//建立二叉树(二叉树的建立都是先序输入)
BiTree CreateTree(){
	int data;
	scanf("%d",&data);
	BiTree root;
	
	if(data <= 0){
		return Null;
		}else{
			root =(BiTree)malloc(sizeof(BiNode));
			root->data = data;
			root ->lchild = CreateTree();
			root->rchildc = CreateTree();
		}//off if 
	}
	return root;

5.3先序遍历:

先序遍历就是首先访问根结点,然后先序访问左子树,最后先序遍历根的右子树(就是说先把左边的访问完)

//先序访问PreorderTraverse(PT)(递归思想)
void PT(BiTree root){
	if(root){
		printf("%d ",root->data);
		PT(root->lchild);
		PT(root->rchild);
	}//off if
} //off PT

//非递归(栈思想)
void PT(BiTree root){
	BiTree stack[MaxSize];
	BiTree p;
	int top = -1;
	if(root != NULL){
		//根节点入站
		top++;
		stack[top] = root;
		while(top>-1){
			//出栈并且访问该节点
			p = stack[top];
			top--;
			printf("%d ",p->data);
			//右孩子入栈
			if(p->rchild ! = NULL){
				top++;
				stack[top] = p->rchild;
			} 
			//左孩子入栈
			if(p-lchild != NULL){
				top++;
				stack[top] = p-lchild;
			} 
		} //off while
	}//off if
} //off PT
 

5.4中序遍历:

中序遍历的过程是首先中序遍历左子树,然后访问根结点,最后中序遍历根的右子树。

//中序遍历二叉树:递归实现 
 void IT(BiTree root) {
     if (root) {
         InOrderTraverse(root->lchild);
         printf("%d ", root->data);
         InOrderTraverse(root->rchild);
     }off if
 } off IT

//中序遍历二叉树:非递归实现 
 void IT(BiTree root) {
     BiTree stack[MaxSize];
     BiTree p;
     int top = -1;
     if (root != NULL) {
         p = root;
         while (top > -1 || p != NULL) {
             //扫描p的所有左节点并入栈
             while (p != NULL) {
                 top++;
                 stack[top] = p;
                 p = p->lchild;
             } 
             if (top > -1) {
                 //出栈并访问节点
                 p = stack[top];
                 top--;
                 printf("%d ", p->data);
                 //扫描右孩子
                 p = p->rchild; 
             }//of if
         }off while
     } off if
 }off IT

5.5后序遍历

序遍历的过程是首先后序遍历左子树,然后后序遍历根的右子树,最后访问根结点。

//后序遍历二叉树:递归实现 
 void PostOrderTraverse(BiTree root) {
     if (root) {
         PostOrderTraverse(root->lchild);
         PostOrderTraverse(root->rchild);
         printf("%d ", root->data);
     }off if
 } off void

//后序遍历二叉树:非递归实现 
 void PostOrderTraverseNonRec(BiTree root) {
     BiTree stack[MaxSize];
     BiTree p;
     int top = -1;
     int sign; 
     if (root != NULL) {
         do {
             //root节点入栈
             while (root != NULL) {
                 top++;
                 stack[top] = root;
                 root = root->lchild;
             } 
             //p指向栈顶前一个已访问节点
             p = NULL;
             //置root为已访问
             sign = 1;
             while (top != -1 && sign) {
                 //取出栈顶节点
                 root = stack[top];
                 //右孩子不存在或右孩子已访问则访问root
                 if (root->rchild == p) {
                     printf("%d ", root->data);
                     top--;
                     //p指向被访问的节点
                      p = root; 
                  } else {
                     //root指向右孩子节点
                     root = root->rchild;
                     //置未访问标记
                     sign = 0; 
                  }
             }off while
         } while (top != -1);
     } off if
 }off void

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值