目录
1.用队列实现层序遍历(判断是否为完全二叉树)
1.实现层序遍历
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);
}
}
printf("\n");
QueueDestory(&q);//销毁队列
}
2.判断二叉树是否为完全二叉树
思想:用队列实现层序遍历,孩子为NULL也进队列,当出队列的元素是NULL时,把后面所有元素都出队列。若后面元素都为空,即是完全二叉树,若不是,则非完全二叉树。2
bool BTreeComplete(BTNode* root)
{
Queue q;
QueueInit(&q);
if (root)
QueuePush(&q, root);
while (!QueueEmpty(&q))
{
BTNode* front = QueueFront(&q);
QueuePop(&q);
if (front == NULL)//队列出元素,若是NULL,则break,后面把所有元素出队列
break;
QueuePush(&q, front->left);
QueuePush(&q, front->right);
}
while (!QueueEmpty(&q))
{
BTNode* front = QueueFront(&q);
QueuePop(&q);
if (front)// 空后面出到非空,那么说明不是完全二叉树
{
QueueDestory(&q);
return false;
}
}
QueueDestory(&q);
return true;
2.二叉树的前序遍历(非递归)
根->左子树->右子树
List* p1 = (List*)malloc(sizeof(List));
List* p2 = (List*)malloc(sizeof(List));
List* p3 = (List*)malloc(sizeof(List));
List* p4 = (List*)malloc(sizeof(List));
List* p5 = (List*)malloc(sizeof(List));
List* p6 = (List*)malloc(sizeof(List));
p1->a = 'A';
p2->a = 'B';
p3->a = 'C';
p4->a = 'D';
p5->a = 'E';
p6->a = 'F';
p1->left = p2;
p1->right = p3;
p2->left = p4;
p2->right = p5;
p3->left = p3->right = NULL;
p4->left = p4->right = NULL;
p5->left = NULL;
p5->right = p6;
p6->left = p6->right = NULL;
创建的二叉树如下图
思想:如图:
代码实现:
ST ps;//创建一个栈:ps
StackInit(&ps);
StackPush(&ps,p1);//先将头节点入栈
while (!StackEmpty(&ps))//栈不为空则继续
{
List* front = StackTop(&ps);
StackPop(&ps);//头节点出栈
printf("%c ", front->a);
if (front->right)//先将右孩子入栈
{
StackPush(&ps,front->right);
}
if (front->left)//再将左孩子入栈
{
StackPush(&ps, front->left);
}
}
3.二叉树的中序遍历(非递归)
左子树->根->右子树
思路:遇到节点,先把它入栈,后面依次遍历它的左子树,若该节点的左子树为空,将其出栈,然后遍历该节点的右子树(遍历右子树的方法:先把它入栈,后面依次遍历它的左子树,若该节点的左子树为空,将其出栈,然后遍历该节点的右子树)。
ST ps;
StackInit(&ps);
List* front = p1;
while (!StackEmpty(&ps)||front)
{
while (front)
{
StackPush(&ps, front);//节点不为空,就入栈
front = front->left;//找左孩子
}
if (!StackEmpty(&ps))
{
front = StackTop(&ps);若该节点左孩子为空,将其出栈,后找该节点右孩子
StackPop(&ps);
printf("%c ", front->a);
front = front->right;//后以同样的方法遍历右孩子
}
}
4.二叉树的后序遍历(非递归)
思路:在前序遍历的过程中,孩子入栈的顺序颠倒一下(先进左孩子,再进右孩子),再把出栈的元素放入另一个栈B。遍历完后,再将栈B元素出栈,即使后序遍历
ST ps;
ST pss;
StackInit(&ps);//创建两个栈ps,pss
StackInit(&pss);
StackPush(&ps, p1);
while (!StackEmpty(&ps))
{
List* front = StackTop(&ps);
StackPop(&ps);
StackPush(&pss, front);//将出栈元素放入新的栈中
if (front->left)
{
StackPush(&ps, front->left);//先将左孩子入栈
}
if (front->right)//再将右孩子入栈
{
StackPush(&ps, front->right);
}
}
while (!StackEmpty(&pss))
{
List* front = StackTop(&pss);
StackPop(&pss);
printf("%c ", front->a);
}