构建二叉树及一些基本操作
二叉树的存储结构主要有二叉链表和数组,根据不同的遍历结果可以构建二叉树(一定要有中序遍历结果)
构建二叉树
扩展先序序列构建二叉树
‘#’代表虚结点
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define ElemType char
typedef struct BiNode{
ElemType data;
struct BiNode *lchild, *rchild;
}BiNode,*BiTree;
void InitBiTree (BiTree *BT);
void CreatBiTree (BiTree *BT);//二级指针
void InOrderTraverse (BiTree BT);
int main (void) {
BiTree BT;
InitBiTree (&BT);
CreatBiTree (&BT);
InOrderTraverse (BT);
printf ("\n");
return 0;
}
void InitBiTree (BiTree *BT) {
(*BT) = NULL;
}
void CreatBiTree (BiTree *BT) {
ElemType ch;
ch = getchar();
if (ch == '#') (*BT) = NULL;
else {
(*BT) = (BiTree)malloc(sizeof(BiNode));
(*BT)->data = ch;
CreatBiTree(&(*BT)->lchild);//依然要用二级指针
CreatBiTree(&(*BT)->rchild);
}
}
先序和中序遍历序列构建二叉树
BiTree CreatBT (ElemType *pre, ElemType *in, int n) {
BiTree s;
ElemType *p;
int k;
if (n == 1) {
s = (BiTree)malloc(sizeof(BiTNode));
s->data = *pre;
s->lchild = NULL;
s->rchild = NULL;
return s;
}
for (p = in; p < in + n; p++){
if (*p == *pre) break;
}
k = p - in;
s = (BiTree)malloc(sizeof(BiTNode));
s->data = *pre;
s->lchild = NULL;
s->rchild = NULL;
if (k) s->lchild = CreatBT (pre + 1, in, k);
if (n - k -1) s->rchild = CreatBT (pre + k + 1, p + 1, n - k - 1);
return s;
}
层次遍历及中序遍历构建二叉树
参考这位的思路层次遍历和中序遍历构建二叉树。我个人因为先写的先序和中序序列构建二叉树,思维有些固化,而层次遍历和先序遍历在左右递归建立左右子树这个地方有蛮大的区别,需要多琢磨。
BiTree CreatTree (ElemType *layer, ElemType *in, int lay1, int lay2, int in1, int in2) {
if (in1 > in2) {
return NULL;
}
BiTree T;
T = (BiTree)malloc(sizeof(BiTNode));
T->lchild = NULL;
T->rchild = NULL;
ElemType i, j;
int flag = 0;
for (i = lay1; i <= lay2; i++){
for (j = in1; j <= in2; j++) {
if (layer[i] == in[j]) {
flag = 1;
//printf ("%d %d %d\n",layer[i], in[j], i);
break;
}
}
if (flag == 1) break;
}
T->data = layer[i];
T->lchild = CreatTree (layer, in, lay1 + 1, lay2, in1, j - 1);
T->rchild = CreatTree (layer, in, lay1 + 1, lay2, j + 1, in2);
return T;
}
中序和后序遍历构建二叉树
(肝完作业来补坑…)
含虚结点的二叉树
如abc@@de@#,#代表输入结束,@代表虚结点。
(肝完作业来补坑…)
二叉树的输出
先判空再输出
先序输出
void PreOrderTraverse (BiTree T) {
if (T) {
printf ("%d ", T->data);
PreOrderTraverse (T->lchild);
PreOrderTraverse (T->rchild);
}
}
中序输出
void InOrderTraverse (BiTree BT) {
if (BT) {
InOrderTraverse (BT->lchild);
printf ("%c ", BT->data);
InOrderTraverse (BT->rchild);
}
}
后序输出
void PostOrderTraverse (BiTree T) {
if (T) {
PostOrderTraverse (T->lchild);
PostOrderTraverse (T->rchild);
printf ("%d ",T->data);
}
}
叶子结点
输出叶子结点
void LeafNode (BiTree T) {
if (T) {
if (T->lchild == NULL && T->rchild == NULL) {
printf ("%d ", T->data);
}
else {
LeafNode (T->lchild);
LeafNode (T->rchild);
}
}
}
输出叶子结点个数
判断条件同上,将输出改为计数。