二叉树的非递归遍历


二叉树的非递归遍历需要借助栈,层次遍历则需要用到队列

结构体


typedef struct Tnode
{
    int data ;
    struct Tnode *lchild;
    struct Tnode *rchild;
}Tnode , *TreeList;

typedef struct StackNode
{
    /* data */
    Tnode *node;
    struct StackNode *next;//指向下一个数据
}StackNode,*LinkStack;

typedef struct Queue
{
    Tnode *node;
    struct Queue *next;
}Queue,* LinkQueue;

二叉树的创建

使用前序的方式进行递归创建

TreeList createTree()
{
    int val;
	TreeList root ;
	printf("please input :");
	scanf("%d",&val);
	root = (TreeList)malloc(sizeof(Tnode));
	if(!root)
	{
		printf("create fail \n");
	}
	if(val<0)
	{
		return NULL;

	}
	if(val > 0 )
	{
		root->data = val;
		root->lchild = createTree();
		root->rchild = createTree();
	}
	return root;
}

队列的基本操作

void EnQueue(Queue *queue , Tnode *node)
{
    Queue *tmp = (Queue *)malloc(sizeof(Queue));
    while(queue->next != NULL)
    {
        queue = queue->next;
    }
    tmp->node = node ;
    queue->next = tmp;
	tmp->next = NULL;
}
TreeList DeQueue(Queue *queue)
{
    TreeList node = (TreeList)malloc(sizeof(Tnode)) ;
    if(queue->next != NULL)
    {
        node = queue->next->node;
        queue->next = queue->next->next;
    }
    return node;
}

栈的基本操作

void Push(StackNode *s ,Tnode *node)
{
    StackNode *p = (StackNode *) malloc(sizeof(StackNode));
    p->node = node ;
    p->next = s->next; 
    s->next = p;
	
}

TreeList Pop(StackNode *s)
{
    TreeList node =  (TreeList)malloc(sizeof(Tnode)) ;
    if(s)
    {
		//printf("pop data is %d \n ",s->next->data);
		node = s->next->node;
		s->next = s->next->next;//移除
    }
    return node;
}

非递归前序遍历

实现过程:当前节点不为空时,输出此时节点的值,再将根节点入栈,指向当前节点左孩子;如果节点为空节点,则当前栈出队,指向当前节点的右孩子

void preOrder(TreeList root)
{
    StackNode *stack = InitStack();
    TreeList node = (TreeList)malloc(sizeof(Tnode));
    node = root ;
    while(node || StackEmpty(stack))
    {
        if(node)
        {
            printf("%d",node->data);
            Push(stack,node);
            node = node->lchild;
        }
        else
        {
            node = Pop(stack);
            node = node->rchild;
        }
    }
}

非递归中序遍历

实现过程:节点不为空则入栈,指向当前节点的左孩子;如果节点为空,则出栈,打印当前节点的值,指向当前节点的右孩子

void inOrder(TreeList root )
{
    StackNode *stack = InitStack();
    TreeList node = (TreeList)malloc(sizeof(Tnode));
    node = root;
    while(node||StackEmpty(stack))
    {
        if(node)
        {
            Push(stack,node);
           node = node->lchild;
        }
        else
        {
           node = Pop(stack);
           printf("%d",node->data);
           node = node->rchild;
        }
    }
}

非递归后序遍历

实现过程:需要借助两个栈来实现后序遍历,根节点不为空,入栈1,栈2,当前节点指向右节点;如果节点为空,出栈1,指向左节点;最后打印栈2;
解释:借助两个栈来实现树,在栈1是中右左,在栈2打印的时候是左右中,就实现了后序遍历

void postOrder(TreeList root )
{
    StackNode *stack = InitStack();
    StackNode *liststack = InitStack();
    TreeList node = (TreeList)malloc(sizeof(Tnode));
    node = root;
    while(node||StackEmpty(stack))
    {
        if(node)
        {
            Push(stack,node);
            Push(liststack,node);
            node = node->rchild;

        }
        else
        {
            node = Pop(stack);
            node = node->lchild;
        }
    }
    PrintfStack(liststack);
}

层次遍历

实现过程:使用队列先进先出的方式,将树根节点入队,如果队列不为空,则打印当前节点,出队;出队的左孩子不为空,则左孩子入队,右孩子不为空,右孩子入队

while(QueueEmpty(que))
    {
	   printf("%d",que->next->node->data);
       node =  DeQueue(que);
       if(node->lchild != NULL)
       {
           EnQueue(que,node->lchild);
       }
       if(node->rchild != NULL)
       {
           EnQueue(que,node->rchild);
       }
     

整个程序

#include<stdio.h>
#include<stdlib.h>

typedef struct Tnode
{
    int data ;
    struct Tnode *lchild;
    struct Tnode *rchild;
}Tnode , *TreeList;

typedef struct StackNode
{
    /* data */
    Tnode *node;
    struct StackNode *next;//指向下一个数据
}StackNode,*LinkStack;

typedef struct Queue
{
    Tnode *node;
    struct Queue *next;
}Queue,* LinkQueue;

TreeList createTree()
{
    int val;
	TreeList root ;
	printf("please input :");
	scanf("%d",&val);
	root = (TreeList)malloc(sizeof(Tnode));
	if(!root)
	{
		printf("create fail \n");
	}
	if(val<0)
	{
		return NULL;

	}
	if(val > 0 )
	{
		root->data = val;
		root->lchild = createTree();
		root->rchild = createTree();
	}
	return root;
}
Queue *InitQueue()
{
    Queue *queue = (Queue *)malloc(sizeof(Queue));
    if(queue == NULL)
    {
        printf("create fail \n");
        return 0;
    }
    queue->next = NULL;
    return queue;
}
void EnQueue(Queue *queue , Tnode *node)
{
    Queue *tmp = (Queue *)malloc(sizeof(Queue));
    while(queue->next != NULL)
    {
        queue = queue->next;
    }
    tmp->node = node ;
    queue->next = tmp;
	tmp->next = NULL;
}
TreeList DeQueue(Queue *queue)
{
    TreeList node = (TreeList)malloc(sizeof(Tnode)) ;
    if(queue->next != NULL)
    {
        node = queue->next->node;
        queue->next = queue->next->next;
    }
    return node;
}
void printfall(Queue *queue)
{
    while(queue->next != NULL)
	{
		printf("all %d\n",queue->next->node->data);
		queue = queue->next ;
	}
}
int QueueEmpty(Queue *que )
{
    if(que != NULL)
    {
        return 1;
    }
    return 0;
}
StackNode *InitStack()
{
    StackNode *s = (StackNode *) malloc(sizeof(StackNode));
	if(s == NULL)
    {
        printf("create fail \n");
        return 0;
    }
    s->next =  NULL;
    return s;
}
void Push(StackNode *s ,Tnode *node)
{
    StackNode *p = (StackNode *) malloc(sizeof(StackNode));
    p->node = node ;
    p->next = s->next; 
    s->next = p;
	
}

TreeList Pop(StackNode *s)
{
    TreeList node =  (TreeList)malloc(sizeof(Tnode)) ;
    if(s)
    {
		//printf("pop data is %d \n ",s->next->data);
		node = s->next->node;
		s->next = s->next->next;//移除
    }
    return node;
}
int StackEmpty(StackNode *stack)
{
    if(stack->next != NULL )
    {
        return 1;
    }
    return 0;
}
void PrintfStack(StackNode *s)
{
    while(s->next != NULL)
    {
        printf("%d",s->next->node->data);
        s->next = s->next->next;
    }
}
void preOrder(TreeList root)
{
    StackNode *stack = InitStack();
    TreeList node = (TreeList)malloc(sizeof(Tnode));
    node = root ;
    while(node || StackEmpty(stack))
    {
        if(node)
        {
            printf("%d",node->data);
            Push(stack,node);
            node = node->lchild;
        }
        else
        {
            node = Pop(stack);
            node = node->rchild;
        }
    }
}
void inOrder(TreeList root )
{
    StackNode *stack = InitStack();
    TreeList node = (TreeList)malloc(sizeof(Tnode));
    node = root;
    while(node||StackEmpty(stack))
    {
        if(node)
        {
            Push(stack,node);
           node = node->lchild;
        }
        else
        {
           node = Pop(stack);
           printf("%d",node->data);
           node = node->rchild;
        }
    }
}
void postOrder(TreeList root )
{
    StackNode *stack = InitStack();
    StackNode *liststack = InitStack();
    TreeList node = (TreeList)malloc(sizeof(Tnode));
    node = root;
    while(node||StackEmpty(stack))
    {
        if(node)
        {
            Push(stack,node);
            Push(liststack,node);
            node = node->rchild;

        }
        else
        {
            node = Pop(stack);
            node = node->lchild;
        }
    }
    PrintfStack(liststack);
}
int main()
{
    TreeList tree = (TreeList)malloc(sizeof(Tnode));
	
	TreeList node = (TreeList)malloc(sizeof(Tnode));
	
    Queue *que = InitQueue();
	tree = createTree();
    EnQueue(que,tree);
    printf("preOrderTree is : ");
    preOrder(tree);
    printf("\nInorderTree is :");
    inOrder(tree);
    printf("\npostOrderTree is :");
    postOrder(tree);
    printf("\nlevel traversal is:");
    while(QueueEmpty(que))
    {
	   printf("%d",que->next->node->data);
       node =  DeQueue(que);
       if(node->lchild != NULL)
       {
           EnQueue(que,node->lchild);
       }
       if(node->rchild != NULL)
       {
           EnQueue(que,node->rchild);
       }
        
    }
}

运行结果

在这里插入图片描述
树:
在这里插入图片描述
其中-1就是为NULL,输入顺序为:1,2,4,-1,-1,5,-1,-1,3,6,-1,-1,7,-1,-1

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

曾许人间第一流.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值