二叉树
来源:互联网 发布:c语言开发游戏 编辑:程序博客网 时间:2024/06/16 21:33
二叉树定义结构为:
typedef struct BtNode{ ElemType data; BtNode *leftchild; BtNode *rightchild;}BtNode,*BinaryTree;
二叉树遍历<递归实现>
//先序遍历void PreOrder(BtNode *ptr){ if(NULL != ptr) { cout<<ptr->data; PreOrder(ptr->leftchild); PreOrder(ptr->rightchild); }}//中序遍历void InOrder(BtNode *ptr){ if(ptr->leftchild != NULL) { InOrder(ptr->leftchild); } cout<<ptr->data; if(ptr->rightchild !=NULL) { InOrder(ptr->rightchild); }}//后序遍历void PastOrder(BtNode *ptr){ if(ptr != NULL) { PastOrder(ptr->leftchild); PastOrder(ptr->rightchild); cout<<ptr->data; }}
创建树
//创建结点函数BtNode * BuyNode(){ BtNode *node = (BtNode*)malloc(sizeof(BtNode)); if(NULL == node) exit(1); memset(node, 0, sizeof(node)); return node;}BtNode * CreateTree1(){ BtNode *s = NULL; ElemType m; cin>>m; if(m != END) { s = BuyNode(); s->data = m; s->leftchild = CreateTree1(); s->rightchild = CreateTree1(); } return s;}
对于str=”ABC##DE##F##G#H##”,如果使用CreateTree2()函数实现,会创建一棵什么样的树呢?
BtNode * CreateTree2(char *str){ BtNode *p = NULL; if(NULL != str && *str != END) { p = BuyNode(); p->data = *str; p->leftchild = CreateTree2(++str); p->rightchild = CreateTree2(++str); } return p;}
生成的树是:
函数调用过程如下:
不同空间,每次函数递归调用会开辟栈帧空间。
将CreateTree2()函数修改后,
BtNode * CreateTree2(char *&str){ BtNode *p = NULL; if(NULL != str && *str != END) { p = BuyNode(); p->data = *str; p->leftchild = CreateTree2(++str); p->rightchild = CreateTree2(++str); } return p;}
参数str前加了&后,相当于是变为二级指针**,每一次函数递归调用都会把字符串str遍历一遍。
类似如下:
BtNode * CreateTree3(char ** const pstr){ BtNode *p = NULL; if(pstr != NULL && *pstr != NULL && **pstr != END) { p = BuyNode(); p->data = **pstr; //++*pstr; //p->leftchild = CreateTree3(pstr); p->leftchild = CreateTree3(&(++*pstr));////// p->rightchild = CreateTree3(&(++*pstr)); } return p;}
调用过程如下:
二叉树的结点个数
int Size(BtNode *ptr){ if(ptr == NULL) { return 0; } else { return Size(ptr->leftchild)+Size(ptr->rightchild)+1; }}
二叉树的深度
int Depth(BtNode *ptr){ if(ptr == NULL) return 0; int m = Depth(ptr->leftchild); int n = Depth(ptr->rightchild); return m>n ? m+1 : n+1;}
查找元素
BtNode* FindValue(BtNode *ptr,ElemType x){ if(ptr == NULL || ptr->data == x)//如果根节点为空或查找x为根节点 { return ptr; } else { BtNode *p = FindValue(ptr->leftchild,x); if(NULL == p)//p为空,查找右子树 { p = FindValue(ptr->rightchild,x); } return p; }}
查找父节点
BtNode * Parent(BtNode *ptr,BtNode *child)//找父节点{ if(ptr != NULL || ptr->leftchild==child || ptr->rightchild==child) { return ptr; } else { BtNode *p = Parent(ptr->leftchild,child); if(p == NULL) { p = Parent(ptr->rightchild,child); } return p; }}BtNode * FindParent(BtNode *ptr,BtNode *child){ if(ptr == NULL || child == NULL || ptr == child) { return NULL; } else { return Parent(ptr,child); }}
在后序序列中查找元素
int FindIs(ElemType *is,ElemType x,int n){ int pos = -1;//位置偏移量 for(int i=0; i<n; ++i) { if(is[i] == x) { pos = i; break; } } return pos;}
根据中序和先序 创建树
已知一棵二叉树的前序序列和中序序列,构造该二叉树的过程如下:
1. 根据前序序列的第一个元素建立根结点;
2. 在中序序列中找到该元素,确定根结点的左右子树的中序序列;
3. 在前序序列中确定左右子树的前序序列;
4. 由左子树的前序序列和中序序列建立左子树;
5. 由右子树的前序序列和中序序列建立右子树。
BtNode * CreatePI(ElemType *ps,ElemType *is,int n){ BtNode *s = NULL; if(n > 0) { s = BuyNode(); s->data = ps[0]; int pos = FindIs(is,ps[0],n); if(pos == -1) exit(1); s->leftchild = CreatePI(ps+1,is,pos); s->rightchild = CreatePI(ps+pos+1,is+pos+1,n-pos-1); } return s;}BtNode * CreateTreePI(ElemType *ps,ElemType *is,int n){ if(ps==NULL || is==NULL || n<1) return NULL; else { return CreatePI(ps, is, n); }}BtNode* CreateIL(ElemType *is,ElemType *ls,int n){ BtNode *s = NULL; if(n > 0) { s = BuyNode(); s->data = ls[n-1];//后序序列的最后一个是根节点 int pos = FindIs(is,ls[n-1],n);//在中序序列中查找根节点,确定左右子树 int leftLen; int rightLen; leftLen = pos; rightLen = n-pos-1; if(leftLen > 0)//建立左子树 { s->leftchild = CreateIL(is,ls,leftLen); } if(rightLen > 0) { s->rightchild = CreateIL(is+leftLen+1,ls+leftLen,rightLen); } } return s;}
根据中序和后序 创建树
根据先序和后序不能创建一棵树
已知一棵二叉树的后序序列和中序序列,构造该二叉树的过程如下:
1. 根据后序序列的最后一个元素建立根结点;
2. 在中序序列中找到该元素,确定根结点的左右子树的中序序列;
3. 在后序序列中确定左右子树的后序序列;
4. 由左子树的后序序列和中序序列建立左子树;
5. 由右子树的后序序列和中序序列建立右子树。
阅读全文