数据结构之非递归遍历和层次遍历(C语言版)
来源:互联网 发布:如何优化前端页面 编辑:程序博客网 时间:2024/05/21 10:48
调试环境:win10+vs2015
树是一种非常重要的数据结构,遍历树就变得尤为重要。
这里主要讲利用栈实现非递归遍历二叉树和利用队列实现层次遍历二叉树。
非递归遍历
首先需要编写一个树的结构体和相关函数
//声明一个树的结构体typedef struct Tree { char data; //存放的数据 struct Tree* left; //指向左孩子 struct Tree* right; //指向右孩子}Tree,*pTree;//初始化化二叉链表pTree Init() { pTree ptree = (pTree)malloc(sizeof(Tree)); //申请节点 ptree->data = 0; //赋初值 ptree->left = NULL; ptree->right = NULL; return ptree; //赋值}//先序遍历创建二叉链表void Creat(pTree* ptree) { //传入一个树节点的指针 char c; c = getchar(); //获取控制台的一个字符 if (c == '.')*ptree = NULL; //如果为“.”,就把该子树赋空 else { *ptree = (pTree)malloc(sizeof(Tree)); //否则,申请节点 (*ptree)->data = c; //赋值 Creat(&((*ptree)->left)); //递归调用,创建左子树 Creat(&((*ptree)->right)); //递归调用,创建右子树 }}
其次声明一个栈
//定义一个栈节点的结构体typedef struct Stack { pTree ptree; //存放子树 struct Stack * next; //指向下一个栈节点地址}Stack,*pStack;//初始化栈pStack InitStack() { pStack ps = (pStack)malloc(sizeof(Stack)); //申请一个节点 ps->next = NULL; //赋值 ps->ptree = NULL; return ps; //返回}//压栈pStack PushStack(pStack* ps, pTree ptree) { //因为要改变栈头结点的指向所以传入指针 pStack temp = (pStack)malloc(sizeof(Stack)); //申请节点 temp->next = (*ps)->next; //将申请的节点压入栈 (*ps)->next = temp; temp->ptree = ptree; return *ps; //返回}//弹栈pStack PopStack(pStack* ps) { if (IsEmptyStack(*ps))return *ps; //判断栈是否为空 pStack temp = (*ps)->next; //将栈头结点取出来 (*ps)->next = temp->next; free(temp); //释放 temp = NULL; //置空 return *ps; //返回}//判空int IsEmptyStack(pStack ps) { if (ps->next == NULL)return 1; //判断是否为空,是返回1 else return 0;}//中序非递归遍历void MidNotPrint(pTree ptree) { if (ptree == NULL)return; //如果是空树,直接返回 pStack ps = InitStack(); //初始化栈 pTree temp = ptree; //做一个树的临时变量 while (temp != NULL || !IsEmptyStack(ps)) { //循环 if (temp != NULL) { //当前树不为空 PushStack(&ps, temp); //压栈 temp = temp->left; // 当前树变成其左子树 } else { temp = ps->next->ptree; //读取栈的第一个节点 printf("%c ", temp->data); //打印输出 temp = temp->right; //转到右子树 ps = PopStack(&ps); //当前节点弹栈 } }}
测试一下
int main() { pTree ptree = Init(); //初始化树 Creat(&ptree); //控制台输入字符串创建树 MidNotPrint(ptree); //中序非递归打印 return 0;}
控制台输入:abc..de.g..f…
输出结果:c b e g d f a
利用队列实现层次遍历
树的结构体定义和上面的相同,只不过多了函数
//队列实现层次遍历void CengPrint(pTree ptree) { if (ptree == NULL)return; //判空 pQueue pq = InitQueue(); //初始化队列 pq = PushQueue(&pq, ptree); //入队 while (!IsEmptyQueue(pq)) { pTree temp = pq->next->ptree; //读取节点信息 printf("%c ", temp->data); //打印输出 if (temp->left)PushQueue(&pq, temp->left); //左子树不为空,左子树入队 if (temp->right)PushQueue(&pq, temp->right); //右子树不为空,右子树入队 pq = PopQueue(&pq); //当前节点出队 }}
队列的结构体定义
//初始化队列pQueue InitQueue() { pQueue pq = (pQueue)malloc(sizeof(Queue)); //申请节点 pq->next = NULL; //赋初值 pq->ptree = NULL; return pq;}//入队pQueue PushQueue(pQueue* pq, pTree ptree) { pQueue temp = (*pq)->next; //当前节点的拷贝 if (temp != NULL) { //判断队列是否不空 while (temp->next != NULL)temp = temp->next; //访问队列最后一个节点 pQueue tmp = (pQueue)malloc(sizeof(Queue)); //申请空间 tmp->ptree = ptree; //赋值 tmp->next = NULL; temp->next = tmp; //改变指针指向 } else { temp = (pQueue)malloc(sizeof(Queue)); //申请节点 temp->next = NULL; //赋值 temp->ptree = ptree; (*pq)->next = temp; //改变指针指向 } return *pq;}//出队pQueue PopQueue(pQueue* pq) { if (IsEmptyQueue(*pq))return *pq; //判空 pQueue temp = (*pq)->next; //改变指针指向 (*pq)->next = temp->next; free(temp); //释放 temp = NULL; //置空 return *pq;}//判空int IsEmptyQueue(pQueue pq) { if (pq->next == NULL)return 1; else return 0;}
测试函数
int main() { pTree ptree = Init(); Creat(&ptree); CengPrint(ptree); return 0;}
控制台输入:abc..de.g..f…
运行后结果:a b c d e f g
总结:
利用栈和队列实现对树的遍历是数据结构里面最基础的算法,只有掌握好了他们才能够掌握更高大上的数据结构算法。
0 0
- 数据结构之非递归遍历和层次遍历(C语言版)
- (C语言版)二叉树遍历算法——包含递归前、中、后序和层次,非递归前、中、后序和层次遍历共八种
- 数据结构C语言版之邻接矩阵(遍历)
- 数据结构之二叉树遍历(递归和非递归)
- 中序遍历非递归算法(C语言版)
- 数据结构 树 层次遍历二叉树 C语言版
- <数据结构>二叉树的递归、非递归以及层次遍历算法C语言实现
- 二叉树的遍历(递归+非递归+层次遍历)
- 数据结构C语言版之邻接表(各种遍历)
- java数据结构--二叉树,递归遍历,非递归遍历,层次遍历
- 【数据结构】二叉树的定义,递归遍历,非递归遍历,层次遍历,深度等
- 二叉树遍历(先中后序 递归和非递归+层次遍历)java代码 可直接运行
- 二叉树的非递归遍历 C语言版
- 二叉树的非递归遍历 C语言版
- 二叉树的非递归遍历 C语言版
- 二叉树的非递归遍历 C语言版
- 树的遍历(先中后序,非递归,层次遍历)
- 数据结构之关于树的操作(树的递归和非递归遍历)-(四补)
- PYTHON属性访问
- 多个github帐号的SSH key切换
- 蓝桥网 算法训练 方格取数
- MAC下用homebrew安装及配置apache、php和mysql
- c++11多线程编程---线程安全队列
- 数据结构之非递归遍历和层次遍历(C语言版)
- Boost.Lockfree
- 8086逻辑运算和移位
- 安卓Andriod使用入门(一)【圆形Menu菜单】
- D-Link DP-LINK302打印服务器WIN7版软件
- 用友T3建立年度帐提示:对象名TAX_SB_NSSB_BJ_ZB无效
- Windows Server 2003修改系列号
- Windows2012微软取消了服务器桌面个性化选项
- 开发一款开源爬虫框架系列(三):聊聊并发包中的队列(Queue)