24-3-3二叉树层次遍历

即从上到下,从左到右

c++实现

思路:分别为建立节点,清空子树和读入节点。层次遍历bfs。节点初始化用node():have_value(false){}

#include<iostream>
#include<queue>
#include<vector>
#include<stdlib.h>
using namespace std;
char s[maxn];
struct node{
	node *left;
	node *right;
	int v;
	bool have_value;
	node():have_value(false),left(NULL),right(NULL){}//初始化
};
node *root;
node *newnode(){return new node();}//new运算符申请内存
void addnode(int v,char* s){
	node* u;
	for(int i=0;i<strlen(s);i++){
		if(s[i]=='L'){
			if(u->left==NULL)newnode();
			u=u->left;
		}
		if(s[i]=='R'){
			if(u->right==NULL)newnode();
			u=u->right;
		}
	}
	if(u->have_value)return false;
	u->have_value=true;
	u->v=v;
}
void remove_tree(node* u){
	if(u==NULL)return;
	remove_tree(u->left);
	remove_tree(u->right);
	delete u;
}
bool read_input(){
	failed=false;
	remove_tree(root);
	root=newnode();
	for(;;){
		if(scanf("%s",s)!=1)return false;
		if(!strcmp(s,"()"))break;
		int v;
		sscanf(&s[1],"%d",&v);
		addnode(v,strchr(s,',')+1);//strchr(s,',')在s中找,的地址
	}
	return true;
}
bool bfs(vector<int>& ans){//节点 u 是通过 q.front() 获取的,无需手动更新
	queue<node*>q;
	ans.clear();
	q.push(root);
	while(!q.empty()){
		node* u=q.front();q.pop();
		if(!u->have_value)return false;
		ans.push_back(u->v);//ans储存层次遍历后的值,按该顺序
		if(u->left!=NULL)q.push(u->left);
		if(u->right!=NULL)q.push(u->right);
	}
	return true;
}
以结构体+指针方式 
//释放内存不方便,速度较快
const int root=1;
void newtree(){
	left[root]=right[root]=0;
	have_value[root]=false;
	cnt=root;
}
int newnode(){
	int u=++cnt;
	left[u]=right[u]=0;
	have_value[root]=false;
	return u;
}

node* newnode(){
	node* u=&node[++cnt];
	u->left=u->right=NULL;
	u->have_value=false;
	return u;
}
内存池搭建
queue<node*>freenodes;//内存池搭建
//需要创建对象时从内存池中获取,而不是直接调用 new 操作。当对象不再需要时,将其放回内存池而不是立即释放内存
node n[maxn];
void init(){
	for(int i=0;i<maxn;i++){
		freenodes.push(&node[i]);
	}
}
node* newnode(){
	node* u=freenodes.front();
	u->left=u->right=NULL;
	u->have_value=false;
	freenodes.pop();//创建完节点将u退出来
	return u;
}
void deletenode(node* u){
	freenodes.push(u);//将想删除的u加进队列
}

C语言实现 

#include<stdio.h>
char s[maxn];
bool read_input(){//
	failed=false;//记录是否已经有节点
	root=newnode();
	for(;;){
		if(scanf("%s",s)!=1)return false;
		if(!strcmp(s,"()"))break;//一直读取,直到()来临
		int v;
		sscanf(&s[1],"%d",&v);//字符串转数字
		addnode(v,strchr(s,',')+1);//读取,后的字符
	}
	return true;
}
struct node{
	bool have_value;//是否赋值
	int v;//值
	node *left,*right;//下一层的左右节点
};
struct queue{//一个队列一个节点
	struct node* data;
	struct queue* next;//下一层
};
struct node* root;
struct queue *front,*rear;//双队列,front便于弹出节点
void push(struct node *root){
	struct queue *newnode=(struct queue *)malloc(sizeof(struct queue));
	newnode->data=root;//该队列节点为根节点
	newnode->next=NULL;
	if(rear==NULL){//该队列不存在
		front=newnode;
		rear=newnode;
	}
	else{//放入新队列,front不用更新,始终指向头节点
		rear->next=newnode;
		rear=newnode;
	}
}
struct node* pop(){//弹出最前的节点
	if(front==NULL)return NULL;
	struct queue* temp=front;
	struct node* data=front->data;
	front=front->next;//NULL的下个节点才为空,更新了rear值,头节点往下可以顺利遍历
	free(temp);
	return data;
}
struct node* newnode(){//单个节点需要的
	struct node* newnode = (struct node*)malloc(sizeof(struct node));
    if(newnode != NULL) {
        newnode->have_value = 0; // 默认为 false
        newnode->v = 0; // 默认为 0
        newnode->left = NULL;
        newnode->right = NULL;
    }
    return newnode;//赋值完要返回
}
void addnode(int v,char* s){//树上增加节点
	int n=strlen(s);
	node* u=root;
	for(int i=0;i<n;i++){
		if(s[i]=='L'){
			if(u->left==NULL)u->left=newnode();//没有节点就建立新的
			u=u->left;
		}
		else if(s[i]=='R'){
			if(u->right==NULL)u->right=newnode();
			u=u->right;
		}
	}
	if(u->have_value)failed=true;//已经有该节点了错误
	u->v=v;
	u->have_value=true;
}
bool bfs(int *ans){
	node* q;
	int* result = NULL;//ans要获取最终的result值
    int index = 0;
	push(root);
	while(front!=NULL){//一个节点都没有了
		struct node* current=pop();
		if(!current->have_value)return false;
		result = (int* )malloc(sizeof(int));
        result[index] = current->value;
        index++;
		if(current->left==NULL)push(current->left);
		if(current->right==NULL)push(current->right);
	}
	ans=result;
	return true;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值