hello,你们好,明天就是"double eleven了,不知道你们准备好没有,咱们仍是加班加点的把二叉树来看一下。node
在讲遍历以前,咱们首先应该了解一下二叉树是怎么创建的 数组
3 / \ 9 20 / \ 15 7
你可能会看到这样的一颗二叉树,那么这颗二叉树的根节点就是 3 ,而它的两个孩子结点就是 9 和 20 ,在咱们创建一颗二叉树的时候,
就算它只有一个或者没有孩子,咱们也要把另一个或两个孩子补上去,能够是空格,也能够是其余你本身定义的特殊字符。(可是补了字符的两个孩子就不用管了。)
看了上面,相信你对二叉树已经有了一个印象了,让咱们开始吧。函数
1、结构体post
typedef struct node{
elemtype data; //注意这里的 elemtype 前面要设置成 char 类型(也就是字符串),指针
//由于咱们的二叉树可能会是字母什么的
struct node*lchild,*rchild; //而后构造它的两个孩子指针,跟以前的 next 差很少,就是一个blog
//指向左边的 next 和一个指向右边的 next
}node,*btnode; //常规定义 node 数组名和 btnode 指针类型名递归
2、创建二叉树图片
3 / \ 9 20 / \ 15 7
关于方法,上面有提到,这里再提两点:字符串
1,在构造数的过程当中,由于用到的是递归,因此当咱们构造了 3 以后,再构造 9 时,就又能够把它当作是一个新的跟结点,这就是咱们递归的原理。it
2,就是咱们的二叉树的输入问题了,由于存在着某些孩子结点不存在的状况,因此在输入的时候就要注意了,如上图,咱们的输入就应该是:
(咱们的表空字符设为 * )
39**2015**7***
是的,元素之间没有空格,咱们的输入按照的是前序遍历的输入(当初满二叉树的前序),在没有的地方补上表空字符 * 就行了
你们会不会问为何 15 后面有两个 * 呢,咱们前面提到的就算没有可是也要补上去就是这个了,9 后面构造了两个,而后构造的节点后面就不用管啦
#注意最后一个节点必须多输入一个 * ,这样计算机才知道已经输入完了
Status creat_btree(btnode *T){
elemtype ch; //定义一下咱们即将输入的元素
scanf("%c",&ch); //直接一次性输入全部元素,计算机会一个
//一个读取
if(ch == ' ') (*T) = NULL; //这里的空格就是咱们的表空字符,当这个
//孩子不存在的时候,就能够把它的指针
//定位 NULL 了
else{
if(!((*T) = (btnode)malloc(sizeof(node)))) exit(ERROR);
(*T)->data=ch; //空间分配成功,就能够给咱们的结点赋值了。
creat_btree(&(*T)->lchild); //赋完值以后,利用递归,就能够先构造它的
//左边(左子树)
creat_btree(&(*T)->rchild); //构造右子树
}
return OK; //你们能够试着想一下,先是跟结点,而后是它
//的孩子,当其中一个孩子的孩子的孩子......就算
//没有的也构造完了,这个孩子就完成了,就
//经过return 返回,
//进行下一个递归,最后一个 return(也就是咱们
//多写的那个 * )
//返回以后,就表明结束啦。
}
在遍历以前,我须要先设置一个 printf 函数
Status print(elemtype e){
printf("%c ",e);
return OK;
}
3、前序遍历
前序遍历首先访问根节点,而后遍历左子树,最后遍历右子树。(以下图)
Status preorder(btnode T,Status (* print)(elemtype e)){ //你们是否是对这里的参数感到奇怪,
//经过后面的参数。咱们就能够在子函数
//里面调用咱们定义了的其余子函数了
if(T){ //先判断根节点是否为空
if (print(T->data)) //非空的话就能够输出它所表明的元素了
if(preorder(T->lchild,print)) //而后再对左边进行遍历,注意一下 preorder
//的函数调用方式
if(preorder(T->rchild,print)) //接着是右边
return OK; //这个 OK 跟咱们建立二叉树的原理是同样的
//(其实递归的原理都差很少)
else return ERROR;
}
else return OK;
}
4、中序遍历
中序遍历是先遍历左子树,而后访问根节点,而后遍历右子树。
Status inorder(btnode T,Status (* print)(elemtype e)){
if(T){
if(inorder(T->lchild,print))
if (print(T->data))
if(inorder(T->rchild,print))
return OK;
else return ERROR; //别的就很少说了,提一下这里
//的 return ERROR ,这个必须是跟
//print(T->data)的 if 对齐的,为了防止
//输入或者输出的时候有误,
//用来退出错误项的。
}
else return OK;
}
5、后序遍历
后序遍历是先遍历左子树,而后遍历右子树,最后访问树的根节点。
Status postorder(btnode T,Status (* print)(elemtype e)){
if(T){
if(postorder(T->lchild,print))
if(postorder(T->rchild,print))
if (print(T->data))
return OK;}
else return ERROR;
else return OK;
}
差很少就很少说了。
附:main函数
void main()
{
node t;btnode T = &t; //这里记住要指一下。
creat_btree(&T);
printf("前序遍历为:");preorder(T,print);
printf("\n中序遍历为:");inorder(T,print);
printf("\n后序遍历为:");postorder(T,print);
system("pause");
}
全部图片来自LeetCode