一、二叉树的三种遍历
常用命令
创建二叉树
bitree * tree_create() {
data_t ch;
bitree *r;
scanf("%c", &ch);
if (ch == '#')
return NULL;
if ((r = (bitree *)malloc(sizeof(bitree))) == NULL) {
printf("malloc failed\n");
return NULL;
}
r->data = ch;//封装节点
r->left = tree_create(); //左子树
r->right = tree_create(); //右子树
return r;
}
先序遍历
//先序遍历
void preorder(bitree * r) {
if (r == NULL) {
return;
}
printf("%c", r->data);//根
preorder(r->left);//左
preorder(r->right);//右
}
中序遍历
//中序遍历
void inorder(bitree * r) {
if (r == NULL) {
return;
}
inorder(r->left);
printf("%c", r->data);
inorder(r->right);
}
后序遍历
//后序遍历
void postorder(bitree * r) {
if (r == NULL) {
return;
}
postorder(r->left);
postorder(r->right);
printf("%c", r->data);
}
层次遍历
void layerorder(bitree * r) {
linkqueue * lq;
if ((lq = queue_create()) == NULL)
return;
if (r == NULL)
return;
printf("%c", r->data);//访问
enqueue(lq, r);//入队
while (!queue_empty(lq)) {//队列不为空
r = dequeue(lq);//出队
if (r->left) {//左子树存在
printf("%c", r->left->data);//访问
enqueue(lq, r->left);//入队
}
if (r->right) {//右子树存在
printf("%c", r->right->data);//访问
enqueue(lq, r->right);//入队
}
}
puts("");
}
二、二叉树的层次遍历
void layerorder(bitree * r) {
linkqueue * lq;
if ((lq = queue_create()) == NULL)
return;
if (r == NULL)
return;
printf("%c", r->data);//访问
enqueue(lq, r);//入队
while (!queue_empty(lq)) {//队列不为空
r = dequeue(lq);//出队
if (r->left) {//左子树存在
printf("%c", r->left->data);//访问
enqueue(lq, r->left);//入队
}
if (r->right) {//右子树存在
printf("%c", r->right->data);//访问
enqueue(lq, r->right);//入队
}
}
puts("");
}
三、实现
头文件
tree.h
#ifndef _TREE_H_
#define _TREE_H_
typedef char data_t;
typedef struct node_t {
data_t data;//数据部分
struct node_t * left;//左孩子
struct node_t * right;//右孩子
}bitree;
bitree * tree_create();
void preorder(bitree * r);//先序遍历
void inorder(bitree * r);//中序
void postorder(bitree * r);//后序
void layerorder(bitree * r);
#endif
linkqueue.h
#include "tree.h"
typedef bitree * datatype;
typedef struct node {
datatype data;
struct node *next;
}listnode , *linklist;
typedef struct {
linklist front;
linklist rear;
}linkqueue;
linkqueue * queue_create();
int enqueue(linkqueue *lq, datatype x);
datatype dequeue(linkqueue *lq);
int queue_empty(linkqueue *lq);
int queue_clear(linkqueue *lq);
linkqueue * queue_free(linkqueue *lq);
源程序
tree.c
#include <stdio.h>
#include <stdlib.h>
//#include "tree.h" //"linkqueue.h"中包含"tree.h"
#include "linkqueue.h"
bitree * tree_create() {
data_t ch;
bitree *r;
scanf("%c", &ch);
if (ch == '#')
return NULL;
if ((r = (bitree *)malloc(sizeof(bitree))) == NULL) {
printf("malloc failed\n");
return NULL;
}
r->data = ch;//封装节点
r->left = tree_create(); //左子树
r->right = tree_create(); //右子树
return r;
}
//先序遍历
void preorder(bitree * r) {
if (r == NULL) {
return;
}
printf("%c", r->data);//根
preorder(r->left);//左
preorder(r->right);//右
}
//中序遍历
void inorder(bitree * r) {
if (r == NULL) {
return;
}
inorder(r->left);
printf("%c", r->data);
inorder(r->right);
}
//后序遍历
void postorder(bitree * r) {
if (r == NULL) {
return;
}
postorder(r->left);
postorder(r->right);
printf("%c", r->data);
}
void layerorder(bitree * r) {
linkqueue * lq;
if ((lq = queue_create()) == NULL)
return;
if (r == NULL)
return;
printf("%c", r->data);//访问
enqueue(lq, r);//入队
while (!queue_empty(lq)) {//队列不为空
r = dequeue(lq);//出队
if (r->left) {//左子树存在
printf("%c", r->left->data);//访问
enqueue(lq, r->left);//入队
}
if (r->right) {//右子树存在
printf("%c", r->right->data);//访问
enqueue(lq, r->right);//入队
}
}
puts("");
}
linkqueue.c
#include <stdio.h>
#include <stdlib.h>
#include "tree.h"
#include "linkqueue.h"
linkqueue * queue_create() {
linkqueue *lq;
if ((lq = (linkqueue *)malloc(sizeof(linkqueue))) == NULL) {
printf("malloc linkqueue failed\n");
return NULL;
}
lq->front = lq->rear = (linklist)malloc(sizeof(listnode));
if (lq->front == NULL) {
printf("malloc node failed\n");
return NULL;
}
lq->front->data = 0;
lq->front->next = NULL;
return lq;
}
int enqueue(linkqueue *lq, datatype x) {
linklist p;
if (lq == NULL) {
printf("lq is NULL\n");
return -1;
}
if ((p = (linklist)malloc(sizeof(listnode))) == NULL) {
printf("malloc node failed\n");
return -1;
}
p->data = x;
p->next = NULL;
lq->rear->next = p;
lq->rear = p;
return 0;
}
datatype dequeue(linkqueue *lq) {
linklist p;
if (lq == NULL) {
printf("lq is NULL\n");
return NULL;
}
p = lq->front;
lq->front = p->next;
free(p);
p = NULL;
return (lq->front->data);
}
int queue_empty(linkqueue *lq) {
if (lq == NULL) {
printf("lq is NULL\n");
return -1;
}
return (lq->front == lq->rear ? 1 : 0);
}
int queue_clear(linkqueue *lq) {
linklist p;
if (lq == NULL) {
printf("lq is NULL\n");
return -1;
}
while (lq->front->next) {
p = lq->front;
lq->front = p->next;
//printf("clear free:%d\n", p->data);
free(p);
p = NULL;
}
return 0;
}
linkqueue * queue_free(linkqueue *lq) {
linklist p;
if (lq == NULL) {
printf("lq is NULL\n");
return NULL;
}
while (lq->front) {
p = lq->front;
lq->front = p->next;
//printf("free:%d\n", p->data);
free(p);
}
free(lq);
lq = NULL;
return NULL;
}
测试文件test.c
#include <stdio.h>
#include "tree.h"
int main(int argc, const char *argv[])
{
bitree * r;
if ((r = tree_create()) == NULL)
return -1;
preorder(r);
puts("");
inorder(r);
puts("");
postorder(r);
puts("");
layerorder(r);
return 0;
}
四、作业
已知遍历结果如下,试画出对应的二叉树
前序: A B C E H F I J D G K
中序: A H E C I F J B D K G
(利用遍历规则的特点,还原二叉树,提交还原的二叉树,或者写出后序遍历结果)
后序遍历结果:HEIJFCKGDBA