#include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> #define OK 1 #define NO 0 #define ERROR -1 #define TRUE 1 #define FALSE 0 #define MAXSIZE 50 typedef int Status; typedef char TElemType; typedef struct BiTNode { TElemType data; struct BiTNode* lchild; struct BiTNode* rchild; }BiTNode; typedef BiTNode* BiTree; typedef BiTree SElemType_Sq; void InitBiTree(BiTree *T);//构造二叉树,初始化二叉树 void ClearBiTree(BiTree *T);//清空二叉树 void DestroyBiTree(BiTree *T);//销毁二叉树 Status BiTreeEmpty(BiTree T);//判断树是否为空 void CreatBitTree(BiTree *T);//按先序序列构造二叉树 int BiTreeLength(BiTree T);//返回二叉树的长度,按完全二叉树计算 int TreeDepth(BiTree T);//返回树的深度(层数) Status Root(BiTree T,TElemType *e);//返回根结点的值 TElemType Value(BiTree p);//返回某结点的值,p为节点指针 void Assign(BiTree p,TElemType value);//为某结点赋值 !!分析一下 不是需要*p传进去吗 ?里面是对它结构的值进行操作 TElemType Parent(BiTree T,TElemType e);//返回某结点的双亲结点值 TElemType LeftChild(BiTree T,TElemType e);//返回某结点左孩子的值 TElemType RightChild(BiTree T,TElemType e);//返回某结点右孩子的值 TElemType LeftSibling(BiTree T,TElemType e);//返回某结点左兄弟结点的值 TElemType RightSibling(BiTree T,TElemType e);//返回某结点右兄弟结点的值 void Leve1orderTraverse_1(BiTree T);//层序遍历二叉树 void PreOrderTraverse_1(BiTree T);//先序遍历二叉树 void InOrderTraverse_1(BiTree T);//中序遍历二叉树 void PostOrderTraverse(BiTree T);//后序遍历二叉树 void PrintTree(BiTree T,int level); int main(int argc,char **argv) { BiTree T ; printf("1\n函数InitBiTree 测试..\n"); { printf("初始化一个空二叉树 T..\n"); InitBiTree(&T);//要对T的值进行改变,肯定要传递T的指针进去,因此要用二重指针。 printf("\n"); } printf("4\n函数BiTreeEmpty 测试..\n"); { BiTreeEmpty(T)?printf(" T 为空!!"):printf(" T 不为空!!"); printf("\n"); } printf("5\n函数CreatBitTree 测试..\n"); { printf("按先序序列创建二叉树..\n"); printf("作为示范,录入先序序列:ABDG###EH##I##CF#J###\n"); CreatBitTree(&T); printf("\n"); } /*printf("23\n函数PrintTree 测试..\n"); { printf("按二叉树结构打印树:T= \n"); PrintTree(T,1); printf("\n"); }*/ printf("7\n函数BiTreeDepth 测试..\n"); { printf("T的深度为%d \n",TreeDepth(T)); printf("\n"); } printf("19\n函数Leve1orderTraverse_1 测试..\n"); { printf("层序遍历二叉树 T = "); Leve1orderTraverse_1(T); printf("\n\n"); } printf("19\n函数PreOrderTraverse_1 测试..\n"); { printf("先序遍历二叉树1 T = "); PreOrderTraverse_1(T); printf("\n\n"); } printf("19\n函数InOrderTraverse_1 测试..\n"); { printf("中序遍历二叉树1 T = "); InOrderTraverse_1(T); printf("\n\n"); } printf("19\n函数PostOrderTraverse 测试..\n"); { printf("后序遍历二叉树 T = "); PostOrderTraverse(T); printf("\n\n"); } printf("8\n函数Root 测试..\n"); { TElemType e; Root(T,&e); printf("T的根结点为:%c \n",e); printf("\n"); } printf("9\n函数Value 测试..\n"); { BiTree p=T->lchild->rchild->lchild; printf("指针p指向的结点值为%c \n",Value(p)); printf("\n"); } printf("10\n函数Assign 测试..\n"); { BiTree p=T->lchild->rchild->lchild; Assign(p,'X'); printf("将'X'赋给 p 指向的结点后,T = \n"); Leve1orderTraverse_1(T); printf("\n"); } printf("11\n函数Parent 测试..\n"); { printf("'X'结点的双亲为:%c \n",Parent(T,'X')); printf("\n"); } printf("12、13\n函数LeftChild、RightChild测试..\n"); { printf("'E'的左孩子结点值为:%c,右孩子结点值为:%c\n",LeftChild(T,'E'),RightChild(T,'E')); printf("\n"); } printf("14\n函数LeftSibling测试..\n"); { printf("'I'的左兄弟值为:%c",LeftSibling(T,'I')); printf("\n"); } printf("15\n函数RightSibling测试..\n"); { printf("'X'的右兄弟值为:%c",RightSibling(T,'X')); printf("\n"); } printf("2\n函数ClearBiTree 测试..\n"); { ClearBiTree(&T); if(BiTreeEmpty(T)) printf("T 已被清空!\n"); printf("\n"); } return 0; } void InitBiTree(BiTree *T){ *T=NULL; } Status BiTreeEmpty(BiTree T){ return T==NULL?TRUE:FALSE; } void ClearBiTree(BiTree *T){ if(*T) { if((*T)->lchild) ClearBiTree(&((*T)->lchild)); if((*T)->rchild) ClearBiTree(&((*T)->rchild)); free(*T); *T=NULL; } } void CreatBitTree(BiTree *T){ char ch; scanf("%c",&ch); if(ch=='#') *T=NULL; else { *T=(BiTree)malloc(sizeof(BiTNode)); if(!(*T)) exit(-1); (*T)->data=ch; CreatBitTree(&(*T)->lchild); CreatBitTree(&(*T)->rchild); } } int TreeDepth(BiTree T){ if(T==NULL){ return 0; } int nLeft=TreeDepth(T->lchild); int nRight=TreeDepth(T->rchild); return nLeft>nRight?nLeft+1:nRight+1; /***************************************************************************************** *首先如果树T是空的话,就返回深度为0,否则求该树的左孩子的深度和右孩子的深度,两者相互比较* *返回一个较大的值,递归的最后一层返回的是0值,遇到NULL说明是第0层,最后必然是两个NULL因此* *碰到叶子之后叶子返回的是1.然后一层层递归回去。 * ******************************************************************************************/ } void Leve1orderTraverse_1(BiTree T){ int i,j; BiTree p[100]; i=j=0; if(T) p[j++]=T;//如果T存在那么就p[j]指向T并且j++; while(i<j) //j在每一次取值之后就会比原先+1;j比i要多出来的数值就是结点的个数,j从0开始赋值,而j++作为其最后的状态,并没有值。 { printf("%c ",p[i]->data);//相当于按顺序输出数组的元素 if(p[i]->lchild) p[j++]=p[i]->lchild;//将存在的结点按照顺输入到数组中 if(p[i]->rchild) p[j++]=p[i]->rchild; i++; } } void PreOrderTraverse_1(BiTree T){ if(T) { printf("%c ",T->data); PreOrderTraverse_1(T->lchild); PreOrderTraverse_1(T->rchild); } } void InOrderTraverse_1(BiTree T){ if(T){ InOrderTraverse_1(T->lchild); printf("%c ",T->data); InOrderTraverse_1(T->rchild); } } void PostOrderTraverse(BiTree T){ if(T){ PostOrderTraverse(T->lchild); PostOrderTraverse(T->rchild); printf("%c ",T->data); } } Status Root(BiTree T,TElemType *e){ if(!T) return ERROR; else { *e=T->data; return OK; } } TElemType Value(BiTree p){ return p->data; } void Assign(BiTree p,TElemType value){ p->data=value; } TElemType Parent(BiTree T,TElemType e){ /************************************************************************************************************** *parent的实现方法: * * 从root出发,先求各个结点的左孩子,并且判断是否是要求的X的父亲,将每个经过的左结点放在一个数组中node[0]……* * 然后判断到最后一个左结点,而其没有左孩子的时候,结束循环,并且在循环的过程中,将每一个不符合的结点的左孩子* * 置为NULL,这样后来经过这些结点的时候就不会再重新进入循环,同时这也作为判断该节点是否是符合条件的附件的判据* * 之一(另一个是右孩子)。然后进入第二个if语句,如果最左边的叶子的右孩子存在,那么用node[i+1]将其标记,并且 * * 将node[i]的右孩子置为空,这时候相当于去除了这个结点,它不符合条件。然后新的node作为循环的起始点,继续进行 * * 判断。 * * 而若右结点不存在,即为NULL,这个时候它的孩子肯定也是NULL,因此不影响判断的进行,同时将node[i]标记。然后i--* * 返回上一层由于node[i]都被标记因此,i--继续返回上一个结点,然后对node[i-1]的右结点进行判断,迭代一直到root * * i的作用:起到控制循环次数,终止循环的作用 * ***************************************************************************************************************/ BiTNode node[100]; int i=0; if(T==NULL||(T!=NULL&&e==T->data)) return '\0'; node[i]=*T; while(i>=0) { while(node[i].lchild) { if(node[i].lchild->data==e) return node[i].data; node[i+1]=*(node[i].lchild); node[i].lchild=NULL; i++; } if(node[i].rchild) { if(node[i].rchild->data==e) return node[i].data; node[i+1]=*(node[i].rchild); node[i].rchild=NULL; i++; } if(node[i].lchild==NULL&&node[i].rchild==NULL) i--; } if(i<0)//说明元素X不在二叉树中 return '\0'; } TElemType LeftChild(BiTree T,TElemType e){ /********************************************************************************************************************************* * LeftChild实现方法: * * 首先找左边的结点,如果其中某个结点的值就等于要E那么就直接返回它的左孩子,如果没有找到的话,就依次将左边的结点存入node[i]中,* * 直到node[i]最后没有左孩子为止,这个时候,如果该结点的右孩子存在,那么将右孩子的结点直接赋予node[i+1],可由循环继续进行上述 * * 判断,并且标记这个时候的node[i]的右孩子也是NULL,相当于去掉这个结点。 * * 这个时候判断node[i+1]如果它没有左孩子,也没有右孩子,那么这个时候,就会执行i--然后进行上一个node[i]的判断,由于node[i]的左 * * 孩子被置为NULL,因此不会进入循环,而是直接判断后面的右孩子是否存在,然后一直迭代到最后。 * *********************************************************************************************************************************/ BiTNode node[100]; int i=0; if(!T) return '\0'; node[i]=*T; while(i>=0) { while(node[i].data!=e&&node[i].lchild) { node[i+1]=*(node[i].lchild); node[i].lchild=NULL; i++; } if(node[i].data==e) { if(node[i].lchild) return node[i].lchild->data; else return '\0'; } if(node[i].rchild) { node[i+1]=*(node[i].rchild); node[i].rchild=NULL; i++; } if(node[i].lchild==NULL&&node[i].rchild==NULL&&node[i].data!=e) i--; } if(i<0) return '\0'; } TElemType RightChild(BiTree T,TElemType e){ BiTNode node[100]; int i=0; if(!T) return '\0'; node[i]=*T; while(i>=0) { while(node[i].data!=e&&node[i].lchild) { node[i+1]=*(node[i].lchild); node[i].lchild=NULL; i++; } if(node[i].data==e) { if(node[i].lchild) return node[i].rchild->data; else return '\0'; } if(node[i].rchild) { node[i+1]=*(node[i].rchild); node[i].rchild=NULL; i++; } if(node[i].lchild==NULL&&node[i].rchild==NULL&&node[i].data!=e) i--; } if(i<0) return '\0'; } TElemType LeftSibling(BiTree T,TElemType e){ BiTNode node[100]; int i=0; if(((T!=NULL)&&(e==T->data))||T==NULL) return '\0'; node[i]=*T; while(i>=0){ while(node[i].rchild) { if(node[i].rchild->data==e) { if(node[i].lchild) return node[i].lchild->data; else return '\0'; } node[i+1]=*(node[i].rchild); node[i].rchild=NULL; i++; } if(node[i].lchild) { if(node[i].lchild->data==e) return '\0'; node[i+1]=*(node[i].lchild); node[i].lchild=NULL; i++; } if(node[i].lchild==NULL&&node[i].rchild==NULL) i--; } if(i<0) return '\0'; } TElemType RightSibling(BiTree T,TElemType e){ BiTNode node[100]; int i=0; if(((T!=NULL)&&(e==T->data))||T==NULL) return '\0'; node[i]=*T; while(i>=0){ while(node[i].lchild) { if(node[i].lchild->data==e) { if(node[i].rchild) return node[i].rchild->data; else return '\0'; } node[i+1]=*(node[i].lchild); node[i].lchild=NULL; i++; } if(node[i].rchild) { if(node[i].rchild->data==e) return '\0'; node[i+1]=*(node[i].rchild); node[i].rchild=NULL; i++; } if(node[i].lchild==NULL&&node[i].rchild==NULL) i--; } if(i<0) return '\0'; } /* void PrintTree(BiTree T,int level){ int i; PrintTree(T->rchild,level+1); for(i=0;i<level;i++) printf(" "); printf("%c\n",T->data); PrintTree(T->lchild,level+1); } 树状输出一直有些问题,需要再深入思考 */
//文章参考 http://www.cnblogs.com/kangjianwei101/p/5222014.html