单值二叉树
判断根结点与左右子结点值是否相等 使用分治判断左右子树是否为单值二叉树 检查到叶子节点后返回真
bool isUnivalTree ( struct TreeNode * root) {
if ( root == NULL )
return true;
if ( root-> left && root-> left-> val != root-> val)
{
return false;
}
if ( root-> right && root-> right-> val != root-> val)
{
return false;
}
return isUnivalTree ( root-> left) && isUnivalTree ( root-> right) ;
}
检查两颗树是否相同
先判断结构是否相同,即该结点是否都不为空 再判断两当前结点值是否相等
bool isSameTree ( struct TreeNode * p, struct TreeNode * q) {
if ( p == q && q == NULL )
{
return true;
}
if ( p == NULL || q == NULL )
{
return false;
}
if ( q-> val != p-> val)
{
return false;
}
return isSameTree ( p-> left, q-> left) && isSameTree ( p-> right, q-> right) ;
}
对称二叉树
直接使用判断相同树的实现 改为对左子树的左子树与右子树的右子树相比较
bool isSameTree2 ( struct TreeNode * p, struct TreeNode * q) {
if ( p == q && q == NULL )
{
return true;
}
if ( p == NULL || q == NULL )
{
return false;
}
if ( q-> val != p-> val)
{
return false;
}
return isSameTree2 ( p-> left, q-> right) && isSameTree2 ( p-> right, q-> left) ;
}
bool isSymmetric ( struct TreeNode * root) {
return isSameTree2 ( root-> left, root-> right) ;
}
翻转二叉树
交换父节点的左右子结点, 再对子结点执行相同操作,以此递归
struct TreeNode * invertTree ( struct TreeNode * root) {
if ( root == NULL )
{
return NULL ;
}
struct TreeNode * tmp = root-> left;
root-> left = root-> right;
root-> right = tmp;
root-> left = invertTree ( root-> left) ;
root-> right = invertTree ( root-> right) ;
return root;
}
二叉树的前序遍历
先访问根结点再遍历左右子树 这里返回数组的下标 i 注意通过传地址实现值得累加 也可直接将 returnSize 作为下标,不用另外定义下标 i,用法相同
int TreeSize ( struct TreeNode * root)
{
return root == 0 ? 0 : TreeSize ( root-> left) + TreeSize ( root-> right) + 1 ;
}
void PreOrder ( struct TreeNode * root, int * ret, int * pi)
{
if ( root == NULL )
return ;
ret[ * pi] = root-> val;
( * pi) ++ ;
PreOrder ( root-> left, ret, pi) ;
PreOrder ( root-> right, ret, pi) ;
return ;
}
int * preorderTraversal ( struct TreeNode * root, int * returnSize) {
int size = TreeSize ( root) ;
int * ret = ( int * ) malloc ( size * sizeof ( int ) ) ;
int i = 0 ;
PreOrder ( root, ret, & i) ;
* returnSize = size;
return ret;
}
另一颗树的子树
判断每个结点为根结点的子树是否与 subRoot 相同 不相等则继续往下判断以其左右子结点为根结点的子树是否与 subRoot 相同
bool isSameTree ( struct TreeNode * p, struct TreeNode * q) {
if ( p == q && q == NULL )
{
return true;
}
if ( p == NULL || q == NULL )
{
return false;
}
if ( q-> val != p-> val)
{
return false;
}
return isSameTree ( p-> left, q-> left) && isSameTree ( p-> right, q-> right) ;
}
int TreeSize ( struct TreeNode * root)
{
return root == 0 ? 0 : TreeSize ( root-> left) + TreeSize ( root-> right) + 1 ;
}
bool isSubtree ( struct TreeNode * root, struct TreeNode * subRoot) {
if ( TreeSize ( root) < TreeSize ( subRoot) )
{
return false;
}
if ( isSameTree ( root, subRoot) )
{
return true;
}
return isSubtree ( root-> left, subRoot) || isSubtree ( root-> right, subRoot) ;
}
二叉树第k层的结点个数
二叉树第k层即子树的k-1层,以此分治 子树为空返回0 递归到k层,若有结点则计数该结点,返回1
int TreeKLevel ( BTNode* root, int k)
{
if ( root == NULL )
{
return 0 ;
}
if ( k == 1 )
{
return 1 ;
}
return TreeKLevel ( root-> left, k - 1 ) + TreeKLevel ( root-> right, k - 1 ) ;
}
查找二叉树中值为x的结点
又需要判断返回值,同时也需要返回这个值时,最好提前记录返回值,避免多次调用
BTNode* BinaryTreeFind ( BTNode* root, char x)
{
if ( root == NULL )
{
return NULL ;
}
if ( root-> data == x)
{
return root;
}
BTNode* leftret = BinaryTreeFind ( root-> left, x) ;
if ( leftret)
{
return leftret;
}
BTNode* rightret = BinaryTreeFind ( root-> right, x) ;
if ( rightret)
{
return rightret;
}
return NULL ;
}
层序遍历
依托队列实现 首先将根结点入队列 出队列,同时记录队头值,并将其左右子结点入队列
void LevelOrder ( BTNode* root)
{
Queue q;
QueueInit ( & q) ;
if ( root)
QueuePush ( & q, root) ;
while ( ! QueueEmpty ( & q) )
{
BTNode* front = QueueFront ( & q) ;
QueuePop ( & q) ;
printf ( "%d " , front-> data) ;
if ( front-> left)
QueuePush ( & q, front-> left) ;
if ( front-> right)
QueuePush ( & q, front-> right) ;
}
QueueDestroy ( & q) ;
}
判断是否为完全二叉树
先进行层序遍历,遇到空结点就停止 如果队列中存在有效元素,则不为完全二叉树
bool TreeComplete ( BTNode* root)
{
Queue q;
QueueInit ( & q) ;
if ( root)
QueuePush ( & q, root) ;
while ( ! QueueEmpty ( & q) )
{
BTNode* front = QueueFront ( & q) ;
QueuePop ( & q) ;
if ( front == NULL )
break ;
QueuePush ( & q, front-> left) ;
QueuePush ( & q, front-> right) ;
}
while ( ! QueueEmpty ( & q) )
{
BTNode* front = QueueFront ( & q) ;
QueuePop ( & q) ;
if ( front)
{
QueueDestroy ( & q) ;
return false;
}
}
QueueDestroy ( & q) ;
return true;
}
二叉树的构建及遍历
参考字符串为前序,自然也通过前序构建 遇到 ‘#’ 则只向后移动字符串指针,返回空
BTNode* FormTree ( char * pc, int * pi)
{
if ( pc[ * pi] == '#' )
{
( * pi) ++ ;
return NULL ;
}
BTNode* node = ( BTNode* ) malloc ( sizeof ( BTNode) ) ;
node-> data = pc[ * pi] ;
( * pi) ++ ;
node-> left = FormTree ( pc, pi) ;
node-> right = FormTree ( pc, pi) ;
return node;
}
void InOrder1 ( BTNode* root)
{
if ( root == NULL )
{
return ;
}
InOrder1 ( root-> left) ;
printf ( "%c " , root-> data) ;
InOrder1 ( root-> right) ;
}
int main ( ) {
char ch[ 100 ] = { 0 } ;
while ( scanf ( "%s" , ch) != EOF )
{
int i = 0 ;
BTNode* tree = FormTree ( ch, & i) ;
InOrder1 ( tree) ;
printf ( "\n" ) ;
}
return 0 ;
}