0
点赞
收藏
分享

微信扫一扫

【数据结构】树的线性表示

unadlib 2022-03-15 阅读 97
数据结构

“ Ctrl AC!一起 AC!”

目录

1.树的括号表示:

特点:

将括号表示法转化成孩子表示法:

代码实现:

2.树的层号表示:

概述: 

​ 将层号表示转换成树的孩子表示(扩充版):


1.树的括号表示:

特点:

  • "("前面的一定是某颗树的根节点
  • “(  )”之间的结点是上述根节点的子结点

将括号表示法转化成孩子表示法:

代码实现:

#define m 3 //自定义树的度数,决定孩子表示法的结点的孩子最大个数 
#define MAXSIZE 20 //树的孩子表示中结点最大个数
#define BMAXSIZE 50 //树的括号表示法(字符数组)的数组大小
typedef char datatype;
typedef struct node{ //树的孩子表示法中的单个结点 
	datatype data;
	int child[m];
}treenode; 
treenode tree[MAXSIZE];
int root; //根节点的小标
int length; //树中实际包含的结点的个数
char p[BMAXSIZE]; //树的括号表示(就是一个字符串)
void bracktotree(char p[],int *root,int *length,treenode tree[]){
	int stack[MAXSIZE]; //存放根节点
	int top; //栈顶指针 
	int i,j,k,l,done; //j用来更新tree,k用来遍历p,done为程序结束标志
	k=0,j=0,*root=0;
	top=0; done=1;
	tree[j].data=p[k]; //先把第一个根节点放入tree中
	k++;
	for(i=0;i<m;i++) tree[j].child[i]=-1; //目前还没有子结点发现(因为k只走了一下)
	while(done){
		if(p[k]=='('){
			stack[top]=j; //把根结点放入栈中,方便后续结点认领
			++top;
			++k; 
		}
		else if(p[k]==')'){ //表示一个括号内的结点已处理完,这个括号的根节点可以出去了 
			--top;
			if(top==0) done=0;
			else ++k;
		}
		else if(p[k]==',') k++;
		else { //说明发现了新结点 
			++j; //先把这个结点装进tree,再去找父结点 
			tree[j].data=p[k]; 
			for(i=0;i<m;i++) tree[j].child[i]=-1;
			l=stack[top-1]; //上述结点的父结点
			i=0;
			while(tree[l].child[i]!=-1) i++;
			tree[l].child[i]=j;
			++k; 
		} 
	} 
	*length=j+1; //因为j从零开始的,所以结点总数为j+1 
} 

2.树的层号表示:

概述: 

 将层号表示转换成树的孩子表示(扩充版):

#define m 3
#define MAXSIZE 20
typedef char datatype;
typedef struct node{ //孩子表示法的结点 
	datatype data;
	int child[m];
	int parent;
}treenode;
typedef struct { //层号表示法的结点 
	datatype data;
	int lev;
}levelnode; 
treenode tree[MAXSIZE];
levelnode ltree[MAXSIZE]; 
int root;
int length; //数组中实际包含的结点个数 
void leveltotree(int length,levelnode ltree[],int *root,treenode tree[]){
	int i,j,k;
	for(i=0;i<length;i++){ //初始化 
		for(j=0;j<m;j++){
			tree[i].child[j]=-1;
		}
	}
	*root=0;
	tree[0].data=ltree[0].data; //先放根节点 
	tree[0].parent=-1;
	for(i=1;i<length;i++){ //遍历层号表示法的数组中的其他结点 
		tree[i].data=ltree[i].data;
		j=i-1; //看他前面的结点大小
		if(ltree[i].lev>ltree[j].lev){ //i更大,说明i是j的第一个子女 
			tree[i].parent=j;
			tree[j].child[0]=i;
		} 
		else{
			while(ltree[i].lev<ltree[j].lev){ //当i一直更小时,j回溯祖宗,找到与i同层的结点 
				j=tree[j].parent; 
			}
			tree[i].parent=tree[j].parent; //i的双亲自然就是j的双亲
			j=tree[j].parent; //往上走处理上述共同双亲
			k=0;
			while(tree[j].child[k]!=-1) k++; //找个空孩子位置挂上i 
			tree[j].child[k]=i; 
		}
	} 
}

感谢阅读!!!

“ Ctrl AC!一起 AC!” 

举报

相关推荐

0 条评论