二叉树的相关算法

0、二叉树的结点表示

if(p->lchild != NULL && p->rchild != NULL)//度为2的结点,左右孩子同时不空
if((p->lchild == NULL && p->rchild != NULL) || (p->lchild != NULL && p->rchild == NULL))//度为1的结点,左孩子不为空,或者右孩子不为空
if(p->lchild == NULL && p->rchild == NULL)//度为0的结点,两个孩子都为空

1、二叉树的先序遍历递归与非递归

void preorder(BiTree T)
{
		if(T != NULL)
		{
				visit();
				preorder(T->lchild);
				preorder(T->rchild);
		}
}
//一直入栈往左走,到头出栈掉个头
void preorder(BiTree T)
{
		InitStack(S);
		p = T:
		while(p != NULL || !StackEmpty(S))
		{
					if(p !=NULL)
					{
								printf(p->data);
								push(S,p);
								p = p->lchild;
					}
					else
					{
								pop(S,p);
								p = p->rchild;
					}
		}
}

2、二叉树的中序遍历

void Inorder(BiTree T)
{
		if( T != NULL)
		{
					Inorder(T->lchild);
					visit(T);
					Inorder(T->rchild);
		}
}
void Inorder(BiTree T)
{
		InitStack(S);
		p = T;
		while(p != NILL || !StackEmpty(S))
		{
					if(p != NULL)
					{
							push(S,p);
							p = p->lchild;		
					}
					else
					{
								pop(S,p);
								printf(p->data);
								p = p->rchild;
					}
		}
}

3、二叉树的后序遍历

void postorder(BiTree T)
{
		if(T != NULL)
		{
					postOrder(T->lchild);
					postorder(T->rchild);
					visit(T);
		}
}
void PostOrder(BiTree T)
{
		InitStack(T);
		p = T;
		while(p != NULL || !StackEmpty(s))
		{
				if(p != NULL)
				{
							push(S,p);
							p = p->lchild;
				}
				else
				{
							pop(S,p);
							if(p->rchild == NULL && (p->rchild).tag == 0)//如果右孩子为空或者标志位为0则
							{
										push(S,p);
										p = p->rchild;
							}
							else//如果top的右孩子为空且没有被访问过则输出
							{
										printf(p->data);
										p.tag = 1;
										p = NULL;
							}
				}
		}
}

4、二叉树的层序遍历算法

void LevelOrder(BiTree T)
{
		InitQueue(Q);
		BiTree p;
		EnQueue(Q,T);
		while(!IsEmpty(Q))
		{
				DeQueue(Q,p);
				visit(p);
				if(p->lchild != NULL)
						EnQueue(Q,p->lchild);
				if(p->rchild != NULL)
						EnQueue(Q,p->rchild);
		}
}

void levelorder(BiTree T)
{
		BiTree Q[MAXSIZE];
		BiTree p = T;
		int front = -1,rear = -1;
		int last = 0,level = 0;
	
		Q[++rear] = T;
		while(front < rear)//队列不为空
		{
				p = Q[++front];
				if(p->lchild)
						Q[++rear] = p->lchild;
				if(p->rchild)
						Q[++rear] = p->rchild;
		}
}

5、编写二叉树自下而上,从右到左的层序遍历算法
算法思想
一般的二叉树层序遍历是自上而下,从左到右的顺序,可以将每一次访问的结点入栈,遍历结束后在出栈

void LevelOrder(BiTree T)
{
		InitQueue(Q);
		InitStack(S);
		BiTree p = T;
		EnQueue(Q,p);
		while(!isEmpty(Q))
		{
					DeQueue(Q,p);
					posh(S,p);
					if(p->lchild != NULL)
					{
								Enqueue(Q,p->lchild);
					}
					if(p->rchild != NULL)
					{
								Enqueue(Q,p->rchild)
					}
		}
		while(IsEmpty(s))
		{
					pop(S,p);
					visit(p->data);
		}
}

6、求二叉树中层序的最高度

int Bidepth(BiTree T)
{
		if(T == NULL)
		{
				return 0;
		}
		else
		{
				BiTree Q[Maxsize];
				BiTree p;
				int front = -1,rear = -1;
				int last = 0,level = 0;

				Q[++rear] = T;
				while(front < rear)
				{
						p = Q[++front];
						if(p->lchild != NULL)
								Q[++rear] = p->lchild;
						if(p->rchild != NULL)
								Q[++rear] = p->rchild;
						if(front == level)
						{
									level++;
									last = rear;//last指向当前层数的最右结点,这个地方不是很理解,硬记!
						}
			}
		}
}

7、求二叉树中宽度

int Width(BiTree T)
{
		if(T == NULL)
		{
					return 0;
		}
		else
		{
					BiTree Q[MAXSIZE];
					BiTree p;
					int front = -1,rear = -1;
					int last = 0,count = 0;
	
					Q[++rear] = T;
					while(front < rear)
					{
							p = Q[++front];
							temp++;
							if(p->lchild != NULL)
									Q[++rear] = p->lchild;
							if(p->rchild != NULL)
									Q[++rear] = p->rchild;
							if(front > last)//不是很理解为啥
							{
										last = rear;//为沙
										if(temp > maxw)
												maxw = temp;
										temp = 0;
							}
					}
		}
		return maxw;
}

8、计算二叉树所有结点个数

int Node(BiTree T)
{
		int num1,num2;
		if(T == NULL)
				return 0;
		else
		{
				num1 = Node(T->lchild);
				num2 = Node(T->rchild);
				return (num1 + num2 + 1);//因为有根结点所有要+1
		}
}

9、计算二叉树所有的叶子结点(度为1的结点)

int Node(BiTree T)
{
		if(T == NULL)
				return 0;
		else if(T->lchild == NULL && T->rchild == NULL)
				return 1;
		else
		{
				num1 = Node(T->lchild);
				num2 = Node(T->rchild);
				return num1+num2;
		}
}

10、计算二叉树中双分支结点(度为2的结点)

int Node(BiTree T)
{
		if(T == NULL)
				return 0;
		else if(T->lchild == NULL || T->rchild == NULL)//当n为单分支时不计算
				n = 0;
		else//当为双分支时n=1
				n = 1;
		num1 = Node(T->lchild);
		num2 = Node(T->rchild);
		return (num1+num2+n)
}
int

11、求二叉树中最小值的结点

int FindMinNode(BiTree T)
{
		if(T != NULL)
		{
				if(T->data < min)
				{
							min = T->data;
				}
				FindMinNode(T->lchild,min);
				FindMinNode(T->rchild,min);
		}
}

int preorder(BiTree T)
{
		min = 0
		if(T != NULL)
		{
				if(min > T->data)
						min = T->data;
				preorder(T->lchild);
				preorder(T->rchild);
		}
		return min;
}

12、求二叉树所有结点值的和

int Findsum(BiTree T)
{
		if(T == NULL)
				return 0;
		else
				return (T->data + Findsum(T->lchild) + Findsum(T->rchild));

}
int preorder(BiTree T)
{
		int sum = 0
		if(T != NULL)
		{
				sum += T->data;
				preorder(T->lchild);
				preorder(T->rchild);
		}
		return sum;
}

13、求二叉树中值为x的结点

int FindCount(BiTree T,int x)
{
			count = 0;
			if(T != NULL)
			{
					if(T->data == x)
							count++;
					FindCount(T->lchild);
					FindCount(T->rchild);
			}
			return count;
}
int FindCount(BiTree T,int x)
{
		if(T == NULL)
				return 0;
		else if(T->data == x)
				return (1+FindCount(T->lchild,x) + FindCount(T->rchild,x));
		else
				return (FindCount(T->lchild,x) + FindCount(T->rchild,x));
}

14、求二叉树结点的高度

int Depth(BTNode *T)
{
		if(T == NULL)
				return 0;
		else
		{
				ldeep = Depth(T->lchild);
				rdeep = Depth(T->rchild);
				return (ldeep > rdeep):(ldeep + 1):(rdeep + 1);//加1是因为根结点
		}
}

15、求指定值x的双亲结点p(没看懂)
算法思想
在二叉树中查找x的双亲结点,找到后p指向x结点的双亲结点否则p=NULL,当b为空或根结点为x时,p=NULL

void FindParent(BiTree T,int x,BiTree &p)
{
		if(T != NULL)
		{
				if(T->data == x)
				{
						p = NULL;
				}
				else if(T->lchild != NULL && T->lchild->data == x)//如果T->lchild 不为空或者T->lchild==x则
				{
						p = b;
				}
				else if(T->rchild != NULL && T->rchild->data == x)
				{
						p = b;
				}
				else
				{
							FindParent(T->lchild,x,p);
							if(p == NULL)
									FIndParent(T->rchild,x,p);
				}
		}
		else
		{
				p = NULL;
		}
}

16、交换树b的左右子树

void Swap(BiTree T)
{
		BiTree *Temp;
		if(T != NULL)
		{
				Swap(T->lchild);
				Swap(T->rchild);
				temp = T->lchild;
				T->lchild = T->rchild;
				T->rchild = temp;
		}
}

17、求二叉树T中值为x的层号

int level(BiTree T)
{
		InitQueue(Q);
		P = T;
		Enqueue(Q,p);
		while(!IsEmpty(Q))
		{
				DeQueue(Q,p);
				visit(p);
				if(p->lchild != NULL)
						Enqueue(Q,p->lchild);
				if(p->rchild != NULL)
						Enqueue(Q,p->rchild);
		}
}
int level(BiTree T)
{
		if(T == NULL)
		{
					return 0;
		}
		else
		{
				BiTree Q[MAXSIZE];
				BiTree p;
				int front = -1,rear = -1;
				int last = 0,level = 0;
		
				Q[++rear] = T;
				while(front < rear)
				{			
							p = Q[++front];
							if(p->data == x)
									return level;
							if(p->lchild != NULL)
							{
										Q[++rear] = p->lchild;
							}
							if(p->rchild != NULL)
							{
										Q[++rear] = p->rchild;							
							}
							if(front == level)
							{
										level++;
										last = rear;
							}
				}
		}
}
int NodeLevel(BiTree T,int x,int h)
{
		int h1;
		if(T == NULL)
				return 0;
		else if(T->data == x)
				return h;
		else
		{
				h1 = NodeLevel(T->lchild,x,h+1);//在左子树中递归查找
				if(h1 == 0)//为沙呀,没看懂
						return NodeLevel(T->rchild,x,h+1);//左子树中为找到在右子树查找
				else
						return h1;
		}
}

18、求先序遍历中第k个结点的值
算法思想
用全局变量n保存先序遍历时访问结点,
当二叉树为空时返回空,
当k==n时表示找到结点,
当k!=n时,在左子树找,若找到返回,否则在右子树找,返回

int preorder(BiTree T,int k)
{	
		int count = 0;
		p = T;
		if(p != NULL)
		{
				if(k == count)
						visit(p->data);
				count++;
				preorder(p->lchild);
				preorder(p->rchild);
		}
}
int preNode(BiTree T,int k)
{
		if(T == NULL)
				return 0;
		if(n == k)
				return T->data;
		n++;
		ch = PreNode(T->lchild,k);
		if(ch != NULL)
				return ch;
		ch = PreNode(T->rchild,k);
				return ch;
}

19、中序遍历中第k的结点

ElemType InNOde(BiTree T,int k)
{
		if(T == NULL)
		{
				return 0;
		}
		ch = InNode(T->lchild);//在左子树中找
		if(ch != NULL)//找到返回
				return ch;
		else//在右子树找
		{
				if(n == k)
						return T->data;
				n++;
				return InNode(T->rchild,k);
		}

}

20、后序遍历中第k的结点

ElemType PostNode(BiTree T,int k)
{
		if(T == NULL)
				return 0;
		ch = postnode(T->lchild,k);
		if(ch != NULL)
				return ch;
		else
		{
				ch = postNode(T->rchild,k);
				if(ch != NULL)
						return ch;
				if(n == k)
						return T->data;
				n++;
		}
}

21、求二叉树的WPL
算法思想
基于先序遍历,记录每个wpl把每个结点的深度作为递归函数的一个参数

int wpl_preorder(BiTree T,int deep)
{
		int wpl = 0;
		if(T->lchild == NULL && T->rchild == NULL)//叶子结点,度为0的结点计算wpl
				wpl = wpl + deep*T->weight;
		if(T->lchild != NULL)
				wpl_preorder(T->lchild,deep+1);
		if(T->rchild != NULL)
				wpl_preorder(T->lchild,deep+1);
		return wpl;
}

22、将二叉树转为中缀表达式,通过括号反映出优先级次序
算法思想
如果是叶子结点输出,除根结点外,遍历左子树之前加左括号,遍历完右子树加右括号

typedef struct Node
{
		char data[10];
		struct node *left,*right;
}BiTree;
void BtreeToExp(BiTree T,int deep)
{
		if(T == NULL)
				return 0;
		else if(T->left === NULL && T->right == NULL)//如果是叶子结点则输出
				print(T->data);
		else
		{
				if(deep > 1)	//若有子表达式,则加括号	
					printf("(");
				BtreeToExp(T->left,deep+1);
				printf(T->data);
				BtreeToExp(T->right,deep+1);
				if(deep > 1)//加括号
					printf(")");
		}
}

23、输出从根到叶子结点的路径

int path(BiTree *p)
{
		int i = 0,top = 0;
		ElemType stack[MAXSIZE];
		if(p != NULL)
		{
				stack[++top] = p->data;
		}
		if(p->lchild == NULL && p->rchild == NULL)
		{
				for(i = 0;i < top;i++)
				{
						printf(stack[i]);
				}
		}
		path(p->lchild);
		path(p->rchild);
		--top;
}

24、判断二叉树是否为完全二叉树
算法思想
如果树为空,则直接返回错。
如果树不为空,层次遍历二叉树 ;
如果树左孩子为空,右孩子不为空,则该树一定不是完全二叉树;
如果树左右孩子都不为空,则pop该节点,将其左右孩子入队列;
如果树左孩子不为空,右孩子为空;或者左右孩子都为空;则该节点之后的队列中的结点都为叶子节点;
该树才是完全二叉树,否则就不是完全二叉树。

void level(BiTree T)
{
		InitQueue(Q);
		EnQueue(Q,T);
		if(T == NULL)
				return 0;
		while(!isempty(Q))
		{
				if(T->lchild == NULL && T->rchild != NULL)//如果左子树为空,右子树不为空则肯定不是完全二叉树
						return 0;
				if(T->lchild != NULL && T->rchild != NULL)//如果左右孩子都不为空
				{
						DeQueue(Q,T);
						EnQueue(Q,T->lchild);
						EnQueue(Q,T->rchild);
				}
				if((T->lchild != NULL && T->rchild == NULL) || T->lchild == NULL && T->rchild != NULL)//为叶子结点
				{
						DeQueue(Q,T);
						while(QueueLength(Q))
						{
								if(T->lchild == NULL && T->rchild == NULL)
								{
											DeQueue(Q,t);
								}
								else
								{
											return 0;
								}
								return 1;
						}
				}
				
				//DeQueue(Q,p);
				//if(p->lchild != NULL)
				//		EnQueue(Q,p->lchild);
				//if(p->rchild != NULL)
				//		EnQueue(Q,p->rchild);
		}
		return 1;
}
  • 2
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值