二叉树的基本操作

二叉树的基本操作

二叉树的创建

#include<stdio.h>
#include<stdlib.h>
typedef struct BNode{
	char data;
	struct BNode *left,*right;
}BNode,*Bitree;

void CreateTree(Bitree &T)//使用先序递归的方式建立,输入..代表该节点已是树叶
{
	char n;
	scanf("%c",&n);
	if(n=='#') T=NULL;
	else
	{
		T=(Bitree)malloc(sizeof(BNode));//接受到非.的字符立即创建一个节点,接着创建他的左子树和右子树
		T->data=n;
		CreateTree(T->left);
		CreateTree(T->right);
	}
}

  • 输入124##5##36###即可
  • 先序遍历:124536
  • 中序遍历:425163
  • 后序遍历:452631
  • 层序遍历:123456

先序,中序,后序的递归算法

void pretravel(Bitree T)//先序遍历的递归 
{
	if(T)
	{
		printf("%c ",T->data);		
		pretravel(T->left);
		pretravel(T->right);
	}
 } 
 void intravel(Bitree T)//中序遍历的递归 
{
	if(T)
	{
		intravel(T->left);
		printf("%c ",T->data);
		intravel(T->right);		
	}
}

void posttravel(Bitree T)//后续遍历的递归 
{
	if(T)
	{
		posttravel(T->left);
		posttravel(T->right);	
		printf("%c ",T->data);			
	}
 } 
 

非递归的先序遍历,中序遍历


    typedef struct Stack{
	Bitree *top;
	Bitree *base;
	int high;
}stack;

void initstack(Stack &s)
{
	s.base=(Bitree*)malloc(100*sizeof(Bitree));
	s.top=s.base;
	s.high=100;
}

void Push(Stack& s,Bitree &e)//e为指向树中节点的指针
{
	if(s.top-s.base>=s.high)
	{
		Bitree *newbase=(Bitree*)realloc(s.base,10*sizeof(Bitree));
		s.base=newbase;
		s.top=s.base+s.high;
		s.high+=10;
	}
	*s.top=e;//将指针存放在栈中
	s.top++;
}

void Pop(Stack& s,Bitree &e)//用e来接收指向上一节点的指针
{
	if(s.top==s.base) return;
	s.top--;
	e=*s.top;
}

void Firtravel(Bitree T)//非递归的先序遍历 
{
	Stack s;
	initstack(s);
	Bitree p=T;
	while(p||s.base!=s.top)
	{
		if(p)
		{
			printf("%c ",p->data);
			Push(s,p);
			p=p->left;
		}
		else
		{
			Pop(s,p);
			p=p->right;
			
		}
	}
}

void ordertravel(Bitree T)//非递归的中序遍历 
{
	Stack s;
	initstack(s);
	Bitree p=T;
	while(p||s.base!=s.top)
	{
		if(p)
		{
			Push(s,p);
			p=p->left;
		}
		else
		{
			Pop(s,p);
			printf("%c ",p->data);
			p=p->right;
		}
	}
}

层序遍历

typedef struct squeue{
	Bitree *data;
	int front;
	int rear;
}squeue;
void initsqueue(squeue &q)//初始化循环队列 
{
	q.data=(Bitree*)malloc(100*sizeof(Bitree));
	q.front=0;
	q.rear=q.front;
}
void Enqueue(squeue &q,Bitree &e)
{
	if((q.rear+1)%100==q.front) return;
	q.data[q.rear]=e;
	q.rear=(q.rear+1)%100;
 }
void Dequeue(squeue &q,Bitree &e)
{
	if(q.rear==q.front) return;
	e=q.data[q.front];
	q.front=(q.front+1)%100;
}
void ordertravel(Bitree &T)//层序遍历 
{
	squeue Q;
	initsqueue(Q);
	Bitree p=T;
	if(T) Enqueue(Q,p);
	while(Q.front!=Q.rear)
	{
		Dequeue(Q,p);
		printf("%c ",p->data);
		if(p->left) Enqueue(Q,p->left);
		if(p->right) Enqueue(Q,p->right);
	}
}

第k层的层序遍历的递归

void travelk(Bitree T,int k)//第k层的层序遍历 
{
	if(T==NULL||k<1) return;
	if(k==1) printf("%c ",T->data);
	else
	{
		travelk(T->left,k-1);
		travelk(T->right,k-1);		
	}
}

第k层的层序遍历

void travelk_s(Bitree T,int k)//第k层的层序遍历 
{
	if(T==NULL||k<1) return;
	squeue Q;
	initsqueue(Q);
	int level=1,levelnum;
	Enqueue(Q,T);
	while(Q.front!=Q.rear)
	{
		if(level==k) break;
		levelnum=(Q.rear-Q.front+100)%100;
		int n=0;
		while(n<levelnum)
		{
			Bitree e;
			Dequeue(Q,e);
			if(e->left) Enqueue(Q,e->left);
			if(e->right) Enqueue(Q,e->right);
			n++;
		}
		level++;
	} 
	while(Q.front!=Q.rear)
	{
		Bitree t;
		Dequeue(Q,t);
		printf("%c ",t->data);
	}
}

判断是否为完全二叉树(两种方式)

int absolutetravel(Bitree &T)//无论出队节点有没有孩子,都将孩子入队(空指针作为判断标志)
{
	squeue Q;
	initsqueue(Q);
	Bitree p=T;
	if(T) Enqueue(Q,T);
	while(Q.front!=Q.rear)
	{
		Dequeue(Q,p);
		if(p)
		{
			Enqueue(Q,p->left);
			Enqueue(Q,p->right);			
		}
		else//此时出队元素为空指针,则后面的应该都为空指针
		{
			while(Q.front!=Q.rear)
			{
				Dequeue(Q,p);
				if(p) return 0;
			}
			return 1;
		 } 
	}
	
}
int absolutetravel_s(Bitree T)//判断是否为完全二叉树,队中没有空指针 
{
	int tag=1;
	squeue Q;
	initsqueue(Q);
	Bitree p=T;
	if(T) Enqueue(Q,T);
	while(Q.front!=Q.rear&&tag)
	{
		Dequeue(Q,p);
		if(p->left)
		{
			Enqueue(Q,p->left);
			if(p->right) Enqueue(Q,p->right);//当一个节点有左孩子和右孩子,继续
			else tag=0;//当一个节点只有左孩子,给出停止标志
		}
		else
		{
			tag=0;//一个节点没有左孩子,给出停止标志
			if(p->right) return 0;//一个节点没有左孩子,但有右孩子,必定不是完全二叉树
		}
	}
	while(Q.front!=Q.rear)
	{
		Dequeue(Q,p);//此时队中存放的都不应该有左孩子和右孩子,说明为完全二叉树
		if(p->left||p->right) return 0;//若出现,则不是
	}
	return 1;
}
二叉树是一种非常重要的数据结构,它的基本操作包括创建、销毁、遍历、查找等。下面是二叉树基本操作的实现方法: 1. 创建二叉树:通过前序遍历的数组构建二叉树,其中 '#' 表示空节点。具体实现方法可以参考引用中的 BinaryTreeCreate 函数。 2. 销毁二叉树:遍历二叉树,依次释放每个节点的内存空间。具体实现方法可以参考引用中的 BinaryTreeDestory 函数。 3. 遍历二叉树二叉树的遍历包括前序遍历、中序遍历、后序遍历和层序遍历。具体实现方法可以参考引用中的 BinaryTreePrevOrder、BinaryTreeInOrder、BinaryTreePostOrder 和 BinaryTreeLevelOrder 函数。 4. 查找二叉树节点:在二叉树中查找值为 x 的节点,具体实现方法可以参考引用中的 BinaryTreeFind 函数。 5. 计算二叉树节点个数:计算二叉树中节点的个数,具体实现方法可以参考引用[2]中的 BinaryTreeSize 函数。 6. 计算二叉树叶子节点个数:计算二叉树中叶子节点的个数,具体实现方法可以参考引用中的 BinaryTreeLeafSize 函数。 7. 计算二叉树第 k 层节点个数:计算二叉树中第 k 层节点的个数,具体实现方法可以参考引用中的 BinaryTreeLevelKSize 函数。 8. 判断二叉树是否是完全二叉树:判断二叉树是否是完全二叉树,具体实现方法可以参考引用中的 BinaryTreeComplete 函数。 9. 计算二叉树的深度:计算二叉树的深度,具体实现方法可以参考引用中的 BinaryTreeDeep 函数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值