二叉树定义结构为:
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. 由右子树的后序序列和中序序列建立右子树。