二叉树 常见操作

这篇博客主要总结了二叉树的一些经典算法题目,包括但不限于先序遍历、森林与二叉树的转换等。作者指出,这些题目中的某些问题可以通过观察满二叉树和完全二叉树的特性来简化解决,比如利用先序遍历记录特定节点。博客内容以代码实现和算法思路为主,是作者完成数据结构作业后的思考和分享。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一般是没有什么动力自己写代码来实践数据结构的,可能还是因为数据结构老师留了新的作业2333.,作业是这样的:


嗯。。其实每一道题都是很经典的算法,一篇博文应该是放不下的,先大体总结一下系列做法,很多都是借鉴的大牛2333,个人的一点小想法其实就是3和4.3中对应森林的叶子结点其实就是二叉树结构中没有左子树的结点,在先序遍历的过程中稍加记录就好。而4呢,就在于满二叉树和完全二叉树的对应结点序号一致就好

代码:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
using namespace std;
#define STACK_INIT_SIZE 100
#define maxn 100
int cnt=0;
int len=0;
int res=0;
int height;
int tag[maxn];
typedef char TElemType;
typedef struct BiTNode{
	TElemType data;
	struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
typedef struct{
	int top;
	BiTree data[maxn];
}SqStack;
typedef struct{
	BiTree *base;
	BiTree *top;
	int stacksize;
	int llen;
}stack;
void InitStack(stack &s){
	s.base=(BiTree*)malloc(STACK_INIT_SIZE*sizeof(BiTree));
	if(!s.base) exit(0);
	s.top=s.base;
	s.stacksize=STACK_INIT_SIZE;
	s.llen=0;	
}
void push(stack &s,BiTree e){
	if(s.top-s.base>=s.stacksize){
		s.base=(BiTree*)realloc(s.base,(s.stacksize+STACK_INIT_SIZE)*sizeof(BiTree));
		if(!s.base) exit(0);
		s.top=s.base+s.stacksize;
		s.stacksize+=STACK_INIT_SIZE;
	}
	*s.top++=e;
	s.llen++;
}
void pop(stack &s){
	if(s.top==s.base) exit(0);
	//e=*--s.top;
	s.top--;
	s.llen--;
}
BiTree Top(stack s){
	if(s.top==s.base) exit(0);
	BiTree e;
	e=*(s.top-1);
	return e;
}
int isEmpty(stack s)
{
	if(s.base==s.top)
	return 1;
	else
	return 0;
}
BiTree CreateBiTree(BiTree &T) { 
  // 按先序次序输入二叉树中结点的值(一个字符),空格字符表示空树,
  // 构造二叉链表表示的二叉树T。
  char ch;
  scanf("%c",&ch);
  fflush(stdin);
  if (ch=='#') T = NULL;
  else {
    if (!(T = (BiTNode *)malloc(sizeof(BiTNode)))) exit(0);
    T->data = ch;              // 生成根结点
    CreateBiTree(T->lchild);   // 构造左子树
    CreateBiTree(T->rchild);   // 构造右子树
  }
  return T;
} // CreateBiTree
void PreorderTraverse(BiTree T)
{
	SqStack s;
	BiTree p;
	s.top=-1;
	p=T;
	while(p)
	{
		while(p){
		printf("%c",p->data);
		if(p->rchild)
		{
			if(s.top==maxn) exit(0);
			else s.data[++s.top]=p->rchild;
		}
		else
		res++;
		p=p->lchild;
		}
		if(s.top!=-1) p=s.data[s.top--];
	}
	printf("\n");
}
int TreeDeep(BiTree BT ){
      int deeptree=0;
      stack S;
      InitStack(S);
      BiTree p=BT;
      while(p!=NULL||!isEmpty(S)){
          while(p!=NULL){
              push(S,p);
              //push(tag,0);
              tag[len++]=0;
             p=p->lchild;
        }
         if(tag[len-1]==1){
             deeptree=deeptree>S.llen?deeptree:S.llen;
             pop(S);
             len--;
             p=NULL;
         }else{
             p=Top(S);
             p=p->rchild;
             len--;
             //push(tag,1);
             tag[len++]=1;
         }
     }
     height=deeptree;
     printf("%d\n",deeptree);
     return deeptree;
}
int getlevelnode(BiTree proot, int k)
{
    if(proot == NULL || k == 0)
        return 0;

    int cur_level_size = 0;//当前层的节点个数
    int cur_level = 0;  //当前层数

    queue <BiTree> que;
    que.push(proot);
    while (!que.empty())
    {
        ++cur_level;
        cur_level_size = que.size();
        if(cur_level == k)//当到第k层时
            break;

        int temp_count = 0;
        //当前层的所有节点出队,下一层的结点入队
        while (temp_count < cur_level_size) 
        {
            ++temp_count;
            proot = que.front();
            que.pop();
            if (proot->lchild != NULL)
                que.push(proot->lchild);
            if (proot->rchild != NULL)
                que.push(proot->rchild);
        }       
    }
    while(!que.empty())
        que.pop();//清空队列
    if(cur_level == k)
        return cur_level_size;
    return 0;
}
bool IsFullBitree(BiTree  T)//
{
     queue<BiTree> Q;
     BiTree p;
     bool flag=false;
     if(T!=0)
     {
 		Q.push(T);
	    while(!Q.empty())
 		{
 			p=Q.front();
 			Q.pop();
      		if(!p)
  			flag=true;
  			else if(flag)
    		return false;
  			else
  			{	  	
    			Q.push(p->lchild);
				Q.push(p->rchild);    
			}
 		}
 }
 return true;
}
int main()
{
	BiTree al;
	printf("先序建树2333:\n");
	CreateBiTree(al);
	printf("先序遍历结果为:\n");
	PreorderTraverse(al);
	printf("树的深度为");
	TreeDeep(al);
	for(int i=1;i<=height;i++)
	printf("第%d层结点数为%d\n",i,getlevelnode(al,i));
	printf("二叉树对应的森林的叶子结点数为:");
	printf("%d\n",res);
	if(IsFullBitree(al))
	printf("这是一棵完全二叉树\n");
	else
	printf("这不是一棵完全二叉树\n");
	return 0; 
}
/*
struct node {
    int val;
    struct node* left;
    struct node* right;
};
 
int height(struct node* root)
{
    int h, lh, rh;
    if ( root == NULL)
        return -1;//这里返回-1表示叶子节点的高度为0,若规定叶子节点的高度为1,这里返回0即可
    lh = height(root->left);
    rh = height(root->right);
    if (lh > rh) 
        h = lh + 1;
    else 
        h = rh + 1;
    return h;
}*/ 

输入内容:


运行结果:



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值