数据结构 二叉树的遍历(非递归),镜像,完全二叉树判定

先序遍历二叉树(非递归)

数据结构 二叉树的遍历(非递归),镜像,完全二叉树判定_第1张图片

//非递归前序遍历二叉树
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;
}

运行结果:

数据结构 二叉树的遍历(非递归),镜像,完全二叉树判定_第2张图片


中序遍历二叉树(非递归)

数据结构 二叉树的遍历(非递归),镜像,完全二叉树判定_第3张图片

//非递归中序遍历二叉树
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;
}

运行结果:

数据结构 二叉树的遍历(非递归),镜像,完全二叉树判定_第4张图片


后序遍历二叉树(非递归)

数据结构 二叉树的遍历(非递归),镜像,完全二叉树判定_第5张图片

//非递归后序遍历二叉树
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;
}

运行结果:

数据结构 二叉树的遍历(非递归),镜像,完全二叉树判定_第6张图片

二叉树的镜像(递归)

数据结构 二叉树的遍历(非递归),镜像,完全二叉树判定_第7张图片

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);
}

运行结果:

数据结构 二叉树的遍历(非递归),镜像,完全二叉树判定_第8张图片

二叉树的镜像(非递归)

非递归镜像二叉树思路:
依据前面层序遍历的方法,借助队列,遍历二叉树,将其左右子树交换即可。

当队列为空即退出循环完成镜像。

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;
}

运行结果:

数据结构 二叉树的遍历(非递归),镜像,完全二叉树判定_第9张图片

判断是否是完全二叉树

我们先来了解什么是完全二叉树:

    如果二叉树的深度为k,则除第k层外其余所有层节点的度都为2,且叶子节点从左到右依次存在。也即是,将满二叉树的最后一层从左到右依次删除若干节点就得到完全二叉树。满二叉树是一棵特殊的完全二叉树,但完全二叉树不一定是满二叉树。

数据结构 二叉树的遍历(非递归),镜像,完全二叉树判定_第10张图片

//判断是否是完全二叉树
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);
}

运行结果:

数据结构 二叉树的遍历(非递归),镜像,完全二叉树判定_第11张图片

你可能感兴趣的:(数据结构)