数据结构二叉树遍历及线索化后各种操作(绝对无错)

合集下载

二叉树遍历前序中序后序算法

二叉树遍历前序中序后序算法

二叉树遍历前序中序后序算法嘿,朋友,今天咱们聊聊二叉树的遍历,听上去有点复杂,其实一点都不难,就像吃瓜一样轻松!先来简单介绍一下,二叉树就像家里的家谱树,每个节点代表一个家庭成员,左右两个孩子代表着它的“后代”。

而遍历嘛,就是咱们要找出树上的每一个成员,看看他们在干啥。

首先是前序遍历,听这个名字就知道,它是先看爸爸,然后看左边的孩子,最后再看右边的。

这就像咱们去亲戚家串门,进门先跟长辈打招呼,再去找小朋友玩,先礼后兵,懂不懂?这样一来,整个树就都在咱的掌控之中,简直是如虎添翼。

再说这中序遍历,简单得很,就是先看左边,再看爸爸,最后再看右边。

就像咱们吃饭,先把青菜吃了,接着吃主食,最后来个甜点,吃得心满意足。

通过这种方式,咱们能得到一个排好序的结果,简直是个小吃货的心愿。

然后就是后序遍历,听名字就觉得有点神秘。

它的顺序是先看左边的孩子,再看右边的,最后才是爸爸。

这个遍历方式就像是收拾家,先把玩具放回去,再把书整理好,最后再把桌子擦一擦,整个过程干净利落,谁看了都得点赞!这样一来,不论是前、中、后,咱都能把树上的每一个节点清清楚楚地遍历一遍,真是爽快!可能会遇到一些难缠的树,比如不平衡的二叉树,这时候就像是一个在打怪的游戏,咱们得运用聪明才智,找到最优解。

你要是用前序遍历的话,能迅速找到每个节点,可是要是用后序遍历,那可就需要更多的耐心和时间。

每一种遍历方法都有它独特的魅力,就像每个人的性格,各有千秋,谁也不能小看谁!说到这里,咱们还得提提递归和非递归的方法。

递归就像是个循环的故事,永远在重复,直到找到结果;而非递归呢,就是更为直接,像一刀切的方式,让人省心省力。

每种方式都有它的优缺点,选哪个好,得看你自己的情况,真是一个聪明的选择题呢!哎,提到遍历,大家最关心的就是效率问题了。

前序、中序、后序,各有高低,性能的差异就像爬山,谁能跑得快,谁就能早到山顶。

不过别担心,只要有方法,效率就会提高,想要在这棵树上玩得开心,最重要的就是要选择合适的遍历策略。

二叉树的遍历方法

二叉树的遍历方法

二叉树的遍历方法1. 前序遍历:先访问根节点,再遍历左子树,最后遍历右子树。

详细描述:从根节点开始,首先访问根节点并打印它的值。

接着,递归地遍历左子树,然后递归地遍历右子树。

2. 中序遍历:先遍历左子树,再访问根节点,最后遍历右子树。

详细描述:从根节点开始,首先递归地遍历左子树。

然后,访问根节点并打印它的值。

递归地遍历右子树。

3. 后序遍历:先遍历左子树,再遍历右子树,最后访问根节点。

详细描述:从根节点开始,首先递归地遍历左子树。

然后,递归地遍历右子树。

访问根节点并打印它的值。

4. 层序遍历:按照层级顺序从上往下逐层遍历二叉树。

详细描述:从根节点开始,将其放入队列中。

然后,循环执行以下步骤直到队列为空:取出队列头部的节点,访问该节点并打印它的值,将其左子节点和右子节点(如果存在)依次放入队列尾部。

5. 深度优先遍历(DFS):按照深度优先的顺序遍历二叉树。

详细描述:深度优先遍历可以使用递归或者栈来实现。

从根节点开始,首先访问根节点并打印它的值。

接着,递归地遍历左子树,并递归地遍历右子树。

6. 广度优先遍历(BFS):按照广度优先的顺序遍历二叉树。

详细描述:广度优先遍历使用队列来实现。

从根节点开始,首先将根节点放入队列中。

然后,开始循环,直到队列为空:取出队列头部的节点,访问该节点并打印它的值,将其左子节点和右子节点(如果存在)依次放入队列尾部。

7. 反序前序遍历:先访问右子树,再访问左子树,最后访问根节点。

详细描述:从根节点开始,首先递归遍历右子树。

然后,递归遍历左子树。

访问根节点并打印它的值。

8. 反序中序遍历:先遍历右子树,再访问根节点,最后遍历左子树。

详细描述:从根节点开始,首先递归遍历右子树。

然后,访问根节点并打印它的值。

递归遍历左子树。

9. 反序后序遍历:先访问根节点,再遍历右子树,最后遍历左子树。

详细描述:从根节点开始,首先访问根节点并打印它的值。

接着,递归地遍历右子树。

递归地遍历左子树。

二叉树遍历方法

二叉树遍历方法

二叉树遍历方法一、概述二叉树是一种重要的数据结构,它由节点(Node)组成,每个节点最多有两个孩子节点,分别称为左孩子和右孩子。

遍历二叉树是一种重要的操作,可以用于搜索或处理节点的数据。

本文主要介绍四种二叉树遍历方法:前序遍历、中序遍历、后序遍历和层次遍历,并对它们的特点、时间复杂度、以及实际应用做一个详细介绍。

二、前序遍历前序遍历是指,先访问根节点,再访问根节点的左子树,最后访问根节点的右子树。

具体步骤如下:1.访问根节点2.递归遍历左子树3.递归遍历右子树下面是前序遍历的时间复杂度:O(n),其中n表示节点的个数。

因为需要遍历每个节点一次。

前序遍历的应用场景比较广泛,主要用来复制一棵树。

例如我们需要复制一棵二叉树,只需要先创建一个新的节点,将原树的根节点值赋给新节点,再递归复制左子树和右子树即可。

三、中序遍历中序遍历是指,先访问根节点的左子树,再访问根节点,最后访问根节点的右子树。

具体步骤如下:1.递归遍历左子树2.访问根节点3.递归遍历右子树下面是中序遍历的时间复杂度:O(n),其中n表示节点的个数。

因为需要遍历每个节点一次。

中序遍历的应用场景比较少,但也有一些有用的应用。

例如我们有一棵二叉查找树,需要将它转化为排序后的数组。

只需要使用中序遍历,访问每个节点时将节点值存入数组,就可以得到一个排序后的数组。

四、后序遍历后序遍历是指,先访问根节点的左子树,再访问根节点的右子树,最后访问根节点。

具体步骤如下:1.递归遍历左子树2.递归遍历右子树3.访问根节点下面是后序遍历的时间复杂度:O(n),其中n表示节点的个数。

因为需要遍历每个节点一次。

后序遍历的应用场景比较少,但在树的某些操作中比如判断二叉树是否为平衡树时经常用到。

只有按照后序遍历来遍历二叉树,才能判断它是否为平衡树。

五、层次遍历层次遍历是指,从上到下,从左到右依次访问每个节点。

具体步骤如下:1.将根节点入队2.当队列不为空时,取出队头节点并访问3.将队头节点的左子树、右子树入队下面是层次遍历的时间复杂度:O(n),其中n表示节点的个数。

数据结构—树二叉树前序遍历、中序遍历、后序遍历【图解实现】

数据结构—树二叉树前序遍历、中序遍历、后序遍历【图解实现】

数据结构—树二叉树前序遍历、中序遍历、后序遍历【图解实现】AI研习图书馆,发现不一样的精彩世界数据结构二叉树的遍历一、树在谈二叉树的知识点之前,我们首先来看一下树和图的基本概念。

树:不包含回路的连通无向图,树是一种简单的非线性结构。

由于树有一个不包含回路的特点,因此树被赋予了许多特性,如下所示:1、一棵树中任意的两个结点有且仅有唯一的一条路径连通2、一棵树如果有n个结点,那么它一定恰好有n-1条边3、在一棵树中加上一条边,将会构成一个回路4、一棵树中有且仅有一个没有前驱的结点,即为根结点通常情况下,我们在对树进行讨论的时候,将一棵树中的每个点称为结点:根结点:没有父结点的结点叶结点:没有子结点的结点内部结点:一个结点既不是根结点也不是叶结点每个结点有一个深度的概念,例如上图左边的树,4号结点深度是3。

二、二叉树1. 基本概念二叉树是一种非线性结构,二叉树是由递归定义的,其结点有左右子树之分。

2. 二叉树的存储结构二叉树一般采用链式存储结构,存储结点由数据域和指针域组成,二叉树的链式存储结构也称为二叉链表。

指针域:左指针域和右指针域特点:1、每个结点最多有两颗子树2、左子树和右子树是有顺序的,次序不能颠倒3、即使某个结点只有一颗子树,也要区分左右子树4、二叉树可为空,空的二叉树没有结点,非空二叉树有且仅有一个根节点二叉树中有两种比较特殊的二叉树:满二叉树、完全二叉树,对于满二叉树和完全二叉树可以按照层次进行顺序存储。

满二叉树:二叉树中每个内部结点都存在左子树和右子树满二叉树一定是完全二叉树,但完全二叉树不一定是满二叉树。

满二叉树的严格定义:一颗深度为h且具有2h-1个结点的二叉树。

完全二叉树:解释一:如果一颗二叉树除了最右边位置上有一个或几个叶结点缺少外,其他都是丰满的,那么这样的二叉树就是完全二叉树。

解释二:除第h层外,其他各层(1到h-1)的结点数都达到最大个数,第h层从右向左连续缺若干结点,则这个二叉树就是完全二叉树。

二叉树遍历的递归实现详解(先序、中序、后序和层次遍历)

二叉树遍历的递归实现详解(先序、中序、后序和层次遍历)

⼆叉树遍历的递归实现详解(先序、中序、后序和层次遍历)由⼆叉树的定义可知,⼀棵⼆叉树由根结点、左⼦树和右⼦树三部分组成。

因此,只要遍历了这三个部分,就可以实现遍历整个⼆叉树。

若以D、L、R分别表⽰遍历根结点、左⼦树、右⼦树,则⼆叉树的递归遍历可以有⼀下四种⽅式:先序遍历(DLR)先序遍历的递归过程为(1)访问根结点(2)先序遍历根结点的左⼦树(3)先序遍历根结点的右⼦树举例:代码:void PreOrder(BiTree bt){if(bt ==NULL)return; //递归的结束条件----某结点为空时printf("%d",bt->data); //这⾥⽤printf data表⽰访问结点的数据域PreOrder(bt->lchild); //递归遍历左孩⼦PreOrder(bt->rclild); //递归遍历右孩⼦}中序遍历(LDR)(1)中序遍历根结点的左⼦树(2)访问根结点(3)中序遍历根结点的右⼦树举例:代码:void InOrder(BiTree bt){if(bt ==NULL)return; //递归的结束条件----某结点为空时InOrder(bt->lchild); //递归遍历左孩⼦printf("%d",bt->data); //这⾥⽤printf data表⽰访问结点的数据域InOrder(bt->rclild); //递归遍历右孩⼦}后序遍历(LRD)(1)后序遍历⼆叉树的左⼦树(2)后序遍历⼆叉树的右⼦树(3)访问根结点。

举例:代码:void PostOrder(BiTree bt){if(bt ==NULL)return; //递归的结束条件----某结点为空时PostOrder(bt->lchild); //递归遍历左孩⼦PostOrder(bt->rclild); //递归遍历右孩⼦printf("%d",bt->data); //这⾥⽤printf data表⽰访问结点的数据域}层次遍历(1)根结点⼊队列(2)根结点出队列,根结点的左⼦树、右⼦树相继⼊队列(3)根结点的左⼦树结点出队列,左⼦树结点的左⼦树、右⼦树相继⼊队列(4).......举例:代码://层次遍历⼆叉树void LevelOrder(BiTree T){BiTree Queue[MAX],b; //⽤⼀维数组表⽰队列,front和rear表⽰队⾸和队尾的指针int front,rear;front=rear=0;if(T)//若树为空{Queue[rear++]=T; //根节点⼊队列while(front!=rear) //当队列⾮空{b=Queue[front++]; //队⾸元素出队列,并访问这个节点printf("%2c",b->data);if(b->lchild!=NULL) Queue[rear++]=b->lchild ; //若左⼦树⾮空,则⼊队列if(b->rchild!=NULL) Queue[rear++]=b->rchild ; //若右⼦树⾮空,则⼊队列}}}最终代码:#include<stdio.h>#include<stdlib.h>#define MAX 20typedef char TElemType;typedef int Status;typedef struct BiTNode{TElemType data;struct BiTNode *lchild,*rchild; //左右孩⼦的指针} BiTNode,*BiTree;//先序创建⼆叉树void CreateBiTree(BiTree *T){char ch;ch=getchar();if(ch=='#')(*T)=NULL; //#代表空指针else{(*T)=(BiTree)malloc(sizeof(BiTNode)); //申请节点(*T)->data=ch; //⽣成跟节点CreateBiTree(&(*T)->lchild);CreateBiTree(&(*T)->rchild);}}//先序输出⼆叉树void PreOrder(BiTree T){if(T){printf("%2c",T->data); //访问根节点,此处为输出根节点的数据值PreOrder(T->lchild); //先序遍历左⼦树PreOrder(T->rchild); //先序遍历右⼦树}}//中序输出⼆叉树void InOrder(BiTree T){if(T){InOrder(T->lchild);printf("%2c",T->data);InOrder(T->rchild);}}//后序输出⼆叉树void PostOrder(BiTree T){if(T){PostOrder(T->lchild);PostOrder(T->rchild);printf("%2c",T->data);}}//层次遍历⼆叉树void LevelOrder(BiTree T){BiTree Queue[MAX],b; //⽤⼀维数组表⽰队列,front和rear表⽰队⾸和队尾的指针 int front,rear;front=rear=0;if(T)//若树为空{Queue[rear++]=T; //根节点⼊队列while(front!=rear) //当队列⾮空{b=Queue[front++]; //队⾸元素出队列,并访问这个节点printf("%2c",b->data);if(b->lchild!=NULL) Queue[rear++]=b->lchild ; //若左⼦树⾮空,则⼊队列if(b->rchild!=NULL) Queue[rear++]=b->rchild ; //若右⼦树⾮空,则⼊队列}}}//求树的深度int depth(BiTree T){int dep1,dep2;if(T==NULL) return 0;else{dep1=depth(T->lchild);dep2=depth(T->rchild);return dep1>dep2?dep1+1:dep2+1;}}int main(){BiTree T=NULL;printf("\n 创建⼀棵⼆叉树: \n");CreateBiTree(&T); //创建⼆叉树printf("\n先序遍历的结果为:\n");PreOrder(T); //先序遍历printf("\n中序遍历的结果为:\n");InOrder(T); //中序遍历printf("\n 后序遍历的结果为: \n");PostOrder(T);printf("\n 层次遍历的结果为: \n");LevelOrder(T); //层次遍历printf("\n 树的深度为:%d\n",depth(T));}结果⽰例:⼤家喜欢的话可以点个赞,有错误的地⽅请务必在评论区指出哟。

二叉树遍历大全

二叉树遍历大全

二叉树的前序遍历、中序遍历、后续遍历(包括递归、非递归,共六种)1、前序遍历(递归):算法实现一:#include <stdio.h>#include <stdlib.h>typedef struct BiTNode//定义结构体{char data;struct BiTNode *lchild,*rchild;}BiTNode,*BiTree;void CreateBiTree(BiTree &T) //前序创建树{char ch;scanf("%c",&ch);if(ch==' ') T=NULL;else{T=(struct BiTNode *)malloc(sizeof(struct BiTNode));T->data=ch;CreateBiTree(T->lchild);CreateBiTree(T->rchild);}}int print(BiTree T)//前序遍历(输出二叉树){if(T==NULL)return 0;else if(T->lchild==NULL && T->rchild==NULL)return 1;else return print(T->lchild)+print(T->rchild);}void main()//主函数{BiTree T;CreateBiTree(T);printf("%d\n",print(T));}算法实现二:#include<stdio.h>#include<stdlib.h>struct BiTNode//定义结构体{char data;struct BiTNode *lchild,*rchild;};int num=0;void CreatBiTree(struct BiTNode *&p) //前序创建树{char ch;scanf("%c",&ch);if(ch==' ') p=NULL;else{p=(struct BiTNode *)malloc(sizeof(struct BiTNode));p->data=ch;CreatBiTree(p->lchild);CreatBiTree(p->rchild);}}void print(struct BiTNode *p) //前序遍历(输出二叉树){if(p!=NULL){if(p->lchild==NULL&&p->rchild==NULL)else{print(p->lchild);print(p->rchild);}}}void main()//主函数{struct BiTNode *p;CreatBiTree(p);print(p);printf("%d\n",num);}#include<stdio.h>#include<stdlib.h>struct BiTNode//定义结构体{char data;struct BiTNode *lchild,*rchild;};void later(struct BiTNode *&p) //前序创建树{char ch;scanf("%c",&ch);if(ch==' ')p=NULL;else{p=(struct BiTNode *)malloc(sizeof(struct BiTNode));p->data=ch;later(p->lchild);later(p->rchild);}}void print(struct BiTNode *p) //中序遍历(输出二叉树){if(p!=NULL){print(p->lchild);printf("%c",p->data);print(p->rchild);}elseprintf(" ");}void main()//主函数{struct BiTNode *p;later(p);print(p);}#include<stdio.h>#include<stdlib.h>struct BiTNode//定义结构体{char data;struct BiTNode *lchild,*rchild;};void later(struct BiTNode *&p) //前序创建树{char ch;scanf("%c",&ch);if(ch==' ')p=NULL;else{p=(struct BiTNode *)malloc(sizeof(struct BiTNode));p->data=ch;later(p->lchild);later(p->rchild);}}void print(struct BiTNode *p) //后序遍历(输出二叉树){if(p!=NULL){print(p->lchild);print(p->rchild);printf("%c",p->data);}elseprintf(" ");}void main()//主函数{/*检测:printf("到了吗");*/struct BiTNode *p;later(p);print(p);}#include<stdio.h>#include<stdlib.h>struct BiTNode *stack[100];struct BiTNode//定义结构体{char data;struct BiTNode *lchild,*rchild;};void later(struct BiTNode *&p) //前序创建树{char ch;scanf("%c",&ch);if(ch==' ')p=NULL;else{p=(struct BiTNode *)malloc(sizeof(struct BiTNode));p->data=ch;later(p->lchild);later(p->rchild);}}void print(struct BiTNode *p) //前序遍历(输出二叉树){int i=-1;while(1){while(p!=NULL){stack[++i]=p->rchild;/*printf("ok?\n");*/printf("%c",p->data);p=p->lchild;}if(i!=-1){p=stack[i];i--;}elsereturn;}}void main()//主函数{struct BiTNode *p,*t;later(p);print(p);}5、中序遍历(非递归)#include<stdio.h>#include<stdlib.h>struct BiTNode *stack[100];struct BiTNode//定义结构体{char data;struct BiTNode *lchild,*rchild;};void later(struct BiTNode *&p) //前序创建树{char ch;scanf("%c",&ch);if(ch==' ')p=NULL;else{p=(struct BiTNode *)malloc(sizeof(struct BiTNode));p->data=ch;later(p->lchild);later(p->rchild);}}void print(struct BiTNode *p) //中序遍历(输出二叉树){int i=-1;while(1){while(p!=NULL){i++;stack[i]=p;p=p->lchild;}if(i!=-1){p=stack[i];i--;printf("%c",p->data);p=p->rchild;}}}void main()//主函数{struct BiTNode *p;later(p);print(p);}6、后续遍历(非递归):#include<stdio.h>#include<stdlib.h>struct BiTNode *stack[100];struct BiTNode//定义结构体{char data;struct BiTNode *lchild,*rchild;};void later(struct BiTNode *&p) //前序创建树{char ch;scanf("%c",&ch);if(ch==' ')p=NULL;else{p=(struct BiTNode *)malloc(sizeof(struct BiTNode));p->data=ch;later(p->lchild);later(p->rchild);}}void print(struct BiTNode *p) //后序遍历(输出二叉树){int i=-1;while(1){while(p!=NULL){stack[++i]=p;/*printf.0("ok?\n");*/p=p->lchild;}if(i!=-1){while(p==stack[i]->rchild||(p==stack[i]->lchild&&stack[i]->rchild==NULL)) {p=stack[i--];printf("%c",p->data);if(i==-1)return;}p=stack[i]->rchild;}elsereturn;}}int main()//主函数{struct BiTNode *p,*t;later(p);print(p);printf("\n");system("pause");return 0;}供测试使用的数据。

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

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

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

对应的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.先根序:根、左⼦树、右⼦树2.中根序:左⼦树、根、右孩⼦3.后根序:左⼦树、右⼦树、根现在通过⼀个例⼦来为,我让⼤家清晰了解们这三种遍历⽅法:对于这个⼆叉树来说:先根序遍历结果:A B D F G J C E H I中根序遍历结果:F D J G B A H E I C后根序遍历结果:F J G D B H I E C A现在我们来构造⼀个⼆叉树,然后对这个⼆叉树进⾏遍历操作:⾸先,我们按照我们之前博⽂中⼀直有的惯例,上⼿先编写"mec.h":#ifndef _MEC_H_#define _MEC_H_typedef unsigned char boolean;typedef boolean u8;#define TRUE 1#define FALSE 0#define NOT_FOUND -1#define SET(v, i) (v |= (1 << ((i) ^ 7)))#define CLR(v, i) (v &= ~(1 << ((i) ^ 7)))#define GET(v, i) (((v) & (1 << ((i) ^ 7))) != 0)#endif之后,我们再来构建⼆叉树“单节点”结构体:typedef struct BTREE {int data;struct BTREE *left;struct BTREE *right;}BTREE;那么,我们要构建⼆叉树,就要从键盘输⼊⼀个字符串,再读取字符串判断字符串输⼊是否合理,再根据正确的字符串构建⼆叉树。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验二二叉树的存储结构及各种运算的实现第一题:
#include "stdio.h"
#include "malloc.h"
#define maxsize 66
typedef int datatype;
typedef struct node
{
datatype data ;
struct node *lchild,*rchild;
} bitree;
bitree *Q[maxsize];
bitree *creatree()
{
char ch;
int front,rear;
bitree *root,*s;
root=NULL;
front=1;rear=0;
ch=getchar();
while (ch!='#')
{
s=NULL;
if(ch!='@')
{
s=malloc(sizeof(bitree));
s->data=ch;
s->lchild=NULL;
s->rchild=NULL;
}
rear++;
Q[rear]=s;
if(rear==1)
root=s;
else
{
if (s&&Q[front])
if(rear%2==0)
Q[front]->lchild=s;
else
Q[front]->rchild=s;
if(rear%2==1)
front++;
}
ch=getchar();
}
return root;
}
preorder(bitree *t) //前{
if (t)
{
printf(" %c ",t->data);
preorder(t->lchild);
preorder(t->rchild);
}
}
inorder(bitree *t) //中{
if (t)
{
inorder(t->lchild);
printf(" %c ",t->data);
inorder(t->rchild);
}
}
postorder(bitree *t) //后{
if (t)
{
postorder(t->lchild);
postorder(t->rchild);
printf(" %c ",t->data);
}
}
int height(bitree *t) //高度{
int hl,hr;
if(!t) return 0;
else
{
hl=height(t->lchild);
hr=height(t->rchild);
return ((hl>hr?hl:hr)+1);
}
}
int leaf(bitree *t) //叶子{
static int s;
if(t)
{
leaf(t->lchild);
leaf(t->rchild);
if(t->lchild==NULL&&t->rchild==NULL)
s=s+1;
}
return s;
}
main()
{
bitree *t;
int x,y;
printf("输入数据,以#做结尾:\n");
t=creatree();
printf("preorder:\t");preorder(t);
printf("\ninorder:\t");inorder(t);
printf("\npostorder:\t");postorder(t);
x=height(t);
y=leaf(t);
printf("\n高度:%d",x);
printf("\n叶子:%d",y);
printf("\n");
}
第二题:
#include <stdio.h>
#include <malloc.h>
#define maxsize 40
typedef struct node{
char data;
struct node *lchild,*rchild;
int ltag,rtag;
} bitree;
bitree *Q[maxsize]; /*队列*/
bitree *pre=NULL;
bitree *creatree()
{ char ch;
int front,rear; /*队头、队尾*/
bitree *root,*s;
root=NULL; /*空树*/
front=1; rear=0; /*空队*/
ch=getchar();
while(ch!='#')
{ s=NULL;
if(ch!='@') /*建立新结点*/
{ s=(bitree *)malloc(sizeof(bitree));
s->data=ch;
s->lchild=s->rchild=NULL;
s->ltag=s->rtag=0;
}
rear++;
Q[rear]=s; /*入队*/
if(rear==1) root=s;
else
{ if(s && Q[front]) /*孩子、双亲均非空*/
if(rear%2==0) Q[front]->lchild=s;
else Q[front]->rchild=s;
if(rear%2==1) front++; /*出队*/
}
ch=getchar();
}
return root;
}
//中序遍历;
void inorder(bitree *t)
{ if(t)
{ inorder(t->lchild);
printf("%c",t->data);
inorder(t->rchild);
}
}
//中序线索划;
void INTHREAD(bitree *p)
{if(p!=NULL)
{INTHREAD(p->lchild);
if(p->lchild==NULL) p->ltag=1;
if(p->rchild==NULL) p->rtag=1;
if(pre!=NULL)
{ if(pre->rtag==1) pre->rchild=p;
if(p->ltag==1) p->lchild=pre; } pre=p;
INTHREAD(p->rchild);
}
}
//中序线索二叉树中求中序后继结点;
bitree * inordernext (bitree *p)
{
bitree *q;
if(p->rtag==1) return p->rchild;
else
{ q=p->rchild;
while(q->ltag==0) q=q->lchild;
return q;
}
}
//中序遍历;
void traverseinthread(bitree *p)
{
if(p!=NULL)
{while (p->ltag==0 )
p=p->lchild;
do {printf("%c",p->data);
p=inordernext(p);
}while(p!=NULL);
}
}
void main()
{ bitree *t;
t=creatree();
printf("中序遍历结果是:\n:");
inorder(t);
printf("\n");
INTHREAD(t);
printf("线索化中序遍历的结果是:\n");
printf("\n");
traverseinthread(t);
printf("\n");}
输入数据为:abfcd@g@@e#。

相关文档
最新文档