分析二叉树的链式存储建立二叉树的缺点:
- 只能够进行前序遍历,中序遍历,后续遍历的方式建立二叉树,建树的方式不够随意灵活。对于一些题目要求插入的点,不知道父亲节点指针的位置,每次增加新节点都得遍历整个二叉树。
- 而对于数组的方式存储二叉树,直接通过访问父亲节点的下表来建树,比较灵活
比如:在数据为’a’的节点插入左孩子节点(值为’b’)
链式存储法一:
第一步:需要找到节点数据为a的链表指针并返回(遍历)
第二步:才能进行插入
typedef struct Node{
char data;
struct Node *l,*r;//左孩子指针,有孩子指针
}BiTNode,*BiTree;
//数据为a的插入左节点(值为b)
//第一步需要找到该节点的父亲节点并返回(遍历)
//第二步才能进行插入
BiTree findNode(BiTree T,char a){
if(T->data == a)
return T;
BiTree ans = NULL;
if(T->l){
ans = findNode(T->l,a);
if(ans)
return ans;
}
if(T->r)
ans = findNode(T->r,a);
return ans;
}
链式存储法二:
定义一个结构体指针数组map来存储,这样建树就不用每次遍历了
BiTree map[200];//通过a字符的asc码来找该指针的位置
//局限:对于数据不是字符或者小整数的此方法就比较复杂
顺序存储方法:
struct Node{
char l,r;
};
Node tree[200];
//直接通过数组下标进行插入
tree['a'].l = 'b';
下面是一道关于建树的题(题解是顺序存储的方法进行建树)
题目连接洛谷1087
题解如下:
#include<iostream>
#include<cstring>
#include<string>
struct Node{
char s;
int l,r;
};
Node T[100000];
int N;
string S;
void createS(int n,int low,int high){
int num0 = 0;
int num1 = 0;
int i;
for(i = low;i<=high;i++){
if(S[i] == '0')
num0++;
if(S[i] == '1')
num1++;
}
if(num0 == 0)
T[n].s = 'I';
else if(num1 == 0)
T[n].s = 'B';
else
T[n].s = 'F';
}
void createTree(int n,int low,int high){
if(low == high){
createS(n,low,high);
return ;
}
int mid = (low+high)/2;
createS(n,low,high); //为T[n]这个数赋值
createTree(2*n,low,mid); //递归建立左子树
createTree(2*n+1,mid+1,high); //递归建立右子树
return ;
}
void aftTravel(int n){
if(T[n].s == 0)
return;
aftTravel(2*n);
aftTravel(2*n+1);
printf("%c",T[n].s);
}
int main(){
int i,j,k;
cin>>N;
cin>>S;
createTree(1,0,S.length()-1);
aftTravel(1);
return 0;
}
以上来自一个acm小白的个人想法,如有错误之处,请各位大神指出