C语言实现二叉树的前序遍历(递归)
数据结构c语言课设-二叉树排序

题目:二叉排序树的实现1 内容和要求1)编程实现二叉排序树,包括生成、插入,删除;2)对二叉排序树进展先根、中根、和后根非递归遍历;3)每次对树的修改操作和遍历操作的显示结果都需要在屏幕上用树的形状表示出来。
4)分别用二叉排序树和数组去存储一个班(50 人以上)的成员信息(至少包括学号、姓名、成绩3 项),比照查找效率,并说明在什么情况下二叉排序树效率高,为什么?2 解决方案和关键代码2.1 解决方案:先实现二叉排序树的生成、插入、删除,编写DisplayBST函数把遍历结果用树的形状表示出来。
前中后根遍历需要用到栈的数据构造,分模块编写栈与遍历代码。
要求比照二叉排序树和数组的查找效率,首先建立一个数组存储一个班的成员信息,分别用二叉树和数组查找,利用clock〔〕函数记录查找时间来比照查找效率。
2.2关键代码树的根本构造定义及根本函数typedef struct{KeyType key;} ElemType;typedef struct BiTNode//定义链表{ElemType data;struct BiTNode *lchild, *rchild;}BiTNode, *BiTree, *SElemType;//销毁树int DestroyBiTree(BiTree &T){if (T != NULL)free(T);return 0;}//清空树int ClearBiTree(BiTree &T){if (T != NULL){T->lchild = NULL;T->rchild = NULL;T = NULL;}return 0;}//查找关键字,指针p返回int SearchBST(BiTree T, KeyType key, BiTree f, BiTree &p) {if (!T){p = f;return FALSE;}else if EQ(key, T->data.key){p = T;return TRUE;}else if LT(key, T->data.key)return SearchBST(T->lchild, key, T, p);elsereturn SearchBST(T->rchild, key, T, p);}二叉树的生成、插入,删除生成void CreateBST(BiTree &BT, BiTree p){int i;ElemType k;printf("请输入元素值以创立排序二叉树:\n");scanf_s("%d", &k.key);for (i = 0; k.key != NULL; i++){//判断是否重复if (!SearchBST(BT, k.key, NULL, p)){InsertBST(BT, k);scanf_s("%d", &k.key);}else{printf("输入数据重复!\n");return;}}}插入int InsertBST(BiTree &T, ElemType e){BiTree s, p;if (!SearchBST(T, e.key, NULL, p)){s = (BiTree)malloc(sizeof(BiTNode));s->data = e;s->lchild = s->rchild = NULL;if (!p)T = s;else if LT(e.key, p->data.key)p->lchild = s;elsep->rchild = s;return TRUE;}else return FALSE;}删除//某个节点元素的删除int DeleteEle(BiTree &p){BiTree q, s;if (!p->rchild) //右子树为空{q = p;p = p->lchild;free(q);}else if (!p->lchild) //左子树为空{q = p;p = p->rchild;free(q);}else{q = p;s = p->lchild;while (s->rchild){q = s;s = s->rchild;}p->data = s->data;if (q != p)q->rchild = s->lchild;elseq->lchild = s->lchild;delete s;}return TRUE;}//整棵树的删除int DeleteBST(BiTree &T, KeyType key) //实现二叉排序树的删除操作{if (!T){return FALSE;}else{if (EQ(key, T->data.key)) //是否相等return DeleteEle(T);else if (LT(key, T->data.key)) //是否小于return DeleteBST(T->lchild, key);elsereturn DeleteBST(T->rchild, key);}return 0;}二叉树的前中后根遍历栈的定义typedef struct{SElemType *base;SElemType *top;int stacksize;}SqStack;int InitStack(SqStack &S) //构造空栈{S.base = (SElemType*)malloc(STACK_INIT_SIZE *sizeof(SElemType));if (!S.base) exit(OVERFLOW);S.top = S.base;S.stacksize = STACK_INIT_SIZE;return OK;}//InitStackint Push(SqStack &S, SElemType e) //插入元素e为新栈顶{if (S.top - S.base >= S.stacksize){S.base = (SElemType*)realloc(S.base, (S.stacksize + STACKINCREMENT)*sizeof(SElemType));if (!S.base) exit(OVERFLOW);S.top = S.base + S.stacksize;S.stacksize += STACKINCREMENT;}*S.top++ = e;return OK;}//Pushint Pop(SqStack &S, SElemType &e) //删除栈顶,应用e返回其值{if (S.top == S.base) return ERROR;e = *--S.top;return OK;}//Popint StackEmpty(SqStack S) //判断是否为空栈{if (S.base == S.top) return TRUE;return FALSE;}先根遍历int PreOrderTraverse(BiTree T, int(*Visit)(ElemType e)) {SqStack S;BiTree p;InitStack(S);p = T;while (p || !StackEmpty(S)){if (p){Push(S, p);if (!Visit(p->data)) return ERROR;p = p->lchild;}else{Pop(S, p);p = p->rchild;}}return OK;}中根遍历int InOrderTraverse(BiTree T, int(*Visit)(ElemType e)) {SqStack S;BiTree p;InitStack(S);p = T;while (p || !StackEmpty(S)){if (p){Push(S, p);p = p->lchild;}else{Pop(S, p);if (!Visit(p->data)) return ERROR;p = p->rchild;}}return OK;}后根遍历int PostOrderTraverse(BiTree T, int(*Visit)(ElemType e)) {SqStack S, SS;BiTree p;InitStack(S);InitStack(SS);p = T;while (p || !StackEmpty(S)){if (p){Push(S, p);Push(SS, p);p = p->rchild;}else{if (!StackEmpty(S)){Pop(S, p);p = p->lchild;}}}while (!StackEmpty(SS)){Pop(SS, p);if (!Visit(p->data)) return ERROR;}return OK;}利用数组存储一个班学生信息ElemType a[] = { 51, "陈继真", 88,82, "黄景元", 89,53, "贾成", 88,44, "呼颜", 90,25, "鲁修德", 88,56, "须成", 88,47, "孙祥", 87, 38, "柏有患", 89, 9, " 革高", 89, 10, "考鬲", 87, 31, "李燧", 86, 12, "夏祥", 89, 53, "余惠", 84, 4, "鲁芝", 90, 75, "黄丙庆", 88, 16, "李应", 89, 87, "杨志", 86, 18, "李逵", 89, 9, "阮小五", 85, 20, "史进", 88, 21, "秦明", 88, 82, "杨雄", 89, 23, "刘唐", 85, 64, "武松", 88, 25, "李俊", 88, 86, "卢俊义", 88, 27, "华荣", 87, 28, "杨胜", 88, 29, "林冲", 89, 70, "李跃", 85, 31, "蓝虎", 90, 32, "宋禄", 84, 73, "鲁智深", 89, 34, "关斌", 90, 55, "龚成", 87, 36, "黄乌", 87, 57, "孔道灵", 87, 38, "张焕", 84, 59, "李信", 88, 30, "徐山", 83, 41, "秦祥", 85, 42, "葛公", 85, 23, "武衍公", 87, 94, "范斌", 83, 45, "黄乌", 60, 67, "叶景昌", 99, 7, "焦龙", 89, 78, "星姚烨", 85, 49, "孙吉", 90, 60, "陈梦庚", 95,};数组查询函数void ArraySearch(ElemType a[], int key, int length){int i;for (i = 0; i <= length; i++){if (key == a[i].key){cout << "学号:" << a[i].key << " 姓名:" << a[i].name << " 成绩:" << a[i].grade << endl;break;}}}二叉树查询函数上文二叉树根本函数中的SearchBST()即为二叉树查询函数。
数据结构(二十四)二叉树的链式存储结构(二叉链表)

数据结构(⼆⼗四)⼆叉树的链式存储结构(⼆叉链表) ⼀、⼆叉树每个结点最多有两个孩⼦,所以为它设计⼀个数据域和两个指针域,称这样的链表叫做⼆叉链表。
⼆、结点结构包括:lchild左孩⼦指针域、data数据域和rchild右孩⼦指针域。
三、⼆叉链表的C语⾔代码实现:#include "string.h"#include "stdio.h"#include "stdlib.h"#include "io.h"#include "math.h"#include "time.h"#define OK 1#define ERROR 0#define TRUE 1#define FALSE 0#define MAXSIZE 100 /* 存储空间初始分配量 */typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 *//* ⽤于构造⼆叉树********************************** */int index=1;typedef char String[24]; /* 0号单元存放串的长度 */String str;Status StrAssign(String T,char *chars){int i;if(strlen(chars)>MAXSIZE)return ERROR;else{T[0]=strlen(chars);for(i=1;i<=T[0];i++)T[i]=*(chars+i-1);return OK;}}/* ************************************************ */typedef char TElemType;TElemType Nil=''; /* 字符型以空格符为空 */Status visit(TElemType e){printf("%c ",e);return OK;}typedef struct BiTNode /* 结点结构 */{TElemType data; /* 结点数据 */struct BiTNode *lchild,*rchild; /* 左右孩⼦指针 */}BiTNode,*BiTree;/* 构造空⼆叉树T */Status InitBiTree(BiTree *T){*T=NULL;return OK;}/* 初始条件: ⼆叉树T存在。
二叉树遍历(前序、中序、后序、层次、广度优先、深度优先遍历)

⼆叉树遍历(前序、中序、后序、层次、⼴度优先、深度优先遍历)⽬录转载:⼆叉树概念⼆叉树是⼀种⾮常重要的数据结构,⾮常多其他数据结构都是基于⼆叉树的基础演变⽽来的。
对于⼆叉树,有深度遍历和⼴度遍历,深度遍历有前序、中序以及后序三种遍历⽅法,⼴度遍历即我们寻常所说的层次遍历。
由于树的定义本⾝就是递归定义,因此採⽤递归的⽅法去实现树的三种遍历不仅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语言递归生成二叉树探讨

@
~
,
saf” ” ) cr(%c, ; &c
c=tr n t rtm U L = e ae eu N L mi )
es le
t 、
‘
.
(
霞
。
蹶 。
≮ 。
■‘ 、
ro=B o e) l cs ef N d) ot(N d ma o(zo( o e ; l i B )
2二 叉 树 递 归 生 成 .
可 以利 用二 叉树 基本 性 质 . 即从 根 结点 开始 。 断 不 给 当前 叶子结点 添加左 、 右新 的子 结 点 , 成整 棵完 整 生 的二叉树 。这里 , 以前序 递归 方法 为例来 介绍 。需要 注 意 的是输 入时按先 序遍 历次 序输入 二 叉树 中结 点 的字 符值 . 同时要 把左 右子树 为空 的结 点也 要表 示 出来 , 该 文用 、 表 示空树 。 下面 给 出几 种 C语 言实 现方案 : 使用 的宏 定 义 :
# e n t r n t d f e e mi a e i
# e n OK df e i 1
# e i e ERROR d fn 0
方法 1 :
B re c t( Te  ̄ac )(
BT e o t NUL rero= L:
c a ; h c r源自④ : 法。 【 关键词 】 二 叉树 ; : C语 言 ; 归 递
1 引言 .
二 叉树 是一 种基 本 的非 线性 数据 结构 .二叉 链 表 是 其常用 的存储形 式 。用 二 叉链 表实 现生 成二 叉树 的 算 法 比较多 .其 中递归 生成 及递 归遍 历二叉 树 属 于二 叉 树的基本 操作 。 目前无 论在 教学或 实用 使用 中 , 大都 采 用 C、 + 或 C C+ #编 程实 现 ,其 中用 面 向过程 基 本 C 语 言编程属 于重要 的基本 实现 方法 。该 文在 基 于基本 C语 言 环 境 下 对 实现 生 成 二 叉 树 及 遍 历 进 行 一 些 探
数据结构c语言版第三版习题解答

数据结构c语言版第三版习题解答数据结构 C 语言版第三版习题解答在学习计算机科学与技术的过程中,数据结构是一门非常重要的基础课程。
而《数据结构C 语言版第三版》更是众多教材中的经典之作。
其中的习题对于我们理解和掌握数据结构的概念、原理以及算法实现起着至关重要的作用。
接下来,我将为大家详细解答这本书中的一些典型习题。
首先,让我们来看一道关于线性表的习题。
题目是这样的:设计一个算法,从一个有序的线性表中删除所有其值重复的元素,使表中所有元素的值均不同。
对于这道题,我们可以采用双指针的方法来解决。
定义两个指针 p和 q,p 指向线性表的开头,q 从 p 的下一个位置开始。
当 q 所指向的元素与 p 所指向的元素相同时,我们就将 q 所指向的元素删除,并将 q 向后移动一位。
当 q 所指向的元素与 p 所指向的元素不同时,我们将 p 向后移动一位,并将 q 所指向的元素赋值给 p 所指向的位置,然后再将 q 向后移动一位。
当 q 超出线性表的范围时,算法结束。
下面是用 C 语言实现的代码:```cvoid removeDuplicates(int arr, int n) {int p = 0, q = 1;while (q < n) {if (arrp == arrq) {for (int i = q; i < n 1; i++){arri = arri + 1;}(n);} else {p++;arrp = arrq;}q++;}}```再来看一道关于栈的习题。
题目是:利用栈实现将一个十进制数转换为八进制数。
我们知道,将十进制数转换为八进制数可以通过不断除以 8 取余数的方法来实现。
而栈的特点是后进先出,正好适合存储这些余数。
以下是 C 语言实现的代码:```cinclude <stdioh>include <stdlibh>define MAX_SIZE 100typedef struct {int top;int dataMAX_SIZE;} Stack;//初始化栈void initStack(Stack s) {s>top =-1;}//判断栈是否为空int isEmpty(Stack s) {return s>top ==-1;}//判断栈是否已满int isFull(Stack s) {return s>top == MAX_SIZE 1;}//入栈操作void push(Stack s, int element) {if (isFull(s)){printf("Stack Overflow!\n");return;}s>data++s>top = element;}//出栈操作int pop(Stack s) {if (isEmpty(s)){printf("Stack Underflow!\n");return -1;}return s>datas>top;}//将十进制转换为八进制void decimalToOctal(int decimal) {Stack s;initStack(&s);while (decimal!= 0) {push(&s, decimal % 8);decimal /= 8;}while (!isEmpty(&s)){printf("%d", pop(&s));}printf("\n");}int main(){int decimal;printf("请输入一个十进制数: ");scanf("%d",&decimal);printf("转换后的八进制数为: ");decimalToOctal(decimal);return 0;}```接下来是一道关于队列的习题。
二叉树先序遍历算法

二叉树先序遍历算法
二叉树先序遍历是一种树的遍历算法,先序遍历过程如下:
1. 先访问根节点;
2. 再访问左子节点;
3. 再访问右子节点;
二叉树先序遍历是一种树状数据结构的深度优先搜索(DFS)算法。
先序遍历对
树状数据结构中的每个节点仅进行一次访问,且访问的次序是从上到下,从左到右的方式。
先序遍历属于深度优先搜索,它以一定的次序访问树或图的每个节点,然后递归访问其子节点,深度优先搜索可以按一定方式去遍历有向图、二叉树等数据结构,对节点都进行一定次序的编号或标签,访问顺序是按从小到大的顺序,从而把BST全部访问一次。
二叉树先序遍历的时间复杂度为O(n),空间复杂度为O(logn),应用范围很广,常用于二叉查找树的构造或查找、求树的高度和深度、树的前中后序遍历等,其中在建立二叉查找树时,往往我们都会使用先序遍历;同时,也可用先序遍历来求二叉树的节点数,计算树的深度等。
因此,二叉树先序遍历是一种基本而又重要的数据结构遍历算法,在许多应用
场景中都可以被朂泛使用,深受各个计算机领域的热捧。
二叉树遍历(前中后序遍历,三种方式)

⼆叉树遍历(前中后序遍历,三种⽅式)⽬录刷题中碰到⼆叉树的遍历,就查找了⼆叉树遍历的⼏种思路,在此做个总结。
对应的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)的空间复杂度。
c语言二叉树的先序,中序,后序遍历

c语言二叉树的先序,中序,后序遍历1、先序遍历先序遍历可以想象为,一个小人从一棵二叉树根节点为起点,沿着二叉树外沿,逆时针走一圈回到根节点,路上遇到的元素顺序,就是先序遍历的结果先序遍历结果为:A B D H I E J C F K G2、中序遍历中序遍历可以看成,二叉树每个节点,垂直方向投影下来(可以理解为每个节点从最左边开始垂直掉到地上),然后从左往右数,得出的结果便是中序遍历的结果中遍历结果为:H D I B E J A F K C G3、后序遍历后序遍历就像是剪葡萄,我们要把一串葡萄剪成一颗一颗的。
还记得我上面提到先序遍历绕圈的路线么?(不记得翻上面理解)就是围着树的外围绕一圈,如果发现一剪刀就能剪下的葡萄(必须是一颗葡萄)(也就是葡萄要一个一个掉下来,不能一口气掉超过1个这样),就把它剪下来,组成的就是后序遍历了。
后序遍历中,根节点默认最后面后序遍历结果:H I D J E B K F G C A4、口诀先序遍历:先根再左再右中序遍历:先左再根再右后序遍历:先左再右再根这里的根,指的是每个分叉子树(左右子树的根节点)根节点,并不只是最开始头顶的根节点,需要灵活思考理解5、代码展示#include<stdio.h>#include<stdlib.h>typedef struct Tree{int data; // 存放数据域struct Tree *lchild; // 遍历左子树指针struct Tree *rchild; // 遍历右子树指针}Tree,*BitTree;BitTree CreateLink(){int data;int temp;BitTree T;scanf("%d",&data); // 输入数据temp=getchar(); // 吸收空格if(data == -1){ // 输入-1 代表此节点下子树不存数据,也就是不继续递归创建return NULL;}else{T = (BitTree)malloc(sizeof(Tree)); // 分配内存空间T->data = data; // 把当前输入的数据存入当前节点指针的数据域中printf("请输入%d的左子树: ",data);T->lchild = CreateLink(); // 开始递归创建左子树printf("请输入%d的右子树: ",data);T->rchild = CreateLink(); // 开始到上一级节点的右边递归创建左右子树return T; // 返回根节点}}// 先序遍历void ShowXianXu(BitTree T) // 先序遍历二叉树{if(T==NULL) //递归中遇到NULL,返回上一层节点{return;}printf("%d ",T->data);ShowXianXu(T->lchild); // 递归遍历左子树ShowXianXu(T->rchild); // 递归遍历右子树}// 中序遍历void ShowZhongXu(BitTree T) // 先序遍历二叉树{if(T==NULL) //递归中遇到NULL,返回上一层节点{return;}ShowZhongXu(T->lchild); // 递归遍历左子树printf("%d ",T->data);ShowZhongXu(T->rchild); // 递归遍历右子树}// 后序遍历void ShowHouXu(BitTree T) // 后序遍历二叉树{if(T==NULL) //递归中遇到NULL,返回上一层节点{return;}ShowHouXu(T->lchild); // 递归遍历左子树ShowHouXu(T->rchild); // 递归遍历右子树printf("%d ",T->data);}int main(){BitTree S;printf("请输入第一个节点的数据:\n");S = CreateLink(); // 接受创建二叉树完成的根节点printf("先序遍历结果: \n");ShowXianXu(S); // 先序遍历二叉树printf("\n中序遍历结果: \n");ShowZhongXu(S); // 中序遍历二叉树printf("\n后序遍历结果: \n");ShowHouXu(S); // 后序遍历二叉树return 0;}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
C语言实现二叉树的前序遍历算法实现一:
#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);
}
供测试使用的数据。