队列实现二叉树遍历

合集下载

二叉树的建立与先序中序后序遍历 求叶子节点个数 求分支节点个数 求二叉树的高度

二叉树的建立与先序中序后序遍历 求叶子节点个数 求分支节点个数 求二叉树的高度

/*一下总结一些二叉树的常见操作:包括建立二叉树先/中/后序遍历二叉树求二叉树的叶子节点个数求二叉树的单分支节点个数计算二叉树双分支节点个数计算二叉树的高度计算二叉树的所有叶子节点数*/#include<stdio.h> //c语言的头文件#include<stdlib.h>//c语言的头文件stdlib.h千万别写错了#define Maxsize 100/*创建二叉树的节点*/typedef struct BTNode //结构体struct 是关键字不能省略结构体名字可以省略(为无名结构体)//成员类型可以是基本型或者构造形,最后的为结构体变量。

{char data;struct BTNode *lchild,*rchild;}*Bitree;/*使用先序建立二叉树*/Bitree Createtree() //树的建立{char ch;Bitree T;ch=getchar(); //输入一个二叉树数据if(ch==' ') //' '中间有一个空格的。

T=NULL;else{ T=(Bitree)malloc(sizeof(Bitree)); //生成二叉树(分配类型*)malloc(分配元素个数*sizeof(分配类型))T->data=ch;T->lchild=Createtree(); //递归创建左子树T->rchild=Createtree(); //地柜创建右子树}return T;//返回根节点}/*下面先序遍历二叉树*//*void preorder(Bitree T) //先序遍历{if(T){printf("%c-",T->data);preorder(T->lchild);preorder(T->rchild);}} *//*下面先序遍历二叉树非递归算法设计*/void preorder(Bitree T) //先序遍历非递归算法设计{Bitree st[Maxsize];//定义循环队列存放节点的指针Bitree p;int top=-1; //栈置空if(T){top++;st[top]=T; //根节点进栈while(top>-1) //栈不空时循环{p=st[top]; //栈顶指针出栈top--;printf("%c-",p->data );if(p->rchild !=NULL) //右孩子存在进栈{top++;st[top]=p->rchild ;}if(p->lchild !=NULL) //左孩子存在进栈{top++;st[top]=p->lchild ;}}printf("\n");}}/*下面中序遍历二叉树*//*void inorder(Bitree T) //中序遍历{if(T){inorder(T->lchild);printf("%c-",T->data);inorder(T->rchild);}}*//*下面中序遍历二叉树非递归算法设计*/void inorder(Bitree T) //中序遍历{Bitree st[Maxsize]; //定义循环队列,存放节点的指针Bitree p;int top=-1;if(T){p=T;while (top>-1||p!=NULL) //栈不空或者*不空是循环{while(p!=NULL) //扫描*p的所有左孩子并进栈{top++;st[top]=p;p=p->lchild ;}if(top>-1){p=st[top]; //出栈*p节点,它没有右孩子或右孩子已被访问。

层序遍历概念

层序遍历概念

层序遍历概念层序遍历概念层序遍历是一种二叉树的遍历方式,也叫广度优先遍历。

它按照树的层次顺序,从上到下逐层地访问每个节点。

在同一层中,按照从左到右的顺序访问每个节点。

层序遍历可以用于解决很多问题,例如查找最短路径、建立哈夫曼树等。

一、二叉树概念二叉树是一种特殊的树形结构,它的每个节点最多只有两个子节点。

一个节点没有子节点称为叶子节点,具有子节点的节点称为内部节点。

二叉树有很多种不同形态,例如满二叉树、完全二叉树等。

二、广度优先搜索广度优先搜索是一种图形搜索算法,它从起点开始向外扩展,在扩展过程中逐渐覆盖更多的区域。

广度优先搜索可以用来寻找两点之间最短路径或者解决迷宫问题等。

三、层序遍历算法层序遍历算法使用队列来实现。

首先将根节点入队列,然后依次取出队列中的元素,并将其左右子节点入队列。

按照这种方式遍历完一层之后,再遍历下一层,直到所有节点都被访问。

四、层序遍历应用1.查找最短路径在一个图中,如果每个边的权重都相等,那么可以使用广度优先搜索来查找两点之间的最短路径。

通过层序遍历,可以依次扩展到离起点越来越远的节点,直到找到目标节点为止。

2.建立哈夫曼树哈夫曼树是一种用于数据压缩的树形结构。

在哈夫曼编码中,出现频率高的字符使用较短的编码表示,而出现频率低的字符则使用较长的编码表示。

建立哈夫曼树时,可以先将所有叶子节点入队列,并不断取出队列中权值最小的两个节点合并为一个新节点,并将新节点入队列。

最终得到的根节点就是哈夫曼树。

五、总结层序遍历是一种非常实用的算法,在二叉树和图形搜索等领域有着广泛应用。

通过了解其基本原理和应用场景,我们可以更好地理解和运用这种算法来解决实际问题。

专科《数据结构》_试卷_答案

专科《数据结构》_试卷_答案

专科《数据结构》一、(共75题,共150分)1. 数据的逻辑结构在计算机内部存储表示称为为数据的()。

(2分)A.数据结构B.逻辑关系C.物理结构D.数据元素的内部结构.标准答案:C2. ()是数据的不可分割的最小单位。

(2分)A.数据对象B.数据元素C.数据类型D.数据项.标准答案:D3. 算法的时间复杂度是对算法()的度量。

(2分)A.时间效率B.空间效率C.可读性D.健壮性.标准答案:A4. ()是限制了插入和删除操作在一端进行的线性表。

(2分)A.栈B.队列C.串D.数组.标准答案:A5. 数组通常采用顺序存储的优点是()。

(2分)A.便于增加存储空间B.便于依据下标进行随机存取C.避免数据元素的移动D.防止下标溢出.标准答案:B6. 采用带头结点双向链表存储的线性表,在插入一个元素时,需要修改指针()次。

(2分)A.1B.2C.3D.4.标准答案:D7. 线性表的顺序存储结构是一种()的存储结构。

(2分)A.顺序存取B.随机存取C.索引存取D.Hash存取.标准答案:B8. 数组a[1..256]采用顺序存储,a的首地址为10,每个元素占2字节,则a[21]的地址是()。

(2分)A.10B.30C.50D.70.标准答案:C 9. 深度为4的二叉树,第4层至少有()个结点。

(2分)A.0B.1C.8D.15.标准答案:B10. 若二叉树对应的二叉链表共有11个非空链域,则该二叉树有()个结点的二叉树。

(2分)A.10B.11C.20D.21.标准答案:A11. 下面叙述错误的是()。

(2分)A.借助于队列可以实现对二叉树的层遍历B.栈的特点是先进后出C.对于单链表进行插入操作过程中不会发生上溢现象D.在无向图的邻接矩阵中每行1的个数等于对应的顶点度.标准答案:C12. 以下与数据的存储结构无关的术语是()。

(2分)A.循环队列B.双向链表C.哈希表D.数组.标准答案:D13. 在一个长度为n的链式队列中入队实现算法的时间复杂度为()。

数据结构与算法系列研究五——树、二叉树、三叉树、平衡排序二叉树AVL

数据结构与算法系列研究五——树、二叉树、三叉树、平衡排序二叉树AVL

数据结构与算法系列研究五——树、⼆叉树、三叉树、平衡排序⼆叉树AVL树、⼆叉树、三叉树、平衡排序⼆叉树AVL⼀、树的定义树是计算机算法最重要的⾮线性结构。

树中每个数据元素⾄多有⼀个直接前驱,但可以有多个直接后继。

树是⼀种以分⽀关系定义的层次结构。

a.树是n(≥0)结点组成的有限集合。

{N.沃恩}(树是n(n≥1)个结点组成的有限集合。

{D.E.Knuth})在任意⼀棵⾮空树中:⑴有且仅有⼀个没有前驱的结点----根(root)。

⑵当n>1时,其余结点有且仅有⼀个直接前驱。

⑶所有结点都可以有0个或多个后继。

b. 树是n(n≥0)个结点组成的有限集合。

在任意⼀棵⾮空树中:⑴有⼀个特定的称为根(root)的结点。

⑵当n>1时,其余结点分为m(m≥0)个互不相交的⼦集T1,T2,…,Tm。

每个集合本⾝⼜是⼀棵树,并且称为根的⼦树(subtree)树的固有特性---递归性。

即⾮空树是由若⼲棵⼦树组成,⽽⼦树⼜可以由若⼲棵更⼩的⼦树组成。

树的基本操作1、InitTree(&T) 初始化2、DestroyTree(&T) 撤消树3、CreatTree(&T,F) 按F的定义⽣成树4、ClearTree(&T) 清除5、TreeEmpty(T) 判树空6、TreeDepth(T) 求树的深度7、Root(T) 返回根结点8、Parent(T,x) 返回结点 x 的双亲9、Child(T,x,i) 返回结点 x 的第i 个孩⼦10、InsertChild(&T,&p,i,x) 把 x 插⼊到 P的第i棵⼦树处11、DeleteChild(&T,&p,i) 删除结点P的第i棵⼦树12、traverse(T) 遍历树的结点:包含⼀个数据元素及若⼲指向⼦树的分⽀。

●结点的度: 结点拥有⼦树的数⽬●叶结点: 度为零的结点●分枝结点: 度⾮零的结点●树的度: 树中各结点度的最⼤值●孩⼦: 树中某个结点的⼦树的根●双亲: 结点的直接前驱●兄弟: 同⼀双亲的孩⼦互称兄弟●祖先: 从根结点到某结点j 路径上的所有结点(不包括指定结点)。

二叉树遍历(前序、中序、后序、层次、广度优先、深度优先遍历)

二叉树遍历(前序、中序、后序、层次、广度优先、深度优先遍历)

⼆叉树遍历(前序、中序、后序、层次、⼴度优先、深度优先遍历)⽬录转载:⼆叉树概念⼆叉树是⼀种⾮常重要的数据结构,⾮常多其他数据结构都是基于⼆叉树的基础演变⽽来的。

对于⼆叉树,有深度遍历和⼴度遍历,深度遍历有前序、中序以及后序三种遍历⽅法,⼴度遍历即我们寻常所说的层次遍历。

由于树的定义本⾝就是递归定义,因此採⽤递归的⽅法去实现树的三种遍历不仅easy理解并且代码⾮常简洁,⽽对于⼴度遍历来说,须要其他数据结构的⽀撑。

⽐⽅堆了。

所以。

对于⼀段代码来说,可读性有时候要⽐代码本⾝的效率要重要的多。

四种基本的遍历思想前序遍历:根结点 ---> 左⼦树 ---> 右⼦树中序遍历:左⼦树---> 根结点 ---> 右⼦树后序遍历:左⼦树 ---> 右⼦树 ---> 根结点层次遍历:仅仅需按层次遍历就可以⽐如。

求以下⼆叉树的各种遍历前序遍历:1 2 4 5 7 8 3 6中序遍历:4 2 7 5 8 1 3 6后序遍历:4 7 8 5 2 6 3 1层次遍历:1 2 3 4 5 6 7 8⼀、前序遍历1)依据上⽂提到的遍历思路:根结点 ---> 左⼦树 ---> 右⼦树,⾮常easy写出递归版本号:public void preOrderTraverse1(TreeNode root) {if (root != null) {System.out.print(root.val+" ");preOrderTraverse1(root.left);preOrderTraverse1(root.right);}}2)如今讨论⾮递归的版本号:依据前序遍历的顺序,优先訪问根结点。

然后在訪问左⼦树和右⼦树。

所以。

对于随意结点node。

第⼀部分即直接訪问之,之后在推断左⼦树是否为空,不为空时即反复上⾯的步骤,直到其为空。

若为空。

则须要訪问右⼦树。

注意。

在訪问过左孩⼦之后。

c语言实现二叉树的四种遍历和求深度与叶子个数

c语言实现二叉树的四种遍历和求深度与叶子个数

c语言实现二叉树的四种遍历和求深度与叶子个数二叉树是一种常见的数据结构,它由节点组成,每个节点最多有两个子节点。

在C语言中,我们可以使用指针来实现二叉树的操作。

本文将介绍四种常见的二叉树遍历方式,以及如何求解二叉树的深度和叶子节点个数。

首先,我们需要定义一个二叉树节点的结构体,包含一个数据域和两个指针域,分别指向左子节点和右子节点。

代码如下:```cstruct TreeNode {int data;struct TreeNode* left;struct TreeNode* right;};```接下来,我们可以实现二叉树的四种遍历方式:前序遍历、中序遍历、后序遍历和层序遍历。

前序遍历是指先访问根节点,然后递归地遍历左子树和右子树。

代码如下:```cvoid preorderTraversal(struct TreeNode* root) {if (root == NULL) {return;}printf("%d ", root->data);preorderTraversal(root->left);preorderTraversal(root->right);}```中序遍历是指先递归地遍历左子树,然后访问根节点,最后递归地遍历右子树。

代码如下:```cvoid inorderTraversal(struct TreeNode* root) {if (root == NULL) {return;}inorderTraversal(root->left);printf("%d ", root->data);inorderTraversal(root->right);}```后序遍历是指先递归地遍历左子树和右子树,最后访问根节点。

代码如下:```cvoid postorderTraversal(struct TreeNode* root) {if (root == NULL) {return;}postorderTraversal(root->left);postorderTraversal(root->right);printf("%d ", root->data);}```层序遍历是按照树的层次逐层遍历节点。

数据结构-二叉树的存储结构和遍历

数据结构-二叉树的存储结构和遍历

return(p); }
建立二叉树
以字符串的形式“根左子树右子树”定义 一棵二叉树
1)空树 2)只含一个根 结点的二叉树 A 3)
B C
A
以空白字符“ ”表示
以字符串“A ”表示
D
以下列字符串表示 AB C D
建立二叉树 A B C C
T
A ^ B ^ C^ ^ D^
D
建立二叉树
Status CreateBiTree(BiTree &T) {
1 if (!T) return;
2 Inorder(T->lchild, visit); // 遍历左子树 3 visit(T->data); } // 访问结点 4 Inorder(T->rchild, visit); // 遍历右子树
后序(根)遍历
若二叉树为空树,则空操

左 子树
右 子树
作;否则, (1)后序遍历左子树; (2)后序遍历右子树; (3)访问根结点。
统计二叉树中结点的个数
遍历访问了每个结点一次且仅一次
设置一个全局变量count=0
将visit改为:count++
统计二叉树中结点的个数
void PreOrder (BiTree T){ if (! T ) return; count++; Preorder( T->lchild); Preorder( T->rchild); } void Preorder (BiTree T,void( *visit)(TElemType& e)) { // 先序遍历二叉树 1 if (!T) return; 2 visit(T->data); // 访问结点 3 Preorder(T->lchild, visit); // 遍历左子树 4 Preorder(T->rchild, visit);// 遍历右子树 }

二叉树遍历(前中后序遍历,三种方式)

二叉树遍历(前中后序遍历,三种方式)

⼆叉树遍历(前中后序遍历,三种⽅式)⽬录刷题中碰到⼆叉树的遍历,就查找了⼆叉树遍历的⼏种思路,在此做个总结。

对应的LeetCode题⽬如下:,,,接下来以前序遍历来说明三种解法的思想,后⾯中序和后续直接给出代码。

⾸先定义⼆叉树的数据结构如下://Definition for a binary tree node.struct TreeNode {int val;TreeNode *left;TreeNode *right;TreeNode(int x) : val(x), left(NULL), right(NULL) {}};前序遍历,顺序是“根-左-右”。

使⽤递归实现:递归的思想很简单就是我们每次访问根节点后就递归访问其左节点,左节点访问结束后再递归的访问右节点。

代码如下:class Solution {public:vector<int> preorderTraversal(TreeNode* root) {if(root == NULL) return {};vector<int> res;helper(root,res);return res;}void helper(TreeNode *root, vector<int> &res){res.push_back(root->val);if(root->left) helper(root->left, res);if(root->right) helper(root->right, res);}};使⽤辅助栈迭代实现:算法为:先把根节点push到辅助栈中,然后循环检测栈是否为空,若不空,则取出栈顶元素,保存值到vector中,之后由于需要想访问左⼦节点,所以我们在将根节点的⼦节点⼊栈时要先经右节点⼊栈,再将左节点⼊栈,这样出栈时就会先判断左⼦节点。

代码如下:class Solution {public:vector<int> preorderTraversal(TreeNode* root) {if(root == NULL) return {};vector<int> res;stack<TreeNode*> st;st.push(root);while(!st.empty()){//将根节点出栈放⼊结果集中TreeNode *t = st.top();st.pop();res.push_back(t->val);//先⼊栈右节点,后左节点if(t->right) st.push(t->right);if(t->left) st.push(t->left);}return res;}};Morris Traversal⽅法具体的详细解释可以参考如下链接:这种解法可以实现O(N)的时间复杂度和O(1)的空间复杂度。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
}
}
void main()
{
BiTree T;
CreateBiTree(T);
printf("先序遍历:\n");
PreOrder(T);
printf("\n中序遍历:\n");
InOrder(T);
printf("\n后序遍历:\n");
PostOrder(T);
printf("\n层次遍历:\n");
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#define OVERFLOW 2
#define OK 1
#define ERROR 0
typedef struct BiTNode //定义二叉树
{
char data;
struct BiTNode *lchild;
exit(OVERFLOW);
T->data=ch;
CreateBiTree(T->lchild);
CreateBiTree(T->rchild);
}
return OK;
}
void visit(BiTree T)
{
if(T->data!='#')
printf("%c",T->data);
}
void PreOrder(BiTree T)//先序遍历
{
if(T)
{
PostOrder(T->lchild);
PostOrder(T->rchild);
visit(T);
}
}
void InitQueue(LinkQueue *Q){
(*Q).front=(*Q).rear=(QueuePtr)malloc(sizeof(QNode));
if((*Q).front)
*e=p->data;
(*Q).front->next=p->next;
if((*Q).rear==p)
(*Q).rear=(*Q).front;
free(p);
}
}
void Level(BiTree T){/*层次遍历*/
LinkQueue q;
BiTree p;
InitQueue(&q);/*初始化一个空的队列*/
EnQueue(&q,T);/*入队*/
while(QueueEmpty(q))
{
DeQueue(&q,&p);/*出队*/
printf("%c ",p->data);
if(p->lchild)
EnQueue(&q,p->lchild);
if(p->rchild)
EnQueue(&q,p->rchild);
if(p)
p->data=e;p->next=NULL;
(*Q).rear->next=p;
(*Q).rear=p;
}
void DeQueue(LinkQueue *Q,BiTree *e){
QueuePtr p;
if((*Q).front!=(*Q).rear){
p=(*Q).front->next;
struct BiTNode *rchild;
}BiTNode,*BiTree ;
typedef struct QNode//队列节点结构体
{
BiTree data;
struct QNode *next;
}QNode,*QueuePtr;
typedef struct //队列
{
QueuePtr front;
{
if(T)
{
visit(T);
PreOrder(T->lchild);
PreOrder(T->rchild);
}
}
void InOrder(BiTree T)//中序遍历
{
if(T)
{
InOrder(T->lchild);
visit(T);
InOrder(T->rchild);
}
}
void PostOrder(BiTree T)//后序遍历
Level(T);
printf("\n");
}
QueuePtr rear; /*队头、队尾指针*/
}LinkQueue;
char CreateBiTree(BiTree&T) //创建二叉树
{ ቤተ መጻሕፍቲ ባይዱhar ch;
scanf("%c",&ch);
if(ch=='#')
T=NULL;
else{
if(!(T=(BiTree)malloc(sizeof(BiTNode))))
(*Q).front->next=NULL;
}
int QueueEmpty(LinkQueue Q){
if(Q.front==Q.rear)return 0;
return 1;
}
void EnQueue(LinkQueue *Q,BiTree e){
QueuePtr p;
p=(QueuePtr)malloc(sizeof(QNode));
相关文档
最新文档