C语言学习-day09

二叉树的链式存储结构:

//二叉树的链式存储
typedef struct BiTNode{
	int data;//用于存储二叉树结点的值
	struct BiTNode *lchild, *rchild;//两个二叉树结点指针分别二叉树的左孩子和右孩子
}BiTNode,*BiTree;

函数:先序遍历的顺序建立二叉树

输入:二叉树的结构体变量地址:BiTree &T。其成员是int data;(用于存储二叉树结点的值)struct BiTNode *lchild, *rchild;(两个二叉树结点指针分别二叉树的左孩子和右孩子)。

输出:无

优化目标:无,但我这里是以先序遍历的创建的二叉树,还可以使用中序遍历和后序遍历的方法创建

//先序遍历的顺序建立二叉树
void CreateBiTree(BiTree &T){
	int ch;
	if(ch == -1){
		T =NULL;
	}
	else{
		T = (BiTNode *)malloc(sizeof(BiTNode));
		T->data = ch;
		CreateBiTree(T->lchild);
		CreateBiTree(T->rchild);
	}
}

该函数的思想,主要是要明白先序(或中序、后序)遍历方法,首先判断要创建的结点是否为叶子结点,如果不是,就为该结点创建分配空间,然后就依次对其左孩子和右孩子以相同的方法创建。

函数:计算二叉树的深度

输入:二叉树的结构体变量:BiTree T。其成员是int data;(用于存储二叉树结点的值)struct BiTNode *lchild, *rchild;(两个二叉树结点指针分别二叉树的左孩子和右孩子)。

输出:树的深度

优化目标:无

//计算二叉树的深度
int Depth(BiTree T){
	if(T == NULL){
		return 0;
	}
	else{
		int m = Depth(T->lchild);
		int n = Depth(T->rchild);
		if(m<n){
			return n+1;
		}
		else{
			return m+1;
		}
	}
}

该函数的思想:主要是通过递归,如果T不为空,就去递归调用该函数(其左孩子和右孩子)然后,比较两个哪个大,最大的就是该层的深度-1,所以返回最大的+1,最后就可以返回树的深度。

函数:复制二叉树

输入:一个二叉树的结构体变量:BiTree T。其成员是int data;(用于存储二叉树结点的值)struct BiTNode *lchild, *rchild;(两个二叉树结点指针分别二叉树的左孩子和右孩子)。

        另一个二叉树的结构体变量地址:BiTree &NewT。其成员是int data;(用于存储二叉树结点的值)struct BiTNode *lchild, *rchild;(两个二叉树结点指针分别二叉树的左孩子和右孩子)。

输出:无

优化目标:无,同样我这里是以先序遍历的去遍历二叉树的同时进行复制,还可以使用中序遍历和后序遍历的方法复制

//复制二叉树
void Copy(BiTree T,BiTree &NewT){
	if(T == NULL){
		NewT = NULL;
		return;
	}
	else{
		NewT = (BiTNode *)malloc(sizeof(BiTNode));
		NewT->data = T.data;
		Copy(T->lchild,NewT->lchild);
		Copy(T->rchild,NewT->rchild);
	}
}

该函数的思想:就是在对该二叉树进行遍历的过程中,对二叉树一个结点一个结点的复制。

函数:几个统计函数,统计二叉树中结点、叶子结点、度为1、度为2的结点数量

输入:一个二叉树的结构体变量:BiTree T。其成员是int data;(用于存储二叉树结点的值)struct BiTNode *lchild, *rchild;(两个二叉树结点指针分别二叉树的左孩子和右孩子)。

输出:分别计算出二叉树中结点、叶子结点、度为1、度为2的结点的数量

优化目标:无

//统计二叉树中结点的个数
int NodeCount(BiTree T){
	if(T == NULL){
		return 0;
	}
	else{
		return NodeCount(T->lchild) + NodeCount(T->rchild) + 1;
	}
}

//统计二叉树中叶子结点的个数
int LeafCount(BiTree T){
	if(T->lchild == NULL && T->rchild == NULL){
		return 1;
	}
	else{
		return LeafCount(T->lchild) + LeafCount(T->rchild);	
	}
}

//统计二叉树中度为1的结点的个数
int OneCount(BiTree T){
	if(T == NULL){
		return 0;
	}
	if((T->lchild == NULL && T->rchild != NULL) || (T->rchild == NULL &&T->lchild != NULL)){
		return OneCount(T->lchild) + OneCount(T->rchild) + 1;
	}
	else{
		return OneCount(T->lchild) + OneCount(T->rchild);	
	}
}

//统计二叉树中度为2的结点的个数
int TwoCount(BiTree T){
	if(T == NULL){
		return 0;
	}
	if(T->rchild != NULL && T->lchild != NULL){
		return TwoCount(T->lchild) + TwoCount(T->rchild) + 1;
	}
	else{
		return TwoCount(T->lchild) + TwoCount(T->rchild);	
	}
}

该函数的思想:就是利用递归,判断其是否为对应的结点,然后返回其左右孩子同样类型的结点树+1,就可以完成了。

函数:二叉树的先序和中序遍历

输入:一个二叉树的结构体变量:BiTree T。其成员是int data;(用于存储二叉树结点的值)struct BiTNode *lchild, *rchild;(两个二叉树结点指针分别二叉树的左孩子和右孩子)。

输出:无(但在遍历的过程中会将二叉树中的结点进行输出)

优化目标:无(是昨天递归的先序和中序遍历的优化)

//先序遍历(非递归)
void PreOrder(BiTree T){
	InitStack(S);
	BiTNode *p = T;
	while(p!=NULL || !IsEmpty(S)){
		if(p != NULL){
			printf("%d  ",p->data);
			Push(S,p);
			p = p->lchild;
		}
		else{
			Pop(S,p);
			p = p->rchild;
		}
	}
}

//中序遍历(非递归)
void InOder(BiTree T){
	InitStack S;
	BiTNode *p = T;
	while(p!=NULL || !IsEmpty(S)){
		if(p != NULL){
			Push(S,p);
			p = p->lchild;
		}
		else{
			Pop(S,p);
			printf("%d  ",p->data);
			p = p->rchild;
		}
	}
}

该函数的思想:利用栈的先进后出的特性写的,当我们遍历到一个结点的时候,就将其压入栈中,只要栈不空或p不为空的时候说明p还在遍历二叉树。此时如果是先序遍历的话,如果p不为空意思是p是二叉树的结点,然后将p的值输出,再将p压入栈中,p再往左孩子结点走,如果p为空,意思是已经p走到空结点了,就要往回走了,让p等于栈的最后一个结点,往该结点的右孩子结点走,然后依次先访问左孩子结点,然后访问右孩子结点,以至于访问完所有结点。而中序遍历与先序遍历类似,只是中序是在p走到空的时候,往回走的pop之后进行输出。

函数:层次遍历

输入:一个二叉树的结构体变量:BiTree T。其成员是int data;(用于存储二叉树结点的值)struct BiTNode *lchild, *rchild;(两个二叉树结点指针分别二叉树的左孩子和右孩子)。

输出:无

优化目标:无

//层次遍历(非递归)
void LevelOrder(BiTree T){
	InitQueue(Q);
	BiTNode *p = T;
	EnQueue(Q,p);
	while(!IsEmpty(S)){
		DeQueue(Q,p);
		printf("%d  ",p->data);
		if(p->lchild!=NULL){
			EnQueue(Q,p->lchild);
		}
		if(p->rchild!=NULL){
			EnQueue(Q,p->rchild);
		}
	}
}

函数思想:利用队列的先进先出的特性,先将首结点入队,再依次对队列的结点出队后输出,然后依次将该结点的左孩子和右孩子入队,当队列为空的时候就结束了。

今天主要是复习了一下二叉树的几个函数,在对非递归的遍历先看了别人的遍历,然后自己去写,主要是原本知道要用栈和队列,但是还以为对于栈和队列内的值是一个整型,结果是要存储二叉树的结点,所以还是需要再多学习学习。明天的打算是去做一下哈夫曼树。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值