先序遍历二叉树(非递归)
//非递归前序遍历二叉树
void PreOrderByLoop(TreeNode* root)
{
if(root == NULL)
{
//空树
return;
}
ListStack* stack;
ListStackInit(&stack);
//将根结点入栈
ListStackPush(&stack,root);
TreeNode* cur = NULL;
while(ListStackGet(stack,&cur))
{
//将其出栈
ListStackPop(&stack);
//打印栈顶元素
printf("%c ",cur->data);
//将当前元素左右子树入栈,切记先入栈右子树
if(cur->rchild != NULL)
{
ListStackPush(&stack,cur->rchild);
}
if(cur->lchild != NULL)
{
ListStackPush(&stack,cur->lchild);
}
}
return;
}
运行结果:
中序遍历二叉树(非递归)
//非递归中序遍历二叉树
void InOrderByLoop(TreeNode* root)
{
if(root == NULL)
{
//空树
return;
}
TreeNode* cur = root;
ListStack* stack;
ListStackInit(&stack);
while(1)
{
//若cur为空,
//说明已经将树最左端的结点入栈
while(cur)
{
ListStackPush(&stack,cur);
cur = cur->lchild;
}
TreeNode* top = NULL;
int ret = ListStackGet(stack,&top);
if(ret == 0)
{
//栈为空,表明已将将树遍历完毕
return;
}
printf("%c ",top->data);
ListStackPop(&stack);
if(top->rchild != NULL)
{
cur = top->rchild;
}
}
return;
}
运行结果:
后序遍历二叉树(非递归)
//非递归后序遍历二叉树
void PostOrderByLoop(TreeNode* root)
{
if(root == NULL)
{
//空树
return;
}
TreeNode* cur = root;
ListStack* stack;
ListStackInit(&stack);
TreeNode* pre = NULL;
while(1)
{
while(cur)
{
ListStackPush(&stack,cur);
cur = cur->lchild;
}
TreeNode* top = NULL;
int ret = ListStackGet(stack,&top);
if(ret == 0)
{
//空栈,说明二叉树已经遍历完
return;
}
if(top->rchild == NULL || top->rchild == pre)
{
printf("%c ",top->data);
ListStackPop(&stack);
pre = top;
}
else
{
cur = top->rchild;
}
}
return;
}
运行结果:
二叉树的镜像(递归)
void Swap(TreeNode** a,TreeNode**b)
{
if(a == NULL || b == NULL)
{
return;
}
TreeNode* tmp = *a;
*a = *b;
*b = tmp;
}
//递归求二叉树镜像
void TreeMirror(TreeNode* root)
{
if(root == NULL)
{
//空树
return;
}
Swap(&root->lchild,&root->rchild);
TreeMirror(root->lchild);
TreeMirror(root->rchild);
}
运行结果:
二叉树的镜像(非递归)
非递归镜像二叉树思路:依据前面层序遍历的方法,借助队列,遍历二叉树,将其左右子树交换即可。
当队列为空即退出循环完成镜像。
void Swap(TreeNode** a,TreeNode**b)
{
if(a == NULL || b == NULL)
{
return;
}
TreeNode* tmp = *a;
*a = *b;
*b = tmp;
}
//非递归求二叉树镜像
void TreeMirrorByLoop(TreeNode* root)
{
if(root == NULL)
{
return;
}
SeqQueue queue;
SeqQueueInit(&queue);
SeqQueuePush(&queue,root);
TreeNode* top = NULL;
//当队列为空时,说明树已经转换完毕
while(SeqQueueGet(&queue,&top))
{
Swap(&top->lchild,&top->rchild);
SeqQueuePop(&queue);
if(top->lchild != NULL)
{
SeqQueuePush(&queue,top->lchild);
}
if(top->rchild != NULL)
{
SeqQueuePush(&queue,top->rchild);
}
}
return;
}
运行结果:
判断是否是完全二叉树
我们先来了解什么是完全二叉树:
如果二叉树的深度为k,则除第k层外其余所有层节点的度都为2,且叶子节点从左到右依次存在。也即是,将满二叉树的最后一层从左到右依次删除若干节点就得到完全二叉树。满二叉树是一棵特殊的完全二叉树,但完全二叉树不一定是满二叉树。
//判断是否是完全二叉树
int IsCompleteTree(TreeNode* root)
{
if(root == NULL)
{
//空树
return;
}
SeqQueue queue;
SeqQueueInit(&queue);
SeqQueuePush(&queue,root);
TreeNode* top = NULL;
int flag = 0;
while(SeqQueueGet(&queue,&top))
{
SeqQueuePop(&queue);
if(flag == 0)
{
if(top->lchild != NULL && top->rchild != NULL)
{
SeqQueuePush(&queue,top->lchild);
SeqQueuePush(&queue,top->rchild);
continue;
}
else if(top->lchild == NULL && top->rchild != NULL)
{
//此情况一定不是完全二叉树
return 0;
}
else if(top->lchild != NULL && top->rchild == NULL)
{
SeqQueuePush(&queue,top->lchild);
flag = 1;
continue;
}
else
{
//左右子树都为空
flag = 1;
continue;
}
}
else if (flag == 1)
{
//flag == 1;
if(top->lchild == NULL && top->rchild == NULL)
{
;
}
else
{
return 0;
}
}
return 1;
}
}
测试用例:
void TestIsCompleteTree()
{
TITLE;
TreeNode* A = CreateTreeNode('A');
TreeNode* B = CreateTreeNode('B');
TreeNode* C = CreateTreeNode('C');
TreeNode* D = CreateTreeNode('D');
TreeNode* a = CreateTreeNode('a');
TreeNode* b = CreateTreeNode('b');
TreeNode* c = CreateTreeNode('c');
TreeNode* d = CreateTreeNode('d');
//构建满二叉树
A->lchild = B;
A->rchild = C;
B->lchild = D;
int ret = IsCompleteTree(A);
printf("[先序遍历]:\n");
TreePreOrder(A);
printf("\n");
printf("[中序遍历]:\n");
TreeInOrder(A);
printf("\n");
printf("expect is 1,actul is %d \n\n",ret);
//构建非满二叉树
a->lchild = b;
a->rchild = c;
c->lchild = d;
printf("[先序遍历]:\n");
TreePreOrder(a);
printf("\n");
printf("[中序遍历]:\n");
TreeInOrder(a);
printf("\n");
ret = IsCompleteTree(a);
printf("expect is 0,actul is %d \n",ret);
}