如何建树?
方式一(二叉树)
dfs使用root左右指针建立树节点关系,返回根节点root
方式二(二叉树)
dfs使用二维数组,int nds[n][2],如:nds[i][0]表示i节点的左子节点,nds[i][1]表示i节点的右子节点
方式三(树)
dfs使用邻接表保存树节点关系,vector
序列转换
前序后序转中序
后序倒数第一个节点为根root,root在前序中为第一个节点
后序倒数第二个节点为root的右子树的根节点rightTreeRoot,rightTreeRoot在前序中将序列分为左边部分(root和root的左子树),右边部分(root的右子树包含rightTreeRoot)
若rightTreeRoot前只有一个节点,那么说明该rightTreeRoot的父节点root只有一个子节点,即rightTreeRoot既可以为root的左子节点也可以为root的右子节点
node * create(int preL,int preR,int postL,int postR) {
if(preL>preR)return NULL;
node * root = new node;
root->data=post[postR];
root->left=NULL;
root->right=NULL;
if(preL==preR)return root;
int k=preL+1;
while(k<=preR&&pre[k]!=post[postR-1])k++;
if(k-preL>1) {
root->left=create(preL+1,k-1,postL,postL+(k-preL-1)-1);
root->right=create(k,preR,postL+(k-preL-1),postR-1);
} else {
unique = false;
root->right=create(k,preR,postL+(k-preL-1),postR-1);
}
return root;
}
前序中序转后序
前序第一个节点为根root,root在中序中位置为k,将序列分为左边部分(root的左子树),右边部分(root的右子树)
inL~k-1为下次左递归的后序序列,其对应的后序序列为preL+1~preL+(k-inL);
k+1~inR为下次递归的后序序列,其对应的后序序列为postL+(k-inL)+1~preR;
void postFirst(int inL,int inR, int preL,int preR) {
if(inL>inR||flag) return;
int k=inL;
while(k<inR&&in[k]!=pre[preL])k++;
postFirst(inL, k-1, preL+1, preL+(k-inL));
postFirst(k+1, inR, preL+(k-inL)+1, preR);
if(flag==false) {
printf("%d", pre[preL]);
flag=true;
}
}
后序中序转前序
后序第一个节点为根root,root在中序中位置为k,将序列分为左边部分(root的左子树),右边部分(root的右子树)
inL~k-1为下次左递归的后序序列,其对应的后序序列为postL~postL+(k-inL)-1;
k+1~inR为下次递归的后序序列,其对应的后序序列为postL+(k-inL)~postR-1;
node * create(int postL,int postR,int inL,int inR) {
if(postL>postR)return NULL;
node * root=new node;
root->data=post[postR];
// 找到当前根节点在中序遍历中的位置
int i;
for(i=inL; i<=inR; i++) {
if(post[postR]==in[i])
break;
}
int numLeft=i-inL;
root->left=create(postL,postL+numLeft-1,inL,inL+numLeft-1);//inL+numLeft=i
root->right=create(postL+numLeft,postR-1,inL+numLeft+1,inR);//inL+numLeft=i
return root;
}
如何进行层级遍历序列?
方式一
建树,借助队列层级遍历
方式二
建树时,记录index到结点(如:节点i的左子节点index=2i+1,节点i的右子节点index=2i+2),之后节点index升序排序,依次打印即为层序序列
如何记录层级?
DFS中如何记录层级?如何记录每层叶子节点数?
dfs函数参数中记录当前处理节点的层级,使用int max_h记录最大层数方便后续层级遍历,可使用int leaf[n]记录对应层级叶子节点数
void dfs(int index,int h) {
max_h=max(h,max_h);//记录最大层数
if(nds[index].size()==0) { //叶子节点
leaf[h]++;
return;
}
for(int i=0; i<nds[index].size(); i++) {
dfs(nds[index][i],h+1);
}
}
BFS中如何记录层级?如何记录每层叶子节点数?
使用int h[n]记录节点层级,如:h[i]即为节点i的层级,使用int max_h记录最大层数方便后续层级遍历,可使用int leaf[n]记录对应层级叶子节点数
void bfs(){
queue<int> q;
q.push(1);
while(!q.empty()){
int now = q.front();
q.pop();
max_h=max(max_h,h[now]);
if(nds[now].size()==0){
leaf[h[now]]++;
} else{
for(int i=0;i<nds[now].size();i++){
h[nds[now][i]]=h[now]+1;
q.push(nds[now][i]);
}
}
}
}