转载-根据先序序列和中序序列创建二叉树

来源:互联网 发布:海量数据下载 编辑:程序博客网 时间:2024/05/21 17:38

出处:http://blog.csdn.net/bbs375/article/details/52745107

思考:如何才能确定一棵树?
结论:    通过中序遍历和先序遍历可以确定一个树
                通过中序遍历和后续遍历可以确定一个树
                通过先序遍历和后序遍历确定不了一个树。
单独先序遍历:能求解根,但不能求解左子树什么时候结束、右子树什么时候开始。


根据先序和中序结果画树

算法
1、通过先序遍历找到根结点A,再通过A在中序遍历的位置找出左子树,右子树
2、在A的左子树中,找左子树的根结点(在先序中找),转步骤1
3、在A的右子树中,找右子树的根结点(在先序中找),转步骤1

根据如下遍历结果创建二叉树:


先序遍历结果:ABDHKECFIGJ

中序遍历结果:HKDBEAIFCGJ



[cpp] view plain copy
print?
  1. #define _CRT_SECURE_NO_WARNINGS  
  2. #include <stdlib.h>  
  3. #include<stdio.h>  
  4. #include <string.h>  
  5.   
  6. #define  N  100  
  7.   
  8. typedef struct BiTNode    
  9. {    
  10.     char data;    
  11.     struct BiTNode *lchild,*rchild;    
  12. } BiTNode,* BITree;    
  13.   
  14. //先序遍历    
  15. void preOrder(BiTNode*root)    
  16. {    
  17.     if (root==NULL)    
  18.     {    
  19.         return;    
  20.     }    
  21.     printf(”%c ”,root->data);    
  22.     preOrder(root->lchild);    
  23.     preOrder(root->rchild);    
  24. }    
  25. //中序遍历    
  26. void inOrder(BiTNode*root)    
  27. {    
  28.     if (root==NULL)    
  29.     {    
  30.         return;    
  31.     }    
  32.     inOrder(root->lchild);    
  33.     printf(”%c ”,root->data);    
  34.     inOrder(root->rchild);    
  35. }    
  36.   
  37. /************************************************************************/  
  38. /* 算法 
  39. 1、通过先序遍历找到根结点A,再通过A在中序遍历的位置找出左子树,右子树 
  40. 2、在A的左子树中,找左子树的根结点(在先序中找),转步骤1 
  41. 3、在A的右子树中,找右子树的根结点(在先序中找),转步骤1                                                                     */  
  42. /************************************************************************/  
  43.   
  44. //根据先序遍历和中序遍历创建二叉树  
  45. BiTNode* createBiTree(char *pre, char *in, int n)  
  46. {  
  47.     int i = 0;  
  48.     int n1 = 0,n2 = 0;  
  49.     int m1 = 0,m2 = 0;  
  50.     BiTNode*node = NULL;  
  51.     char lpre[N],rpre[N];  
  52.     char lin[N],rin[N];  
  53.     if (n == 0)  
  54.     {  
  55.         return NULL;  
  56.     }  
  57.     node = (BiTNode*)malloc(sizeof(BiTNode));    
  58.     if (node==NULL)    
  59.     {    
  60.         return NULL;    
  61.     }    
  62.     memset(node,0,sizeof(BiTNode));   
  63.     //先序序列的第一个元素必为根结点  
  64.     node->data = pre[0];  
  65.     //根据根结点将中序序列分为左子树和右子数  
  66.     for (i = 0;i<n;i++)  
  67.     {  
  68.         if ((i<=n1)&&(in[i]!=pre[0]))  
  69.         {  
  70.             lin[n1++] = in[i];  
  71.         }  
  72.         else if(in[i]!=pre[0])  
  73.         {  
  74.             rin[n2++] = in[i];  
  75.         }  
  76.     }  
  77.     //根据树的先序序列的长度等于中序序列的长度  
  78.     //且先序遍历是先左子树再后子树,无论先序还是中序 左子树和右子树的长度都是固定的  
  79.     //主意 从i=1开始 因为先序遍历的第一个是根   
  80.     for (i = 1;i < n;i++)  
  81.     {  
  82.         if (i< (n1+1))//n1代表了左子树的长度  
  83.         {  
  84.             lpre[m1++] = pre[i];  
  85.         }  
  86.         else  
  87.         {  
  88.             rpre[m2++] = pre[i];  
  89.         }  
  90.     }  
  91.     node->lchild = createBiTree(lpre,lin,n1);  
  92.     node->rchild = createBiTree(rpre,rin,n2);  
  93.   
  94.     return node;  
  95. }  
  96.   
  97. int main()  
  98. {  
  99.     char preNode[N];  
  100.     char inNode[N];  
  101.     int n = 0;  
  102.     char ch;  
  103.     BiTNode* root=NULL;  
  104.     printf(”请输入先序序列\n”);  
  105.     while((ch = getchar())&&ch!=‘\n’)  
  106.         preNode[n++] = ch;  
  107.     printf(”请输入中序序列\n”);  
  108.     n = 0;  
  109.     while((ch = getchar())&&ch!=‘\n’)  
  110.         inNode[n++] = ch;  
  111.     root = createBiTree(preNode,inNode,n);  
  112.   
  113.     printf(”先序序列\n”);  
  114.     preOrder(root);  
  115.     printf(”\n中序序列\n”);  
  116.     inOrder(root);  
  117.   
  118.     system(”pause”);  
  119.     return 0;  
  120. }  
#define _CRT_SECURE_NO_WARNINGS

include <stdlib.h>

include<stdio.h>

include <string.h>

define N 100

typedef struct BiTNode
{
char data;
struct BiTNode *lchild,*rchild;
} BiTNode,* BITree;

//先序遍历
void preOrder(BiTNode*root)
{
if (root==NULL)
{
return;
}
printf("%c ",root->data);
preOrder(root->lchild);
preOrder(root->rchild);
}
//中序遍历
void inOrder(BiTNode*root)
{
if (root==NULL)
{
return;
}
inOrder(root->lchild);
printf("%c ",root->data);
inOrder(root->rchild);
}

/**************************************************************/
/* 算法
1、通过先序遍历找到根结点A,再通过A在中序遍历的位置找出左子树,右子树
2、在A的左子树中,找左子树的根结点(在先序中找),转步骤1
3、在A的右子树中,找右子树的根结点(在先序中找),转步骤1 */
/**************************************************************/

//根据先序遍历和中序遍历创建二叉树
BiTNode* createBiTree(char *pre, char *in, int n)
{
int i = 0;
int n1 = 0,n2 = 0;
int m1 = 0,m2 = 0;
BiTNode*node = NULL;
char lpre[N],rpre[N];
char lin[N],rin[N];
if (n == 0)
{
return NULL;
}
node = (BiTNode*)malloc(sizeof(BiTNode));
if (node==NULL)
{
return NULL;
}
memset(node,0,sizeof(BiTNode));
//先序序列的第一个元素必为根结点
node->data = pre[0];
//根据根结点将中序序列分为左子树和右子数
for (i = 0;i<n;i++)
{
if ((i<=n1)&&(in[i]!=pre[0]))
{
lin[n1++] = in[i];
}
else if(in[i]!=pre[0])
{
rin[n2++] = in[i];
}
}
//根据树的先序序列的长度等于中序序列的长度
//且先序遍历是先左子树再后子树,无论先序还是中序 左子树和右子树的长度都是固定的
//主意 从i=1开始 因为先序遍历的第一个是根
for (i = 1;i < n;i++)
{
if (i< (n1+1))//n1代表了左子树的长度
{
lpre[m1++] = pre[i];
}
else
{
rpre[m2++] = pre[i];
}
}
node->lchild = createBiTree(lpre,lin,n1);
node->rchild = createBiTree(rpre,rin,n2);

return node;

}

int main()
{
char preNode[N];
char inNode[N];
int n = 0;
char ch;
BiTNode* root=NULL;
printf(“请输入先序序列\n”);
while((ch = getchar())&&ch!=’\n’)
preNode[n++] = ch;
printf(“请输入中序序列\n”);
n = 0;
while((ch = getchar())&&ch!=’\n’)
inNode[n++] = ch;
root = createBiTree(preNode,inNode,n);

printf("先序序列\n");preOrder(root);printf("\n中序序列\n");inOrder(root);system("pause");return 0;

}


阅读全文
0 0
原创粉丝点击