主题:C语言实现树数据结构基本操作
#include<stdio.h>
#include<malloc.h>
#define EXIT_FAILURE 0
#define ERROR -2
#define OK 1
typedef char elemtype;
typedef struct BITNODE
{
elemtype data;
struct BITNODE *lchild,*rchild;
}BITNODE,*BITREE;
/*结构体定义的二叉树结点以及结点指针*/
int PREORDER_CREAT_BITREE (BITREE t)
{
elemtype ch;
ch=getchar();
if (ch==' ')
t=NULL;
else
{
if(!(t=(BITREE)malloc( sizeof(BITNODE) )))exit(EXIT_FAILURE);
t->data=ch;
CREAT_BITREE(t->lchild);
CREAT_BITREE(t->rchild);
}
return OK;
}/*先序递归创建二叉树*/
int INORDER_CREAT_BITREE (BITREE t)
{
elemtype ch;
ch=getchar();
if (ch==' ') t=NULL;
else
{
if(!(t=(BITREE)malloc( sizeof(BITNODE) ))) exit(EXIT_FAILURE); /*fenpei ,danbu fuzhi ,yinwei shi zhongxu bianli*/
INORDER_CREAT_BITREE (t->lchild);
INORDER_CREAT_BITREE (t->rchild);
}
return OK;
}/*中序递归创建二叉树*/
int POSTORDER_CREAT_BITREE(BITREE t)
{
elemtype ch;
ch=getchar();
if(ch==' ') t=NULL;
else
{
if(!(t=(BITREE)malloc( sizeof(BITNODE) ))) exit(EXIT_FAILURE); /*fenpei ,danbu fuzhi ,yinwei shi houxu bianli*/
POSTORDER_CREAT_BITNODE(t->lchild);
POSTORDER_CREAT_BITNODE(t->rchild);
t->data=ch;
}
return OK;
}/*后序递归创建二叉树*/
int PREORDER_TRAVERSE_BITREE(BITREE t)
{
if(t)
{
if(VIST(t->data))
if(PREORDER_TRAVERSE_BITREE(t->lchild) )
if(PREORDER_TRAVERSE_BITREE(t->rchild) )
return OK;
return ERROR;
}
else return OK;
}/*先序递归遍历二叉树*/
int INORDER_TRAVERSE_BITREE(BITREE t)
{
if(t)
{
if(INORDER_TRAVERSE_BITREE(t->lchild) )
if(VIST (t->data))
if(INORDER_TRAVERSE_BITREE(t->rchild) )
return OK;
return ERROR;
}
return OK;
} /*中序递归遍历二叉树*/
int POSTORDER_TRAVERSE_BITREE(BITREE t)
{
if(t)
{
if(INORDER_TRAVERSE_BITREE(t->lchild) )
if(INORDER_TRAVERSE_BITREE(t->rchild) )
if(VIST (t->data))
return OK;
return ERROR;
}
return OK;
}/*后续递归遍历二叉树*/
/*注:上述描述中VIST是一个对结点数据操作的一个函数,可以通过函数指针传入,需要设立一个函数指针传入遍历函数*/
#include<malloc.h>
#define EXIT_FAILURE 0
#define ERROR -2
#define OK 1
typedef char elemtype;
typedef enum POINTERTAG {LINK,THREAD}POINTERTAG;
typedef struct BITHRNODE
{
elemtype data ;
struct BITHRNODE *lchild ,*rchild;
POINTERTAG LTAG,RTAG;
}BITHRNODE,*BITHRTREE;/*描述线索二叉树结点的结构体*/
void INTHREADING(BITHRTREE t,BITHRTREE pre)/*线索化函数,需要2个参数*/
{
if(t)
{
INTHREADING(t->lchild,pre);
if(!t->lchild){t->LTAG=THREAD;t->lchild=pre;}
if(!t->rchild){t->RTAG=THREAD;pre->rchild=t;}
pre=t;
INTHREADING(t->rchild,pre);
}
}/*上述函数用来进行线索化*/
int INORDER_THREAD_BITHRTREE(BITHRTREE t,BITHRTREE thrt)
{
BITHRTREE pre;/*设立指针pre始终指向操作元素(除非是空了)的前一个,即前驱*/
if(!(thrt=(BITHRTREE) malloc(sizeof(BITHRNODE))) ) exit(EXIT_FAILURE);
thrt->LTAG=LINK;
thrt->RTAG=THREAD;
thrt->rchild=thrt;
if(!t)thrt->lchild=thrt;/*初始化头结点*/
else
{
thrt->lchild=t;
pre=thrt;/*初始化头结点*/
INTHREADING(t,pre);/*调用线索化*/
pre->rchild=thrt;
pre->RTAG=THREAD;
thrt->rchild=pre;
}/*对于最后的元素进行指针的设定*/
return OK;
}/*中序线索化二叉树*/
#include<stdio.h>
#include<malloc.h>
#define EXIT_FAILURE 0
#define ERROR -2
#define OK 1
typedef char * *HUFFMANCODE;/*指向char数组的指针*/
typedef struct HTNODE
{
unsigned int weight;
unsigned int parent,lchild,rchild;
}HTNODE,*HUFFMANTREE;
int CREAT_HUFFMANCODING(HUFFMANTREE ht,HUFFMANCODE hc,int *w,int n)/*本函数构造赫夫曼树,并求出存在数组w中的n个字符的赫夫曼编码放到hc中*/
{
int m,i,start,c;
HTNODE *p;
char *cd;
unsigned int f;
if(n<=1) return ERROR;
m=2*n-1;
ht=(HTNODE *)malloc((m+1)*sizeof(HTNODE));/*不用0号单元*/
if(!ht) eixt(EXIT_FAILURE);
for(p=ht+1,i=1;i<=n;i++,p++,w++)
{
p->weight=*w;
p->parent=0;
p->lchild=0;
p->rchild=0;
}
for(;i<=m;++i,++p)
{
p->weight=0;
p->lchild=0;
p->rchild=0;
}
for(i=n+1;i<=m;i++)
{
int s1,s2;
SELECT(ht,i-1,s1,s2);/*本函数用来选择其中2个最小的权值的结点并且返回其标号*/
(ht+s1)->parent=i;
(ht+s2)->parent=i;
(ht+i)->lchild=s1;
(ht+i)->rchild=s2;
(ht+i)->weight=(ht+s1)->lchild+(ht+s2)->rchild;
}/*至此赫夫曼树构造完了*/
hc= (HUFFMANCODE) malloc ( (n+1) * sizeof (char *) ); /*第0号单元不使用*/
if(!hc)exit(EXIT_FAILURE);
cd= (char *) malloc ( n * sizeof (char) );/*分配cd来暂时保存每个求出的编码,在求下个时会被覆盖*/
if(!cd)exit(EXIT_FAILURE);
*(cd+n-1)='\0';/*编码结束符*/
for(i=1;i<=n;++i)
{
start=n-1;/*用以标记编码结束符位置的*/
for(c=i,f=(ht+i)->parent;f!=0;c=f,f=(ht+f)->parent)
if((ht+f)->lchild==c) { *(cd+start-1)=0;start--;}
else { *(cd+start-1)=1;start--;}
*(hc+i)=(char*)malloc((n-start)*sizeof(char));/*分配需要大小的空间并且把首地址存入hc+i的存储单元中*/
STRCOPY(hc+i,cd+start);/*字符串复制函数*/
}/*用从叶子到根逆向求编码并且存入cd中,并且分配hc将所求复制到hc,由于start标志了所求编码的开始,故把其后编码复制到hc*/
free(cd);/*释放使用的转变中间量cd*/
return OK;
}
/*注:STRCOPY和SELECT函数代码没写*/
上述代码均出自个人之手,希望对您有所提示或帮助。。也希望您能顶下本帖子。。。
[em8]
#include<malloc.h>
#define EXIT_FAILURE 0
#define ERROR -2
#define OK 1
typedef char elemtype;
typedef struct BITNODE
{
elemtype data;
struct BITNODE *lchild,*rchild;
}BITNODE,*BITREE;
/*结构体定义的二叉树结点以及结点指针*/
int PREORDER_CREAT_BITREE (BITREE t)
{
elemtype ch;
ch=getchar();
if (ch==' ')
t=NULL;
else
{
if(!(t=(BITREE)malloc( sizeof(BITNODE) )))exit(EXIT_FAILURE);
t->data=ch;
CREAT_BITREE(t->lchild);
CREAT_BITREE(t->rchild);
}
return OK;
}/*先序递归创建二叉树*/
int INORDER_CREAT_BITREE (BITREE t)
{
elemtype ch;
ch=getchar();
if (ch==' ') t=NULL;
else
{
if(!(t=(BITREE)malloc( sizeof(BITNODE) ))) exit(EXIT_FAILURE); /*fenpei ,danbu fuzhi ,yinwei shi zhongxu bianli*/
INORDER_CREAT_BITREE (t->lchild);
INORDER_CREAT_BITREE (t->rchild);
}
return OK;
}/*中序递归创建二叉树*/
int POSTORDER_CREAT_BITREE(BITREE t)
{
elemtype ch;
ch=getchar();
if(ch==' ') t=NULL;
else
{
if(!(t=(BITREE)malloc( sizeof(BITNODE) ))) exit(EXIT_FAILURE); /*fenpei ,danbu fuzhi ,yinwei shi houxu bianli*/
POSTORDER_CREAT_BITNODE(t->lchild);
POSTORDER_CREAT_BITNODE(t->rchild);
t->data=ch;
}
return OK;
}/*后序递归创建二叉树*/
int PREORDER_TRAVERSE_BITREE(BITREE t)
{
if(t)
{
if(VIST(t->data))
if(PREORDER_TRAVERSE_BITREE(t->lchild) )
if(PREORDER_TRAVERSE_BITREE(t->rchild) )
return OK;
return ERROR;
}
else return OK;
}/*先序递归遍历二叉树*/
int INORDER_TRAVERSE_BITREE(BITREE t)
{
if(t)
{
if(INORDER_TRAVERSE_BITREE(t->lchild) )
if(VIST (t->data))
if(INORDER_TRAVERSE_BITREE(t->rchild) )
return OK;
return ERROR;
}
return OK;
} /*中序递归遍历二叉树*/
int POSTORDER_TRAVERSE_BITREE(BITREE t)
{
if(t)
{
if(INORDER_TRAVERSE_BITREE(t->lchild) )
if(INORDER_TRAVERSE_BITREE(t->rchild) )
if(VIST (t->data))
return OK;
return ERROR;
}
return OK;
}/*后续递归遍历二叉树*/
/*注:上述描述中VIST是一个对结点数据操作的一个函数,可以通过函数指针传入,需要设立一个函数指针传入遍历函数*/
#include<malloc.h>
#define EXIT_FAILURE 0
#define ERROR -2
#define OK 1
typedef char elemtype;
typedef enum POINTERTAG {LINK,THREAD}POINTERTAG;
typedef struct BITHRNODE
{
elemtype data ;
struct BITHRNODE *lchild ,*rchild;
POINTERTAG LTAG,RTAG;
}BITHRNODE,*BITHRTREE;/*描述线索二叉树结点的结构体*/
void INTHREADING(BITHRTREE t,BITHRTREE pre)/*线索化函数,需要2个参数*/
{
if(t)
{
INTHREADING(t->lchild,pre);
if(!t->lchild){t->LTAG=THREAD;t->lchild=pre;}
if(!t->rchild){t->RTAG=THREAD;pre->rchild=t;}
pre=t;
INTHREADING(t->rchild,pre);
}
}/*上述函数用来进行线索化*/
int INORDER_THREAD_BITHRTREE(BITHRTREE t,BITHRTREE thrt)
{
BITHRTREE pre;/*设立指针pre始终指向操作元素(除非是空了)的前一个,即前驱*/
if(!(thrt=(BITHRTREE) malloc(sizeof(BITHRNODE))) ) exit(EXIT_FAILURE);
thrt->LTAG=LINK;
thrt->RTAG=THREAD;
thrt->rchild=thrt;
if(!t)thrt->lchild=thrt;/*初始化头结点*/
else
{
thrt->lchild=t;
pre=thrt;/*初始化头结点*/
INTHREADING(t,pre);/*调用线索化*/
pre->rchild=thrt;
pre->RTAG=THREAD;
thrt->rchild=pre;
}/*对于最后的元素进行指针的设定*/
return OK;
}/*中序线索化二叉树*/
#include<stdio.h>
#include<malloc.h>
#define EXIT_FAILURE 0
#define ERROR -2
#define OK 1
typedef char * *HUFFMANCODE;/*指向char数组的指针*/
typedef struct HTNODE
{
unsigned int weight;
unsigned int parent,lchild,rchild;
}HTNODE,*HUFFMANTREE;
int CREAT_HUFFMANCODING(HUFFMANTREE ht,HUFFMANCODE hc,int *w,int n)/*本函数构造赫夫曼树,并求出存在数组w中的n个字符的赫夫曼编码放到hc中*/
{
int m,i,start,c;
HTNODE *p;
char *cd;
unsigned int f;
if(n<=1) return ERROR;
m=2*n-1;
ht=(HTNODE *)malloc((m+1)*sizeof(HTNODE));/*不用0号单元*/
if(!ht) eixt(EXIT_FAILURE);
for(p=ht+1,i=1;i<=n;i++,p++,w++)
{
p->weight=*w;
p->parent=0;
p->lchild=0;
p->rchild=0;
}
for(;i<=m;++i,++p)
{
p->weight=0;
p->lchild=0;
p->rchild=0;
}
for(i=n+1;i<=m;i++)
{
int s1,s2;
SELECT(ht,i-1,s1,s2);/*本函数用来选择其中2个最小的权值的结点并且返回其标号*/
(ht+s1)->parent=i;
(ht+s2)->parent=i;
(ht+i)->lchild=s1;
(ht+i)->rchild=s2;
(ht+i)->weight=(ht+s1)->lchild+(ht+s2)->rchild;
}/*至此赫夫曼树构造完了*/
hc= (HUFFMANCODE) malloc ( (n+1) * sizeof (char *) ); /*第0号单元不使用*/
if(!hc)exit(EXIT_FAILURE);
cd= (char *) malloc ( n * sizeof (char) );/*分配cd来暂时保存每个求出的编码,在求下个时会被覆盖*/
if(!cd)exit(EXIT_FAILURE);
*(cd+n-1)='\0';/*编码结束符*/
for(i=1;i<=n;++i)
{
start=n-1;/*用以标记编码结束符位置的*/
for(c=i,f=(ht+i)->parent;f!=0;c=f,f=(ht+f)->parent)
if((ht+f)->lchild==c) { *(cd+start-1)=0;start--;}
else { *(cd+start-1)=1;start--;}
*(hc+i)=(char*)malloc((n-start)*sizeof(char));/*分配需要大小的空间并且把首地址存入hc+i的存储单元中*/
STRCOPY(hc+i,cd+start);/*字符串复制函数*/
}/*用从叶子到根逆向求编码并且存入cd中,并且分配hc将所求复制到hc,由于start标志了所求编码的开始,故把其后编码复制到hc*/
free(cd);/*释放使用的转变中间量cd*/
return OK;
}
/*注:STRCOPY和SELECT函数代码没写*/
上述代码均出自个人之手,希望对您有所提示或帮助。。也希望您能顶下本帖子。。。
[em8]