数据结构之父指针实现树
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;
}
相关文章推荐
- Linux C函数参考手册(PDF版)
- 用PS实现纹理浮雕效果代码
- 用vbs实现cmd功能的代码
- 用双网卡实现三机互联
- Lua教程(十七):C API简介
- Lua教程(七):数据结构详解
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- C#中实现判断某个类是否实现了某个接口
- C#数据结构揭秘一
- DL.DT.DD实现左右的布局简单例子第1/2页
- C#实现获取系统目录并以Tree树叉显示的方法
- C#实现打造气泡屏幕保护效果
- C/C++数据对齐详细解析
- 利用C语言来求最大连续子序列乘积的方法
- 数据结构之Treap详解
- 字符串的组合算法问题的C语言实现攻略
- C 语言基础教程(我的C之旅开始了)[三]
- C语言实现输入一颗二元查找树并将该树转换为它的镜像
- C++中的extern “C”用法详解