即从上到下,从左到右
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;
}