//双亲表示法
#include <stdio.h>
#include <malloc.h>
#define MAX 12
//巧妙使用顺序和链式存储可以实现树的存储结构
//双亲表示法是使用顺序存储来实现的
typedef struct pNode{
char data;
int parent; //存放双亲在数组中的下标
} pNode;
//使用顺序结构存放节点
typedef struct {
pNode tr[MAX];
int r,node_amount; //存放节点数量信息,以及根的位置
}pTree;
//创造空树
void InitTree(pTree *s){
int i;
s->r=0; //定义根节点位置
s->node_amount=MAX; //定义存放的节点个数
for(i=0;i<MAX;i++){
s->tr[i].data=NULL;
s->tr[i].parent=-1;
}
}
//添加树节点
pNode addNode(char str,int parent){
pNode node;
node.data=str;
node.parent=parent;
return node;
}
//从根节点开始创造树
//FLAG是当前数组下标
pNode createTree(pTree *s,char str,int flag,int parent){
switch(str){
case 'A':s->tr[flag]=addNode(str,parent);
break;
case 'B':s->tr[flag]=addNode(str,parent);
break;
case 'C':s->tr[flag]=addNode(str,parent);
break;
case 'D':s->tr[flag]=addNode(str,parent);
break;
case 'E':s->tr[flag]=addNode(str,parent);
break;
case 'F':s->tr[flag]=addNode(str,parent);
break;
case 'G':s->tr[flag]=addNode(str,parent);
break;
case 'H':s->tr[flag]=addNode(str,parent);
break;
case 'I':s->tr[flag]=addNode(str,parent);
break;
case 'J':s->tr[flag]=addNode(str,parent);
break;
case 'K':s->tr[flag]=addNode(str,parent);
break;
default :s->tr[flag]=addNode(str,parent);
break;
}
}
//还有一个比较好的创建思路
/*
void InitPNode(Ptree &tree)
{
int i,j;
char ch;
printf("请输入结点个数:\n");
scanf("%d",&(tree.n));
printf("请输入结点的序及值其双亲序号:\n");
for(i=0; i<tree.n; i++)
{
fflush(stdin);
scanf("%c,%d",&ch,&j);
tree.tnode[i].data = ch;
tree.tnode[i].parent = j;
}
tree.tnode[0].parent = -1;
}
*/
void travelTree(pTree *s){
int i;
for(i=0;i<MAX;i++){
printf("%c %d \n",s->tr[i].data,s->tr[i].parent);
}
return ;
}
int main(){
int i=0;
int j=65;
int parent[MAX]={-1,0,0,1,1,1,2,2,3,5,7,7};//定义一个双亲数组,跟顺序存储节点数组下标同步
int arrFlag=-1;
pTree tree;
InitTree(&tree); //初始化一个空树。
for(i=0;i<MAX;i++){
createTree(&tree,char(j),i,parent[i]);
j++;
}
travelTree(&tree);
return 0;
}
//孩子表示法
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#define MAX 10
//孩子表示法是使用链式存储和顺序存储联合实现的
//孩子表示法
//孩子链表节点,以单链表的逻辑结构存储
typedef struct plist{
int ChildData; //链表中孩子节点的数据域,该值和数组中孩子的下标相等
struct plist *next;
}plist;
//单链表头节点
typedef struct pNode{
char data;
plist *firstChild; //从第一个孩子开始存储起
}pNode;
typedef struct pTree{
pNode a[MAX];
int root, root_Quantity;
} pTree;
void InitTree(pTree *tree){ //初始化空树
tree->root=-1;
tree->root_Quantity=MAX;
return ;
}
void createTree(pTree *tree){
int i,j;
int num;
for(i=0;i<MAX;i++){
printf("请输入节点名称!\n");
fflush(stdin); //清理输入缓冲区
scanf("%c",&tree->a[i].data);
tree->a[i].firstChild=(plist*)malloc(sizeof(plist));
tree->a[i].firstChild->next=NULL;
printf("请输入节点孩子数量!\n");
scanf("%d",&num);
if(num!=0){
plist *tail = tree->a[i].firstChild;
for(j=0;j<num;j++){
plist *pnew=(plist*)malloc(sizeof(plist));
pnew->next=NULL;
printf("请输入该节点孩子位置!\n");
scanf("%d",&pnew->ChildData);
tail->next=pnew;
tail=tail->next;
//free(pnew); 记得释放,否则同一个变量被malloc多次会内存溢出
}
}else{
continue;
}
}
return ;
}
void travel(pTree *tree){
int i,num=MAX;
plist *p;
for(i=0;i<num;i++){
printf("头节点:%c ",tree->a[i].data);
p=tree->a[i].firstChild->next;
while(p!=NULL){
printf("孩子节点的位置是:%d ",p->ChildData);
p=p->next;
}
printf("\n");
}
}
//孩子表示法还可以和双亲表示法结合进行改进,算法的话也就是结构体里面加多一个表示双亲位置的变量即可
//大同小异
int main(){
pTree tree;
InitTree(&tree);
createTree(&tree);
travel(&tree);
return 0;
}