您的位置:首页 > 理论基础 > 数据结构算法

数据结构之父指针实现树

2015-09-30 09:52 621 查看


/*
实现功能:用父指针法存储树,并给出 root() leftChild() rightChild()
编译环境:Windows7 64b,VC6.0
日期:    2015/7/22
作者:    wtt561111

*/

/*
不清楚的地方{
书上给出的函数:先根周游
给出tree和p返回左孩子的下标
给出tree和p返回右兄弟的下标
我自己定义的函数:返回给定结点的值
 创建一个树
 给出tree返回根节点
 给出tree返回左孩子
 给出tree返回右兄弟
先根周游算法里面用到的函数是我自己定义的,不是书上给出的。
导致周游结果只是输出根节点的值
}

*/

#include "stdio.h"

#include "stdlib.h"

#define MaxNum 10

struct ParTreeNode {
char info;
int parent;//存储父指针所在的下标。下标由先根顺序确定

};

typedef struct ParTreeNode *PParTreeNode;

struct ParTree{
int MAXNUM;
//最大结点个数
int n;
//已有结点个数
struct ParTreeNode *nodelist;//指向结点数组

};

typedef struct ParTree *PParTree;

/*
创建一个树,成功根结点的指针,否则返回NULL

*/

 PParTree createTree_partree(PParTreeNode nodelist,int maxnum,int n){

PParTree tree=(PParTree)malloc( sizeof(struct ParTree) );
if(tree==NULL){
printf("out of space\n");
return NULL;
}
tree->MAXNUM=maxnum;
tree->n=n;
tree->nodelist=nodelist;
return tree;

}

/***********************************************************/

/*
求右兄弟结点的位置。成功返回右兄弟结点的序号,否则返回-1 。
父结点只有一个左孩子,那就是最左的那个孩子。但是还有其他非左孩子。
但是右兄弟只有一个,那就是紧挨着的右边的那个兄弟。

*/

int rightSibling_partree(PParTree t,int p){

int i;
if(p>=0 && p<t->n){//
for(i=p+1;i<t->n;i++){
if(t->nodelist[i].parent == t->nodelist[p].parent)
return i;
}
}
return -1;

}

/***********************************************************/

/*
返回最左子树的紧挨着的那个兄弟。成功返回右兄弟树,否则返回NULL。

*/

PParTree rightSibling_partree(PParTree t){
if(t==NULL)//如果树为空,返回空
return NULL;
if(t->n==1)//如果只有根节点,返回空
return NULL;
int BeginPosition=0;//新树对应的nodelist的值,应从旧树的nodelist的第BeginPostion个开始
int i;
for(i=0;i<t->n;i++){//找到右兄弟对应的位置
if(t->nodelist[i].parent == t->nodelist[0].parent)
BeginPosition=i;
}

int OldTreeN=t->n;
int OldTreeMax=t->MAXNUM;

PParTreeNode NewNodelist=(PParTreeNode)malloc( sizeof(struct ParTreeNode)*(OldTreeMax-BeginPosition) );//为子树申请存储信息的表
if(NewNodelist==NULL){
printf("out of space\n");
return NULL;
}
for(i=1;i<OldTreeN;i++){
NewNodelist[i-1].info=t->nodelist[i].info;//将旧表中的值赋给新树
NewNodelist[i-1].parent=t->nodelist[i].parent;//将旧表中的父结点赋给新树
}
PParTree NewTree=createTree_partree(NewNodelist,OldTreeMax-1,OldTreeN-1);//创建新的树
return NewTree;

}

/***********************************************************/

/*
求最左子结点的位置。成功返回最左子结点的序号,否则返回-1.

*/

int leftChild_partree(PParTree t,int p){

if(t->nodelist[p+1].parent==p)//根左右,如果根的紧跟后面是子结点,就一定是最左子结点。
return (p+1);
 //如果不是子结点,就没有子结点。
return -1;

}

/***********************************************************/

/*
返回根结点的左子树,成功返回左子树,否则返回NULL

*/

PParTree leftChild_partree(PParTree t){
if(t==NULL)//如果树为空,返回空
return NULL;
if(t->n==1)//如果只有根节点,返回空
return NULL;
if(t->nodelist[1].parent==0)//如果没有左孩子则返回空
return NULL;
int OldTreeN=t->n;
int OldTreeMax=t->MAXNUM;

PParTreeNode NewNodelist=(PParTreeNode)malloc( sizeof(struct ParTreeNode)*(OldTreeMax-1) );//为子树申请存储信息的表
if(NewNodelist==NULL){
printf("out of space\n");
return NULL;
}
int count;
for(count=1;count<OldTreeN;count++){
NewNodelist[count-1].info=t->nodelist[count].info;//将旧表中的值赋给新树
NewNodelist[count-1].parent=t->nodelist[count].parent;//将旧表中的父结点赋给新树
}
PParTree NewTree=createTree_partree(NewNodelist,OldTreeMax-1,OldTreeN-1);//创建新的树
return NewTree;

}

/***********************************************************/

/*
返回根结点,成功根结点的指针,否则返回NULL

*/

PParTreeNode root_partree(PParTree t){

if(t==NULL){
printf("input tree again\n");
return NULL;
}
if(t->nodelist==NULL || t->n==0){
printf("empty tree\n");
return NULL;
}
return &(t->nodelist[0]);//nodelist是个数组,不是结构体。但是数组的每一个元素是结构体

}

/***********************************************************/

 

/*
输出结点的值

*/

 void visit(PParTreeNode node){

if(node==NULL){
printf("error\n");
}else{
printf("%c",node->info);
}

}

/***********************************************************/

  

/*
按照先根顺序周游树

*/

 void preOrder(PParTree t){

PParTree c;
if(t==NULL)return;
visit(root_partree(t));
c=leftChild_partree(t);
while(c!=NULL){
preOrder(c);
c=rightSibling_partree(c);
}

}

/***********************************************************/

/****************主函数*************************************/

int main(){

PParTreeNode nodelist=(PParTreeNode)malloc(sizeof(struct ParTreeNode)*MaxNum);
if(nodelist==NULL){
printf("out of spcae\n");
return 0;
}
nodelist[0].info='a';
nodelist[0].parent=-1;
nodelist[1].info='b';
nodelist[1].parent=0;
nodelist[2].info='d';
nodelist[2].parent=1;
nodelist[3].info='e';
nodelist[3].parent=1;
nodelist[4].info='h';
nodelist[4].parent=3;
nodelist[5].info='i';
nodelist[5].parent=3;
nodelist[6].info='j';
nodelist[6].parent=3;
nodelist[7].info='c';
nodelist[7].parent=0;
nodelist[8].info='f';
nodelist[8].parent=7;
nodelist[9].info='g';
nodelist[9].parent=7;

PParTree tree_get=createTree_partree(nodelist,10,10);

// PParTreeNode tree_root=root_partree(tree_get);

// visit(tree_root);
preOrder(tree_get);
return 1;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息