二叉树的非递归遍历算法
Posted hky8220
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二叉树的非递归遍历算法相关的知识,希望对你有一定的参考价值。
#include <stdio.h> #include <stdlib.h> typedef char ElemType; typedef struct BiNode{//二叉树 ElemType data; struct BiNode *lchild,*rchlid; }BiNode,*BiTree; typedef struct NodeStack{//链栈 BiTree data; struct NodeStack *next; }NodeStack; typedef struct Node{//队列结点 BiTree data; struct Node *next; }Node; typedef struct Queue{//链式队列 struct Node *front,*rear; }Queue; BiTree Create_BiTree(BiTree T);//前序遍历建立二叉树 void PreOrder(BiTree T); //前序遍历 void InOrder(BiTree T);//中序遍历 void PostOrder(BiTree T); //后序遍历 void visit(BiTree T);//访问节点 void InOrder2(BiTree T);//中序遍历非递归算法 void PreOrder2(BiTree T);//先序遍历非递归算法 void PostOrder2(BiTree T);//后序遍历非递归算法 void LevelOrder(BiTree T);//层次遍历 void InQueue(Queue *q,BiTree t);//入队 BiTree OutQueue(Queue *q);//出队 void Push(NodeStack *head,BiTree t);//入栈 BiTree Pop(NodeStack *head);//出栈 BiTree GetTop(NodeStack *head);//得到栈顶元素 int main() { BiTree T; T=Create_BiTree(T); printf("先序遍历非递归: "); PreOrder2(T); printf("中序遍历非递归: "); InOrder2(T); printf("后序遍历非递归: "); PostOrder(T); printf("层次遍历: "); LevelOrder(T); return 0; } BiTree Create_BiTree(BiTree T) { char ch; scanf("%c",&ch); if(ch==‘#‘) { T=NULL; } else { T=(BiTree)malloc(sizeof(BiNode)); T->data=ch; T->lchild=Create_BiTree(T->lchild); T->rchlid=Create_BiTree(T->rchlid); } return T; } void PreOrder(BiTree T) { if(T!=NULL) { visit(T); PreOrder(T->lchild); PreOrder(T->rchlid); } } void InOrder(BiTree T) { if(T!=NULL) { InOrder(T->lchild); visit(T); InOrder(T->rchlid); } } void PostOrder(BiTree T) { if(T!=NULL) { PostOrder(T->lchild); PostOrder(T->rchlid); visit(T); } } void visit(BiTree T) { printf("%c ",T->data); } void InOrder2(BiTree T) { //InitStack(S) NodeStack *s; s=(NodeStack*)malloc(sizeof(NodeStack)); s->next=NULL; BiTree p=T; while(p||s->next!=NULL) { if(p) { Push(s,p); p=p->lchild; } else { p=Pop(s); visit(p); p=p->rchlid; } } } void PreOrder2(BiTree T) { //InitStack(S) NodeStack *s; s=(NodeStack*)malloc(sizeof(NodeStack)); s->next=NULL; BiTree p=T; while(p||s->next!=NULL) { if(p) { visit(p); Push(s,p); p=p->lchild; } else { p=Pop(s); p=p->rchlid; } } } void PostOrder2(BiTree T) { NodeStack *s; s=(NodeStack*)malloc(sizeof(NodeStack)); s->next=NULL; BiTree p=T,r=NULL; while(p||s->next!=NULL) { if(p) { Push(s,p); p=p->lchild; } else { p=GetTop(s); if(p->rchlid&&p->rchlid!=r) { p=p->rchlid; Push(s,p); p=p->lchild; } else { p=Pop(s); visit(p); r=p; p=NULL; } } } } void LevelOrder(BiTree T) { Queue Q; Q.front=Q.rear=(Node*)malloc(sizeof(Node)); Q.front->next=NULL; BiTree p; InQueue(&Q,T); while(Q.front!=Q.rear) { p=OutQueue(&Q); visit(p); if(p->lchild!=NULL) { InQueue(&Q,p->lchild); } if(p->rchlid!=NULL) { InQueue(&Q,p->rchlid); } } } void Push(NodeStack *head,BiTree t) { NodeStack *p=(NodeStack*)malloc(sizeof(NodeStack)); p->data=t; p->next=head->next; head->next=p; } BiTree Pop(NodeStack *head) { NodeStack *p=(NodeStack*)malloc(sizeof(NodeStack)); p=head->next; head->next=p->next; return p->data; } void InQueue(Queue *q,BiTree t) { Node *p=(Node*)malloc(sizeof(Node)); p->data=t; p->next=NULL; q->rear->next=p; q->rear=p; } BiTree OutQueue(Queue *q) { Node *p=q->front->next; q->front->next=p->next; if(q->rear==p) { q->rear=q->front; } return p->data; } BiTree GetTop(NodeStack *head) { return head->next->data; }
一. 中序遍历非递归算法
代码实现:
void InOrder2(BiTree T) { //InitStack(S) NodeStack *s; s=(NodeStack*)malloc(sizeof(NodeStack)); s->next=NULL; BiTree p=T; while(p||s->next!=NULL) { if(p) { Push(s,p); p=p->lchild; } else { p=Pop(s); visit(p); p=p->rchlid; } } }
二. 先序遍历非递归算法
与中序非递归算法相似,只需将访问visit(p)放在入栈Push(p)之前即可。
代码实现:
void PreOrder2(BiTree T) { //InitStack(S) NodeStack *s; s=(NodeStack*)malloc(sizeof(NodeStack)); s->next=NULL; BiTree p=T; while(p||s->next!=NULL) { if(p) { visit(p); Push(s,p); p=p->lchild; } else { p=Pop(s); p=p->rchlid; } } }
三. 后序遍历非递归算法
算法思想:
a.沿着根的左孩子,依次入栈,直到左孩子为空
b.读栈顶元素:若其右孩子不空且未被访问过,将右子树转执行a,否则,栈顶元素出栈并访问。
代码实现:
void PostOrder2(BiTree T) { NodeStack *s; s=(NodeStack*)malloc(sizeof(NodeStack)); s->next=NULL; BiTree p=T,r=NULL; while(p||s->next!=NULL) { if(p) { Push(s,p); p=p->lchild; } else { p=GetTop(s); if(p->rchlid&&p->rchlid!=r) { p=p->rchlid; Push(s,p); p=p->lchild; } else { p=Pop(s); visit(p); r=p; p=NULL; } } } }
四. 层次遍历
代码实现:
void LevelOrder(BiTree T) { Queue Q; Q.front=Q.rear=(Node*)malloc(sizeof(Node)); Q.front->next=NULL; BiTree p; InQueue(&Q,T); while(Q.front!=Q.rear) { p=OutQueue(&Q); visit(p); if(p->lchild!=NULL) { InQueue(&Q,p->lchild); } if(p->rchlid!=NULL) { InQueue(&Q,p->rchlid); } } }
运行示例:(按前序遍历建立如下二叉树)
以上是关于二叉树的非递归遍历算法的主要内容,如果未能解决你的问题,请参考以下文章