二叉树的三种遍历递归与非递归算法

BiTree.h

#ifndef MaxSize
  #define   MaxSize     50
#endif

typedef struct BiTNode {
// 定义二叉树存储结构
  ElemType data;                    // 数据域
  struct BiTNode *lchild, *rchild;  // 左、右孩子指针
}BiTNode, *BiTree;

/************************辅助队列**************************/
typedef struct {
// 队列结构
  BiTree data[MaxSize];             // 数据域
  int rear, front;                  // 队头、队尾指针
}SqQueue;

int EnQueue(SqQueue* Q, BiTree node) {
// 入队函数
    if (((Q->rear + 1) % MaxSize) == Q->front) return 0;    // 队满,报错
    Q->data[Q->rear] = node;                                // 入队
    Q->rear = (Q->rear + 1) % MaxSize;                      // 队尾指针加1
    return 1;
}

int DeQueue(SqQueue* Q, BiTree* t) {
// 出队函数
    if (Q->front == Q->rear) return 0;                      // 队空,报错                    
    *t = Q->data[Q->front];                                 // 出队
    Q->front = (Q->front + 1) % MaxSize;                    // 队头指针加1
    return 1;
}

/************************辅助栈**************************/

typedef struct {
// 栈结构
  BiTree data[MaxSize];             // 数据域
  int top;                          // 栈顶指针
}SqStack;

int Push(SqStack* S, BiTree node) {
// 进栈函数
  if (S->top == MaxSize - 1) return 0;      // 栈满,报错
  S->data[++S->top] = node;                 // 栈顶指针加1后结点入栈
  return 1;
}

int Pop(SqStack* S, BiTree* t) {
// 退栈函数
  if (S->top == -1) return 0;               // 栈空,报错
  *t = S->data[S->top--];                   // 结点出栈后栈顶指针减1
  return 1;
}

int GetTop(SqStack S, BiTree* t) {
// 读栈顶元素
    if (S.top == -1) return 0;      // 栈空,报错
    *t = S.data[S.top];             // x记录栈顶元素
    return 1;
}
/**********************************************************/

void Insert(BiTree* T, ElemType e) {
// 插入新节点
  BiTree p, s = (BiTree) malloc (sizeof(BiTNode));  // 创建新结点
  s->lchild = s->rchild = NULL;
  s->data = e;
  if (!*T) {                                        // 若为空树,插入到根节点
    *T = s;
  } else {
    SqQueue Q = {0}; EnQueue(&Q, *T);               // 创建辅助队列,将根结点入队
    while(Q.rear != Q.front) {                      // 按层次遍历二叉树,查找插入点
      DeQueue(&Q, &p);                              // p指针指向出队结点
      if (p->lchild) {                              // 若p的左孩子非空,则入队
        EnQueue(&Q, p->lchild);
      } else {                                      // 若p的左孩子为空,插入新结点,并跳出循环
        p->lchild = s;
        break;
      } if (p->rchild) {                            // 若p的右孩子非空,则入队
        EnQueue(&Q, p->rchild);
      } else {                                      // 若p的右孩子为空,插入新结点,并跳出循环
        p->rchild = s;
        break;
      }
    }
  }
}

void PreOrder(BiTree T) {
// 前序遍历的递归算法
  if (T != NULL) {
    printf("%d ", T->data);
    PreOrder(T->lchild);
    PreOrder(T->rchild);
  }
}

void InOrder(BiTree T) {
// 中序遍历的递归算法
  if (T != NULL) {
    InOrder(T->lchild);
    printf("%d ", T->data);
    InOrder(T->rchild);
  }
}

void PostOrder(BiTree T) {
// 后序遍历的递归算法
  if (T != NULL) {
    PostOrder(T->lchild);
    PostOrder(T->rchild);
    printf("%d ", T->data);
  }
}

void PreOrder2(BiTree T) {
// 前序遍历的非递归算法
  SqStack S = {0}; S.top = -1;
  BiTree p = T;
  while(p || S.top != -1) {
    if (p) {                            // 若结点非空,则将结点进栈并输出,再访问他的左子树
      Push(&S, p);
      printf("%d ", p->data);
      p = p->lchild;
    } else {                            // 若结点为空,则弹栈,再访问弹出结点的右子树
      Pop(&S, &p);
      p = p->rchild;
    }
  }
}

void InOrder2(BiTree T) {
// 中序遍历的非递归算法
  SqStack S = {0}; S.top = -1;
  BiTree p = T;
  while(p || S.top != -1) {
    if (p) {                            // 若结点非空,则将结点进栈,并访问他的左子树
      Push(&S, p);
      p = p->lchild;
    } else {                            // 若结点为空,则弹栈并输出,再访问弹出结点的右子树
      Pop(&S, &p);
      printf("%d ", p->data);
      p = p->rchild;
    }
  }
}

void PostOrder2(BiTree T) {
// 后序遍历的非递归算法
  SqStack S = {0}; S.top = -1;
  int tag[MaxSize] = {0}; BiTree p = T;
  while (p || S.top != -1) {
    if (p) {                            // 若结点非空,将结点进栈,对应标记位置0,并访问它的左子树
      Push(&S, p);
      p = p->lchild;
      tag[S.top] = 0;
    } else {
      while(tag[S.top] == 1) {          // 若当前访问结点为空,将标记为1的栈顶元素弹栈并输出
        Pop(&S, &p);
        printf("%d ", p->data);
      }
      GetTop(S, &p);                    // 取栈顶结点给指针p,并将对应标记位置1,并访问它的右子树
      p = p->rchild;
      tag[S.top] = 1;
    }
    if (S.top == -1) break;             // 若栈空,跳出循环
  }
}

void LevelOrder(BiTree T) {
// 层次遍历算法
  SqQueue Q = {0}; BiTree p;                // 创建辅助队列和结点
  EnQueue(&Q, T);                           // 将根节点入队
  while(Q.rear != Q.front) {                // 循环遍历二叉树
    DeQueue(&Q, &p);                        // p指针指向出队结点,并打印
    printf("%d ", p->data);
    if (p->lchild) EnQueue(&Q, p->lchild);  // 若左子树非空,则入队
    if (p->rchild) EnQueue(&Q, p->rchild);  // 若右子树非空,则入队
  }
}

main.c

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

typedef int ElemType;

#include "BiTree.h"

int main(void)
{
  BiTree T = {0};
  int arr[] = {1,2,3,4,5,6,7,8,9};
  for (int i = 0; i < 9; ++i)
    Insert(&T, arr[i]);
  printf("=========递归算法=========\n");
  printf("前序遍历:"); PreOrder(T);
  printf("\n中序遍历:"); InOrder(T);
  printf("\n后序遍历:"); PostOrder(T);
  printf("\n========非递归算法========\n");
  printf("前序遍历:"); PreOrder2(T);
  printf("\n中序遍历:"); InOrder2(T);
  printf("\n后序遍历:"); PostOrder2(T);
  printf("\n==========================\n");
  printf("层次遍历:"); LevelOrder(T);
  return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值