<数据结构>二叉树的递归、非递归以及层次遍历算法C语言实现
来源:互联网 发布:绵阳互惠软件 编辑:程序博客网 时间:2024/05/16 18:33
二叉树是数据结构中一种非常重要的结构,熟练的掌握二叉树的创建,遍历是打好编程基础的关键。对于遍历,不能仅仅只掌握递归遍历,还应掌握效率更高地非递归遍历。对于非递归的先序、中序、后序遍历要用到栈(在之前的博文中已经提到了具体的实现过程),而在层次遍历中要使用到另一种数据结构——队列,这个在之前博文中没有提到,因此在本篇博文中将会给出简单实现。
在本篇博文中给出的代码实现了:二叉树的创建、二叉树的递归、非递归的先、中、后序以及层次遍历七种遍历算法。话不多说,下面给出代码(仅供参考):
因为要用到栈和队列,因此在这代码一并给出,方便大家运行。
“LinkStack.h”:
"LinkQueue.h":#ifndef _LINKSTACK_H#define _LINKSTACK_H#include<stdlib.h>#include<stdio.h>#include"BiTree.h"//定义栈中数据的类型typedef BiTree LStackElem;//定义栈元素的结构typedef struct SNode{LStackElem data;struct SNode * next;}SNode, *LinkNode;//定义栈的结构typedef struct {LinkNode node; //栈顶指针(相当于链表中的头指针)int size;//栈的大小}LinkStack;//初始化栈void init_link_stack(LinkStack &S);//进栈void push(LinkStack &S, LStackElem e);//出栈void pop(LinkStack &S, LStackElem &e);//判断栈是否为空int is_stack_empty(LinkStack S);//获得栈顶元素void get_top(LinkStack S, LStackElem &e);#endif
#ifndef _LINKQUEUE_H#define _LINKQUEUE_H#include"BiTree.h"typedef BiTree QueueElem;typedef struct QNode{QueueElem data;struct QNode * next;}QNode;typedef struct {QNode * top; //队列头指针QNode * bottom; //队列尾指针int size; //队列大小}LinkQueue;//初始化队列void init_link_queue(LinkQueue &Q);//入队列void in_link_queue(LinkQueue &Q, QueueElem e);//出队列void out_link_queue(LinkQueue &Q, QueueElem &e);//队列是否为空int is_queue_empty(LinkQueue Q);#endif
"BiTree.h":
#ifndef _BITREE_H#define _BITREE_H//定义二叉树中存储的数据类型typedef int BiNodeElem;//定义二叉树的结构typedef struct BiNode{BiNodeElem data;struct BiNode * lchild;struct BiNode * rchild;}BiNode, *BiTree;//初始化一棵仅含根节点的二叉树,根节点的值为evoid init_bitree(BiTree &T, BiNodeElem e);//产生树节点BiNode * creat_bitree_node(BiNodeElem e, BiNode * lchild, BiNode * rchild);//增加左子树void add_lchild(BiNode * &binode, BiNode * lchild);//增加右子树void add_rchild(BiNode * &binode, BiNode * rchild);//递归先序遍历void pro_order_recursion(BiTree T);//递归中序遍历void infix_order_recursion(BiTree T);//递归后序遍历void post_order_recursion(BiTree T);//非递归先序遍历void pro_order_no_recursion(BiTree T);//非递归中序遍历void infix_order_no_recursion(BiTree T);//非递归后序遍历void post_order_no_recursion(BiTree T);//层次遍历void hierarchy_order(BiTree T);#endif
"LinkStack.c":
#include"LinkStack.h"//初始化栈void init_link_stack(LinkStack &S){S.node = (SNode *)malloc(sizeof(SNode));S.node->next = NULL;S.size = 0;}//进栈void push(LinkStack &S, LStackElem e){LinkNode p = (LinkNode)malloc(sizeof(SNode));p->data = e;p->next = S.node->next;S.node->next = p;++S.size;}//出栈void pop(LinkStack &S, LStackElem &e){if(is_stack_empty(S)){printf("栈为空,不能出栈。\n");return;}e = S.node->next->data;LinkNode p = S.node->next;S.node->next = S.node->next->next;free(p);--S.size;}//判断栈是否为空int is_stack_empty(LinkStack S){if(S.size == 0)return 1;elsereturn 0;}//获得栈顶元素void get_top(LinkStack S, LStackElem &e){e = S.node->next->data;}
"LinkQueue.c":
#include"LinkQueue.h"#include<stdio.h>#include<stdlib.h>//初始化队列void init_link_queue(LinkQueue &Q){Q.top = Q.bottom = (QNode *)malloc(sizeof(QNode));Q.top->next = NULL;Q.size = 0;}//入队列(尾插法)void in_link_queue(LinkQueue &Q, QueueElem e){QNode * p = (QNode *)malloc (sizeof(QNode));p->data = e;p->next = NULL;Q.bottom->next = p;Q.bottom = p;++Q.size;}//出队列void out_link_queue(LinkQueue &Q, QueueElem &e){if(Q.size > 0){e = Q.top->next->data;QNode * p = Q.top->next;Q.top->next = Q.top->next->next;if(Q.bottom == p)Q.bottom = Q.top;free(p);--Q.size;}}//队列是否为空int is_queue_empty(LinkQueue Q){if(Q.size == 0)return 1;elsereturn 0;}
"BiTree.c":
#include"BiTree.h"#include"LinkStack.h"#include"LinkQueue.h"#include<stdio.h>#include<stdlib.h>//初始化一棵仅含根节点的二叉树,根节点的值为evoid init_bitree(BiTree &T, BiNodeElem e){T = (BiNode *) malloc(sizeof(BiNode));T->data = e;T->lchild = NULL;T->rchild = NULL;}//产生树节点BiNode * creat_bitree_node(BiNodeElem e, BiNode * lchild, BiNode * rchild){BiNode * pTree = (BiNode *)malloc(sizeof(BiNode));pTree->data = e;pTree->lchild = lchild;pTree->rchild = rchild;return pTree;}//增加左子树void add_lchild(BiNode * &binode, BiNode * lchild){if(binode != NULL)binode->lchild = lchild;}//增加右子树void add_rchild(BiNode * &binode, BiNode * rchild){if(binode != NULL)binode->rchild = rchild;}//递归先序遍历void pro_order_recursion(BiTree T){if(T != NULL){printf("%d ",T->data);pro_order_recursion(T->lchild);pro_order_recursion(T->rchild);}}//递归中序遍历void infix_order_recursion(BiTree T){if(T != NULL){infix_order_recursion(T->lchild);printf("%d ",T->data);infix_order_recursion(T->rchild);}}//递归后序遍历void post_order_recursion(BiTree T){if(T != NULL){post_order_recursion(T->lchild);post_order_recursion(T->rchild);printf("%d ",T->data);}}//非递归先序遍历void pro_order_no_recursion(BiTree T){LinkStack S;init_link_stack(S);//把根节点指针赋值给pBiNode * p = T;while( NULL != p || !is_stack_empty(S)){//打印当前节点,其左节点依次进栈while(NULL != p ){printf("%d ",p->data);push(S,p);p = p->lchild;}if(!is_stack_empty(S)){pop(S,p);p = p->rchild;}}}//非递归中序遍历void infix_order_no_recursion(BiTree T){LinkStack S;init_link_stack(S);//把根节点指针赋值给pBiNode * p = T;while( NULL != p || !is_stack_empty(S)){//左节点依次进栈while(NULL != p){push(S,p);p = p->lchild;}if(!is_stack_empty(S)){pop(S,p);printf("%d ",p->data);p = p->rchild;}}}//非递归后序遍历void post_order_no_recursion(BiTree T){LinkStack S;init_link_stack(S);BiNode * p = T;//存储最近一次访问的节点BiNode * visited =NULL;while(NULL != p || !is_stack_empty(S)){//直接写p 更为简单,不需要写NULL !=pwhile(p){push(S,p);p = p->lchild;}if(!is_stack_empty(S)){pop(S,p);//如果不存在右子树,或右子树被访问/*解析一下:根据上面的while循环,栈顶元素必然不存在左子树;如何存在右子树,又根据后序遍历的特点,最近一次被访问的节点,必然是该节点的右子树*/if( !p->rchild || p->rchild == visited){printf("%d ",p->data);visited = p;p = NULL;}else{push(S,p);p = p->rchild;}}}}//层次遍历void hierarchy_order(BiTree T){LinkQueue Q;init_link_queue(Q);BiNode * p;if(T){in_link_queue(Q,T);while(!is_queue_empty(Q)){out_link_queue(Q,p);printf("%d ",p->data);if(p->lchild)in_link_queue(Q,p->lchild);if(p->rchild)in_link_queue(Q,p->rchild);}}}
"main.c":
#include"LinkStack.h"#include"LinkQueue.h"#include"BiTree.h"int main(){BiTree T;init_bitree(T,10);BiNode * lchild = creat_bitree_node(20,NULL,creat_bitree_node(40,NULL,NULL));add_lchild(T, lchild);BiNode * rchild1 = creat_bitree_node(50,creat_bitree_node(60,NULL,NULL),creat_bitree_node(70,NULL,NULL));BiNode * rchild = creat_bitree_node(30, NULL, rchild1);add_rchild(T,rchild);printf("构造的树的结果如下:\n");printf(" 10\n");printf(" / \\\n");printf(" 20 30\n");printf(" \\ \\ \n");printf(" 40 50\n");printf(" /\\\n");printf(" 60 70\n\n");printf("递归先序遍历的结果:\n");pro_order_recursion(T);printf("\n");printf("递归中序遍历的结果:\n");infix_order_recursion(T);printf("\n");printf("递归后序遍历的结果:\n");post_order_recursion(T);printf("\n");printf("\n===============================================\n\n");printf("非递归先序遍历的结果:\n");pro_order_no_recursion(T);printf("\n");printf("非递归中序遍历的结果:\n");infix_order_no_recursion(T);printf("\n");printf("非递归后序遍历的结果:\n");post_order_no_recursion(T);printf("\n");printf("非递归层次遍历的结果:\n");hierarchy_order(T);printf("\n");return 0;}
运行结果如下:
与大家分享,共同学习,相互提高,如有疑问或建议,请留言。
- <数据结构>二叉树的递归、非递归以及层次遍历算法C语言实现
- 遍历二叉树的递归算法与非递归算法以及C语言实现
- JAVA语言实现二叉树的层次遍历的非递归算法及递归算法。
- JAVA语言实现二叉树的层次遍历的非递归算法及递归算法
- 二叉树的递归,层次,以及非递归遍历
- C语言实现二叉树的常用的算法(递归与非递归实现遍历)
- 二叉树的非递归遍历以及层次遍历
- 数据结构----二叉树遍历的非递归算法实现
- 实现二叉树的先序遍历、中序遍历、后序遍历的递归非递归算法以及层次遍历算法
- C语言数据结构实现二叉树递归与非递归遍历(数据结构第四次实验)
- 非递归二叉树层次遍历算法
- 二叉树的遍历(c语言非递归算法)
- 二叉树遍历的c语言非递归实现
- 二叉树的非递归遍历C语言实现
- 数据结构与算法学习记录--二叉树的创建,递归遍历,非递归遍历的实现
- 【数据结构】二叉树的定义,递归遍历,非递归遍历,层次遍历,深度等
- 二叉树的非递归层次遍历
- 非递归实现二叉树的层次遍历
- 捏合(pinch)手势
- 日语N4复习资料
- 《CS:APP》(深入理解计算机系统》reading notes
- spring rmi 了解
- 给页面换皮肤的思考
- <数据结构>二叉树的递归、非递归以及层次遍历算法C语言实现
- Hinge loss
- 唐顿庄园里的Isobel Crawley夫人真的能来卫报工作吗?
- hdu 1159 Common Subsequence (LCS)
- eclipse一直报initializing java tooling(1%)问题
- 基本UDP套接字之回射程序
- gcc 编译器简介
- 怎么样重写equals方法
- HOG:用于人体检测的梯度方向直方图 Histograms of Oriented Gradients for Human Detection