1. 二叉树的基本结构
typedef char BTDataType;
typedef struct BinaryTreeNode
{
BTDataType _data;
struct BinaryTreeNode * _left;
struct BinaryTreeNode * _right;
} BTNode;
2. 二叉树的基本函数
2.2 二叉树的构建
对字符串一个一个向后挪动,构建二叉树
运用到了递归(分治)
BTNode* BinaryTreeCreate ( BTDataType* a, int n, int * pi)
{
if ( a[ * pi] == '#' || * pi>= n)
{
( * pi) ++ ;
return NULL ;
}
BTNode* obj = ( BTNode* ) malloc ( sizeof ( BTNode) ) ;
if ( obj == NULL )
{
perror ( "malloc fail" ) ;
exit ( - 1 ) ;
}
obj-> _data = a[ * pi] ;
( * pi) ++ ;
obj-> _left = BinaryTreeCreate ( a, n, pi) ;
obj-> _right = BinaryTreeCreate ( a, n, pi) ;
return obj;
}
2.2 二叉树的销毁
void BinaryTreeDestory ( BTNode* root)
{
if ( root == NULL )
return ;
BTNode* L = root-> _left;
BTNode* R = root-> _right;
free ( root) ;
root = NULL ;
BinaryTreeDestory ( L) ;
BinaryTreeDestory ( R) ;
}
2.3 二叉树的节点个数
算该树左子树节点个数+右子树节点个数+ 1(根)
int BinaryTreeSize ( BTNode* root)
{
if ( root == NULL )
return 0 ;
return 1 + BinaryTreeSize ( root-> _left) + BinaryTreeSize ( root-> _right) ;
}
2.4 二叉树的叶子节点个数
int BinaryTreeLeafSize ( BTNode* root)
{
if ( root == NULL )
return 0 ;
if ( root-> _left == NULL && root-> _right == NULL )
return 1 ;
return BinaryTreeLeafSize ( root-> _left) + BinaryTreeLeafSize ( root-> _right) ;
}
2.5 二叉树第k层节点个数
思路是算左子树右子树第k-1层节点个数,不断递推到第1层(节点个数肯定为1)
int BinaryTreeLevelKSize ( BTNode* root, int k)
{
if ( root == NULL )
return 0 ;
if ( k == 1 )
return 1 ;
return BinaryTreeLevelKSize ( root-> _left, k - 1 ) + BinaryTreeLevelKSize ( root-> _right, k - 1 ) ;
}
2.6 二叉树查找值为x的节点
分别去左右子树找,两边都没找到返回null,只要有一边不为null则是找到了
BTNode* BinaryTreeFind ( BTNode* root, BTDataType x)
{
if ( root == NULL )
return NULL ;
if ( root-> _data == x)
return root;
BTNode* left= BinaryTreeFind ( root-> _left, x) ;
BTNode* right= BinaryTreeFind ( root-> _right, x) ;
if ( left == NULL && right == NULL )
return NULL ;
else
return right == NULL ? left : right;
}
2.7 二叉树的遍历
分为前序(根左右),中序(左根右),后序(左右根)
void BinaryTreePrevOrder ( BTNode* root)
{
if ( root == NULL )
{
printf ( "NULL " ) ;
return ;
}
printf ( "%c " , root-> _data) ;
BinaryTreePrevOrder ( root-> _left) ;
BinaryTreePrevOrder ( root-> _right) ;
}
void BinaryTreeInOrder ( BTNode* root)
{
if ( root == NULL )
{
printf ( "NULL " ) ;
return ;
}
BinaryTreeInOrder ( root-> _left) ;
printf ( "%c " , root-> _data) ;
BinaryTreeInOrder ( root-> _right) ;
}
void BinaryTreePostOrder ( BTNode* root)
{
if ( root == NULL )
{
printf ( "NULL " ) ;
return ;
}
BinaryTreePostOrder ( root-> _left) ;
BinaryTreePostOrder ( root-> _right) ;
printf ( "%c " , root-> _data) ;
}
3. 二叉树的扩展函数
3.1 二叉树的层序遍历
需要构建一个队列进行辅助
进入一个节点,并把它的左孩子右孩子依次进入队列,之后将队头节点pop
对头节点一直反复以上操作,直到队列为空
void BinaryTreeLevelOrder ( BTNode* root)
{
if ( root == NULL )
{
printf ( "NULL\n" ) ;
return ;
}
Queue Q;
QueueInit ( & Q) ;
QueuePush ( & Q, root) ;
while ( ! QueueEmpty ( & Q) )
{
printf ( "%c " , Q. front-> x-> _data) ;
if ( Q. front-> x-> _left!= NULL )
QueuePush ( & Q, Q. front-> x-> _left) ;
if ( Q. front-> x-> _right != NULL )
QueuePush ( & Q, Q. front-> x-> _right) ;
QueuePop ( & Q) ;
}
QueueDestroy ( & Q) ;
}
3.2 判断是否为完全二叉树
依旧需要一个队列进行辅助
push一个节点,并把它的左孩子和右孩子入队列(不管是否为空),pop出该队头节点
以上操作反复,直到遇到第一个NULL停止,之后判断后面的队列是否全为NULL
不全为NULL则不是完全二叉树
bool BinaryTreeComplete ( BTNode* root)
{
if ( root == NULL )
return true;
Queue Q;
QueueInit ( & Q) ;
QueuePush ( & Q, root) ;
while ( ! QueueEmpty ( & Q) )
{
if ( Q. front-> x != NULL )
{
QueuePush ( & Q, Q. front-> x-> _left) ;
QueuePush ( & Q, Q. front-> x-> _right) ;
QueuePop ( & Q) ;
}
else
break ;
}
while ( ! QueueEmpty ( & Q) )
{
if ( Q. front-> x != NULL )
{
QueueDestroy ( & Q) ;
return false;
}
QueuePop ( & Q) ;
}
QueueDestroy ( & Q) ;
return true;
}
3.3 是否为对称二叉树
bool judge ( struct TreeNode * left, struct TreeNode * right)
{
if ( left== NULL && right== NULL )
return true;
if ( left== NULL || right== NULL )
return false;
if ( left-> val!= right-> val)
return false;
return judge ( left-> left, right-> right) && judge ( left-> right, right-> left) ;
}
bool isSymmetric ( struct TreeNode * root) {
if ( root== NULL )
return true;
return judge ( root-> left, root-> right) ;
}
3.4 判断是否为子树
借助一个判断是否为相同树的函数,然后对根 左孩子 右孩子依次判断
bool isSameTree ( struct TreeNode * p, struct TreeNode * q) {
if ( p== NULL && q== NULL )
return true;
if ( p== NULL || q== NULL )
return false;
if ( p-> val!= q-> val)
return false;
return isSameTree ( p-> left, q-> left) && isSameTree ( p-> right, q-> right) ;
}
bool isSubtree ( struct TreeNode * root, struct TreeNode * subRoot) {
if ( subRoot== NULL )
return true;
if ( root== NULL && subRoot!= NULL )
return false;
if ( isSameTree ( root, subRoot) )
return true;
return isSubtree ( root-> left, subRoot) || isSubtree ( root-> right, subRoot) ;
}