一、说明
本文的Stack.h参考博客中的栈,Queue.h参考博客中的队列。
二、二叉树概念
一棵二叉树时结点的一个有限集合,该集合或者为空,或者是由一个根结点加上两棵分别为左子树和右子树组成;二叉树每个结点最多有两棵子树,子树有左右之分,次序不能颠倒。
三、二叉树的前中后非递归遍历
二叉树的前中后递归遍历非常简单,但是非递归有点小难,所以我把非递归的算法思想说一下,在实现非递归时我们需要利用到栈。
前序:我们先说一下前序的非递归(以下全是非递归,不再作说明),光靠文字表述可能会不清楚,所以我画了个草图,以下也用此二叉树为例。
因为前序的顺序是根左右,所以我们先遍历和入栈的顺序是A、B、D,当入到D时发现无左右结点所以D出栈,看B是否有右结点,发现B也没,所以也出栈,找A,A有,从C开始上述的过程直到栈为空而且右子树指针为空。每入栈一个元素就输出,这样就完成了前序遍历。
中序 :中序的顺序是左根右,所用的方法跟前序差不多,只不过前序是入栈就输出,而中序是出栈才输出。
后序:后序的顺序是左右根,与前后不一样的是只有在结点无右孩子时才出栈和输出。
四、二叉树的层序遍历
二叉树的层序遍历顾名思义就是一层一层的遍历,本算法用队列来解决。
先将第一层的结点入队 ,每次将队头左右结点入队并进行出队操作,出队顺序就是层序遍历的结果。
五、完全二叉树的判断
满二叉树:在一棵二叉树中,如果所有的分支结点都存在左子树和右子树,并且所有的叶子节点都在同一层上。
完全二叉树:一棵具有N个结点的二叉树的结构与满二叉树的前N个结点的结构相同。
我们先把第一层结点入队,然后将它的左右孩子入队(如果为空入队“#”)并且进行出队操作,当他的队头为空时停止操作;接下来就是判断,如果队头为空但是队列不为空时此二叉树不是完全二叉树,如果队列为空就是完全二叉树,因为完全二叉树的话结点为空后面不可能有结点的。
六、源代码
1、bintree.h
#ifndef _BINTREE__H_
#define _BINTREE__H_
#include "stdio.h"
#include "malloc.h"
#include "assert.h"
#include "stdlib.h"
#include "Queue.h"
#include "Stack.h"
typedef char BTDataType;
typedef struct BTNode
{
struct BTNode* left;
struct BTNode* right;
BTDataType data;
}BTNode;
BTNode* BTCreate(BTDataType* a, int n, int *pi);
void BTDestory(BTNode* *root);
int BTSize(BTNode* root);
int BTLeafSize(BTNode* root);
int BTLevelkSize(BTNode* root,int x);
BTNode* BTFind(BTNode* root,BTDataType x);
void BTPrevOrder(BTNode* root);
void BTInOrder(BTNode* root);
void BTPostOrder(BTNode* root);
void BTLeveOrder(BTNode* root);
int BTComplete(BTNode* root);
void BTPrevOrderNonR(BTNode* root);
void BTInOrderNonR(BTNode* root);
void BTPostOrderNonR(BTNode* root);
#endif
2、bintree.c
#include "bintree.h"
//创建结点
BTNode* BuyBTNode(BTDataType x)
{
BTNode* node = (BTNode*)malloc(sizeof(BTNode));
node->left = node->right = NULL;
node->data = x;
return node;
}
//搭建二叉树
BTNode* BTCreate(BTDataType* a, int n, int *pi)
{
if (a[*pi] != '#')
{
BTNode* root = BuyBTNode(a[*pi]);
++(*pi);
root->left = BTCreate(a, n, pi);
++(*pi);
root->right = BTCreate(a, n, pi);
return root;
}
return NULL;
}
//清除二叉树
void BTDestory(BTNode* *root)
{
BTNode* tmp;
tmp = *root;
BTDestory(&tmp->left);
BTDestory(&tmp->right);
free(root);
tmp = NULL;
}
//结点数
int BTSize(BTNode* root)
{
if (root == NULL)
return 0;
return BTSize(root->left) + BTSize(root->right) + 1;
}
//左孩子结点数
int BTLeafSize(BTNode* root)
{
if (root == NULL)
return 0;
if (root->left == NULL&&root->right == NULL)
{
return 1;
}
return BTLeafSize(root->left) + BTLeafSize(root->right);
}
//第x层的结点数
int BTLevelkSize(BTNode* root, int x)
{
if (root == NULL)
return 0;
if (x == 1)
return 1;
return BTLevelkSize(root->left, x - 1) + BTLevelkSize(root->right, x - 1);
}
//查找指定元素
BTNode* BTFind(BTNode* root, BTDataType x)
{
BTNode* ret = NULL;
if (root == NULL)
return NULL;
if (root->data == x)
return root;
ret = BTFind(root->left, x);
if (ret)
return ret;
ret = BTFind(root->right, x);
if (ret)
return ret;
return NULL;
}
//前序遍历(递归)
void BTPrevOrder(BTNode* root)
{
if (root == NULL)
return;
printf("%c", root->data);
BTPrevOrder(root->left);
BTPrevOrder(root->right);
}
//中序遍历(递归)
void BTInOrder(BTNode* root)
{
if (root == NULL)
return;
BTInOrder(root->left);
printf("%c", root->data);
BTInOrder(root->right);
}
//后序遍历(递归)
void BTPostOrder(BTNode* root)
{
if (root == NULL)
return;
BTPostOrder(root->left);
BTPostOrder(root->right);
printf("%c", root->data);
}
//层序遍历
void BTLeveOrder(BTNode* root)
{
Queue q;
QueueInit(&q);
BTNode* front;
if (root)
QueuePush(&q, root);
while (QueueEmpty(&q))
{
front = QueueFront(&q);
printf("%c", front->data);
QueuePop(&q);
if (front->left!=NULL)
{
QueuePush(&q, front->left);
}
if (front->right!=NULL)
{
QueuePush(&q, front->right);
}
}
}
//判断是否是完全二叉树
int BTComplete(BTNode* root)
{
Queue q;
QueueInit(&q);
BTNode* front;
if (root)
QueuePush(&q, root);
while (QueueEmpty(&q))
{
front = QueueFront(&q);
QueuePop(&q);
if (front)
{
QueuePush(&q, front->left);
QueuePush(&q, front->right);
}
else
break;
}
while (QueueEmpty(&q))
{
front = QueueFront(&q);
if (front)
{
QueueDestory(&q);
return 0;
}
else
QueuePop(&q);
}
return 1;
}
//前序遍历(非递归)
void BTPrevOrderNonR(BTNode* root)
{
Stack s;
StackInit(&s, 20);
BTNode* top;
BTNode* cur = root;
while (cur || StackEmpty(&s)!=0)
{
while (cur)
{
printf("%c", cur->data);
StackPush(&s, cur);
cur = cur->left;
}
top = StackTop(&s);
StackPop(&s);
cur = top->right;
}
printf("\n");
}
//中序遍历(非递归)
void BTInOrderNonR(BTNode* root)
{
Stack s;
StackInit(&s, 20);
BTNode* top;
BTNode* cur = root;
while (cur || StackEmpty(&s) != 0)
{
while (cur)
{
StackPush(&s, cur);
cur = cur->left;
}
top = StackTop(&s);
printf("%c", top->data);
StackPop(&s);
cur = top->right;
}
printf("\n");
}
//后序遍历(非递归)
void BTPostOrderNonR(BTNode* root)
{
Stack s;
StackInit(&s, 20);
BTNode* top, *prav=NULL;
BTNode* cur = root;
while (cur || StackEmpty(&s) != 0)
{
while (cur)
{
StackPush(&s, cur);
cur = cur->left;
}
top = StackTop(&s);
if (top->right == NULL || top->right == prav)
{
printf("%c", top->data);
prav = top;
StackPop(&s);
}
else
{
cur = top->right;
}
}
printf("\n");
}