(C语言版)二叉树遍历算法——包含递归前、中、后序和层次,非递归前、中、后序和层次遍历共八种

来源:互联网 发布:飞天怎么样知乎 编辑:程序博客网 时间:2024/05/09 00:09

        首先,要感谢网上的参考资料。

  1. http://mengliao.blog.51cto.com/876134/1178079(作者:BlackAlpha)
  2. http://blog.csdn.net/fzh1900/article/details/14056735(作者:_云淡风轻)
  3. http://blog.csdn.net/stpeace/article/details/8138458(作者:stpeace)

       二叉树是使用的比较广泛的一种数据结构,这里我写了二叉树的相关操作,包括初始化、新建、以及遍历。这里主要是为了学习二叉树的遍历算法,我总结后,写了八种二叉树的遍历算法,分别是:

      1.递归先序遍历
      2.递归中序遍历
      3.递归后序遍历
      4.非递归先序遍历(单栈辅助)
      5.非递归中序遍历(单栈辅助)
      6.非递归后序遍历(单栈辅助)
      7.递归层次遍历
      8.非递归层次遍历(队列辅助)
      当然,这里还要用到栈和队列,博客中以前有提到过(链式的栈和链式队列),其实还可以用顺序栈和顺序队列的(博客中后面将补上这块)。下面直接上代码:

LinkStack.h 链式栈头文件
#ifndef _LINK_STACK_H_H#define _LINK_STACK_H_H#include "BiTree.h"typedef pBiTree LStackEle; typedef struct LSNODE{LStackEle ele;struct LSNODE *pnext;}LSNode, *pLSNode;typedef struct LSTACK{pLSNode top;}LStack, *pLStack;//栈初始化void InitLinkStack(LStack &s);//入栈void PushLinkStack(LStack &s, LStackEle ele);//出栈void PopLinkStack(LStack &s, LStackEle &ele);//判断栈是否为空bool IsemptyLinkStack(LStack s);//获得栈顶值LStackEle GetTopLinkStack(LStack s);#endif
LinkQueue.h 链式队列头文件
#ifndef _LINK_QUEUE_H_H#define _LINK_QUEUE_H_H#include "BiTree.h"typedef pBiTree LQueueEle;typedef struct LQNODE{LQueueEle ele;struct LQNODE *pnext;}LQNode, *pLQNode;typedef struct LQUEUE{pLQNode rear;pLQNode front;}LQueue, *pLQueue;//初始化队列void InitLinkQueue(LQueue &q);//入队void EnLinkQueue(LQueue &q, LQueueEle ele);//出队void DeLinkQueue(LQueue &q, LQueueEle &ele);//判断队列是否为空bool IsemptyLinkQueue(LQueue q);//获得队头元素值LQueueEle GetFrontLinkQueue(LQueue q);#endif

BiTree.h 二叉树头文件
#ifndef _BITREE_H_H#define _BITREE_H_Htypedef struct BINODE{int ele;struct BINODE *plchild;struct BINODE *prchild;}BiNode, *pBiTree;//初始化二叉树(含根节点)void InitBiTree(pBiTree &bt, int ele);//创建二叉树节点BiNode *CreateBiTreeNode(pBiTree lchild, pBiTree rchild, int ele);//插入左子二叉树void InsertLChild(pBiTree parent, pBiTree lchild);//插入右子二叉树void InsertRChild(pBiTree parent, pBiTree rchild);//计算二叉树的深度int DeepBiTree(pBiTree bt);//递归先序遍历void RePreOrderTraverse(pBiTree bt); //递归中序遍历void ReInOrderTraverse(pBiTree bt);//递归后序遍历void RePostOrderTraverse(pBiTree bt);//非递归先序遍历二void NonRePreOrderTraverse(pBiTree bt);//非递归中序遍历void NonReInOrderTraverse(pBiTree bt);//非递归后序遍历void NonRePostOrderTraverse(pBiTree bt);//非递归层次遍历void NonReLevelOrderTraverse(pBiTree bt);//递归层次遍历void ReLevelOrderTraverse(pBiTree bt);void PrintLevelNode(pBiTree bt, int level);#endif

LinkStack.cpp 链式栈源文件
#include "LinkStack.h"#include <stdlib.h>#include <stdio.h>//栈初始化void InitLinkStack(LStack &s){s.top= NULL;}//入栈void PushLinkStack(LStack &s, LStackEle ele){pLSNode pnew = (pLSNode)malloc(sizeof(LSNode));if (pnew == NULL){printf("内存分配失败!\n");exit(EXIT_FAILURE);}pnew->ele = ele;pnew->pnext = s.top;s.top = pnew;}//出栈void PopLinkStack(LStack &s, LStackEle &ele){pLSNode pt = NULL;if (IsemptyLinkStack(s)){printf("栈为空,不能出栈操作!\n");exit(EXIT_FAILURE);}else{ele = s.top->ele;pt = s.top;s.top = pt->pnext;free(pt);pt = NULL;}}//判断栈是否为空bool IsemptyLinkStack(LStack s){if (s.top == NULL)return true;elsereturn false;}//获得栈顶元素LStackEle GetTop(LStack s){if (IsemptyLinkStack(s)){printf("栈为空,不能获得栈顶元素值!\n");exit(EXIT_FAILURE);}elsereturn s.top->ele;}
LinkQueue.cpp 链式队列源文件
#include <stdlib.h>#include <stdio.h>#include "LinkQueue.h"//初始化队列void InitLinkQueue(LQueue &q){q.front = (pLQNode)malloc(sizeof(LQNode));if (q.front == NULL){printf("内存分配失败!\n");exit(EXIT_FAILURE);}q.rear = q.front;}//入队void EnLinkQueue(LQueue &q, LQueueEle ele){pLQNode pnew = (pLQNode)malloc(sizeof(LQNODE));if (pnew == NULL){printf("内存分配失败!\n");exit(EXIT_FAILURE);}pnew->ele = ele;pnew->pnext = NULL;q.rear->pnext = pnew;q.rear = pnew;}//出队void DeLinkQueue(LQueue &q, LQueueEle &ele){pLQNode pt = NULL;if (IsemptyLinkQueue(q)){printf("队列为空,不能出队操作!\n");exit(EXIT_FAILURE);}ele = q.front->pnext->ele;pt = q.front->pnext;q.front->pnext = pt->pnext;free(pt);/*pt是最后一个节点时,释放完了以后,尾指针指向的是随机内存,所以让它和头指针指向同一个地址。*/if (q.front->pnext == NULL)q.rear = q.front;}//判断队列是否为空bool IsemptyLinkQueue(LQueue q){if (q.front == q.rear)return true;elsereturn false;}//获得队头元素LQueueEle GetFrontLinkQueue(LQueue q){if (IsemptyLinkQueue(q)){printf("队列为空,不能获得队头元素!\n");exit(EXIT_FAILURE);}return q.front->pnext->ele;}

BiTree.cpp 二叉树源文件
#include <stdlib.h>#include <stdio.h>#include "BiTree.h"#include "LinkStack.h"#include "LinkQueue.h"//初始化二叉树(含根节点)void InitBiTree(pBiTree &bt, int ele){bt = (BiNode *)malloc(sizeof(BiNode));if (bt == NULL){printf("内存分配失败!\n");exit(EXIT_FAILURE);}bt->ele = ele;bt->plchild = NULL;bt->prchild = NULL;}//创建二叉树节点BiNode *CreateBiTreeNode(pBiTree lchild, pBiTree rchild, int ele){BiNode *pnew = (BiNode *)malloc(sizeof(BiNode));if (pnew == NULL){printf("内存分配失败!\n");exit(EXIT_FAILURE);}pnew->ele = ele;pnew->plchild = lchild;pnew->prchild = rchild;return pnew;}//插入左子二叉树void InsertLChild(pBiTree parent, pBiTree lchild){parent->plchild = lchild;}//插入右子二叉树void InsertRChild(pBiTree parent, pBiTree rchild){parent->prchild = rchild;}//用递归的方法计算二叉树的深度int DeepBiTree(pBiTree bt){int ldeep = 0, rdeep = 0;if (bt){ldeep = DeepBiTree(bt->plchild);rdeep = DeepBiTree(bt->prchild);return (ldeep > rdeep ? ldeep : rdeep) + 1;}elsereturn 0;}//(一)递归先序遍历void RePreOrderTraverse(pBiTree bt){if(bt != NULL){printf("%d ", bt->ele);RePreOrderTraverse(bt->plchild);RePreOrderTraverse(bt->prchild);}}//(二)递归中序遍历void ReInOrderTraverse(pBiTree bt){if(bt != NULL){ReInOrderTraverse(bt->plchild);printf("%d ", bt->ele);ReInOrderTraverse(bt->prchild);}}//(三)递归后序遍历void RePostOrderTraverse(pBiTree bt){if(bt != NULL){RePostOrderTraverse(bt->plchild);RePostOrderTraverse(bt->prchild);printf("%d ", bt->ele);}}//(四)非递归先序遍历void NonRePreOrderTraverse(pBiTree bt){LStack s;InitLinkStack(s);while (bt != NULL || !IsemptyLinkStack(s)){while ( bt != NULL){printf("%d ", bt->ele);PushLinkStack(s, bt);bt = bt->plchild;}if (!IsemptyLinkStack(s)){PopLinkStack(s, bt);bt = bt->prchild;}}}//(五)非递归中序遍历void NonReInOrderTraverse(pBiTree bt){LStack s;InitLinkStack(s);while (bt != NULL || !IsemptyLinkStack(s)){while (bt != NULL){PushLinkStack(s, bt);bt = bt->plchild;}if (!IsemptyLinkStack(s)){PopLinkStack(s, bt);printf("%d ", bt->ele);bt = bt->prchild;}}}//(六)非递归后序遍历void NonRePostOrderTraverse(pBiTree bt){LStack s;InitLinkStack(s);BiNode * pt = NULL;while (bt != NULL || !IsemptyLinkStack(s)){while (bt != NULL){PushLinkStack(s, bt);bt = bt->plchild;}if (!IsemptyLinkStack(s)){PopLinkStack(s, bt);if (bt->prchild == NULL || bt->prchild == pt){printf("%d ", bt->ele);pt = bt;bt = NULL;}else{PushLinkStack(s, bt);bt = bt->prchild;}}}}//(七)非递归层次遍历void NonReLevelOrderTraverse(pBiTree bt){LQueue q;InitLinkQueue(q);BiNode *pt = NULL;if (bt != NULL){EnLinkQueue(q, bt);while (!IsemptyLinkQueue(q)){DeLinkQueue(q, pt);printf("%d ", pt->ele);if (pt->plchild != NULL)EnLinkQueue(q, pt->plchild);if (pt->prchild != NULL)EnLinkQueue(q, pt->prchild);}}}//(八)递归层级遍历void ReLevelOrderTraverse(pBiTree bt){int i, deep;if (bt != NULL){deep = DeepBiTree(bt);for(i=1; i<deep+1; i++)PrintLevelNode(bt, i);}}void PrintLevelNode(pBiTree bt, int level){if (bt != NULL && level > 0){if (level == 1)printf("%d ", bt->ele);PrintLevelNode(bt->plchild, level - 1);PrintLevelNode(bt->prchild, level - 1);}}

main.cpp 测试程序源文件
#include <stdio.h>#include "BiTree.h"#include "LinkStack.h"#include "LinkQueue.h"int main(void){//二叉树测试代码pBiTree bt;InitBiTree(bt, 10);pBiTree lchild = CreateBiTreeNode(CreateBiTreeNode(NULL, CreateBiTreeNode(CreateBiTreeNode(NULL, NULL, 80), NULL, 55), 40), NULL, 20);InsertLChild(bt, lchild);pBiTree rchild = CreateBiTreeNode(NULL, CreateBiTreeNode(CreateBiTreeNode(NULL, NULL, 60), CreateBiTreeNode(NULL, NULL, 70), 50), 30);InsertRChild(bt, rchild);printf("********二叉树图形********\n");printf("          10\n");printf("         /  \\\n");printf("        20   30\n");printf("       / \\  / \\\n");printf("     40   N N  50\n");printf("    / \\       /  \\\n");printf("   N  55     60   70\n");printf("     / \\    / \\  / \\\n");printf("   80   N  N  N  N  N\n");printf("  / \\\n");printf(" N   N\n");printf("二叉树的深度:%d", DeepBiTree(bt));printf("\n**********************************");printf("\n递归前序遍历:");RePreOrderTraverse(bt);printf("\n递归中序遍历:");ReInOrderTraverse(bt);printf("\n递归后序遍历:");RePostOrderTraverse(bt);printf("\n**********************************");printf("\n非递归前序遍历:");NonRePreOrderTraverse(bt);printf("\n非递归中序遍历:");NonReInOrderTraverse(bt);printf("\n非递归后序遍历:");NonRePostOrderTraverse(bt);printf("\n**********************************");printf("\n非递归层次遍历:");NonReLevelOrderTraverse(bt);printf("\n递归层次遍历:");ReLevelOrderTraverse(bt);putchar('\n');
return 0;}
下面是结果图:


PS:希望大家能共同学习、共同进步。

0 0
原创粉丝点击