二叉树采用链接存储方式存储,分别编写一个二叉树先序遍历的递归算法和非递归算法,用c语言实现

时间: 2023-05-11 16:04:46 浏览: 66
好的,以下是二叉树先序遍历的递归算法和非递归算法的C语言实现: 递归算法: ```c struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; }; void preorderTraversal(struct TreeNode* root){ if(root == NULL){ return; } printf("%d ", root->val); preorderTraversal(root->left); preorderTraversal(root->right); } ``` 非递归算法: ```c struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; }; void preorderTraversal(struct TreeNode* root){ if(root == NULL){ return; } struct TreeNode* stack[1000]; int top = -1; stack[++top] = root; while(top >= 0){ struct TreeNode* node = stack[top--]; printf("%d ", node->val); if(node->right != NULL){ stack[++top] = node->right; } if(node->left != NULL){ stack[++top] = node->left; } } } ``` 希望这个回答能够帮到你!

相关推荐

先序遍历的非递归算法可以通过使用栈来实现。具体步骤如下: 1. 创建一个栈,并将根节点入栈。 2. 当栈不为空时,执行以下操作: 1. 弹出栈顶节点并输出该节点的值。 2. 如果该节点的右子树非空,则将右子树入栈。 3. 如果该节点的左子树非空,则将左子树入栈。 3. 当栈为空时,遍历结束。 以下是C语言实现代码: c #include <stdio.h> #include <stdlib.h> #define MAXSIZE 100 // 定义二叉树结构体 typedef struct TreeNode { int data; struct TreeNode* left; struct TreeNode* right; } TreeNode; // 定义栈结构体 typedef struct Stack { TreeNode* data[MAXSIZE]; int top; } Stack; // 初始化栈 void initStack(Stack* s) { s->top = -1; } // 判断栈是否为空 int isEmpty(Stack* s) { return s->top == -1; } // 判断栈是否已满 int isFull(Stack* s) { return s->top == MAXSIZE - 1; } // 入栈 void push(Stack* s, TreeNode* node) { if (isFull(s)) { printf("Stack is full!\n"); return; } s->data[++(s->top)] = node; } // 出栈 TreeNode* pop(Stack* s) { if (isEmpty(s)) { printf("Stack is empty!\n"); return NULL; } return s->data[(s->top)--]; } // 先序遍历二叉树(非递归算法) void preOrder(TreeNode* root) { if (root == NULL) { return; } Stack s; initStack(&s); push(&s, root); while (!isEmpty(&s)) { TreeNode* cur = pop(&s); printf("%d ", cur->data); if (cur->right) { push(&s, cur->right); } if (cur->left) { push(&s, cur->left); } } } // 创建新节点 TreeNode* createNode(int data) { TreeNode* node = (TreeNode*)malloc(sizeof(TreeNode)); node->data = data; node->left = NULL; node->right = NULL; return node; } // 构建二叉树 TreeNode* buildTree() { TreeNode* root = createNode(1); root->left = createNode(2); root->right = createNode(3); root->left->left = createNode(4); root->left->right = createNode(5); root->right->left = createNode(6); root->right->right = createNode(7); return root; } int main() { TreeNode* root = buildTree(); preOrder(root); // 输出:1 2 4 5 3 6 7 return 0; }
好的,下面是二叉树的递归算法实现以及非递归算法实现: 1. 先序遍历递归算法实现: c void preOrderTraversal(TreeNode* root) { if (root == NULL) return; printf("%d ", root->val); preOrderTraversal(root->left); preOrderTraversal(root->right); } 2. 中序遍历递归算法实现: c void inOrderTraversal(TreeNode* root) { if (root == NULL) return; inOrderTraversal(root->left); printf("%d ", root->val); inOrderTraversal(root->right); } 3. 后序遍历递归算法实现: c void postOrderTraversal(TreeNode* root) { if (root == NULL) return; postOrderTraversal(root->left); postOrderTraversal(root->right); printf("%d ", root->val); } 4. 先序遍历非递归算法实现: c void preOrderTraversalNonRecursion(TreeNode* root) { if (root == NULL) return; TreeNode* stack[1000]; int top = -1; stack[++top] = root; while (top != -1) { TreeNode* node = stack[top--]; printf("%d ", node->val); if (node->right) stack[++top] = node->right; if (node->left) stack[++top] = node->left; } } 5. 中序遍历非递归算法实现: c void inOrderTraversalNonRecursion(TreeNode* root) { if (root == NULL) return; TreeNode* stack[1000]; int top = -1; TreeNode* node = root; while (node != NULL || top != -1) { while (node != NULL) { stack[++top] = node; node = node->left; } node = stack[top--]; printf("%d ", node->val); node = node->right; } } 6. 后序遍历非递归算法实现: c void postOrderTraversalNonRecursion(TreeNode* root) { if (root == NULL) return; TreeNode* stack1[1000]; TreeNode* stack2[1000]; int top1 = -1, top2 = -1; stack1[++top1] = root; while (top1 != -1) { TreeNode* node = stack1[top1--]; stack2[++top2] = node; if (node->left) stack1[++top1] = node->left; if (node->right) stack1[++top1] = node->right; } while (top2 != -1) { TreeNode* node = stack2[top2--]; printf("%d ", node->val); } } 7. 层次遍历算法实现: c void levelOrderTraversal(TreeNode* root) { if (root == NULL) return; TreeNode* queue[1000]; int front = 0, rear = 0; queue[rear++] = root; while (front < rear) { TreeNode* node = queue[front++]; printf("%d ", node->val); if (node->left) queue[rear++] = node->left; if (node->right) queue[rear++] = node->right; } } 注意:以上代码中的 TreeNode 结构体可以根据具体情况自行定义。
首先,我们需要定义二叉树的结构体: c typedef struct TreeNode { char data; // 二叉树结点的数据 struct TreeNode *leftChild; // 左子结点 struct TreeNode *rightChild; // 右子结点 } TreeNode, *Tree; 接下来,我们可以使用数组来存储二叉树的结点信息。假设我们使用一维数组来存储完全二叉树,那么对于数组中的第 i 个元素,它的左子结点为 2i,右子结点为 2i+1。 对于先序遍历,我们可以先访问根结点,再遍历左子树,最后遍历右子树。因此,我们可以使用递归的方式来实现先序遍历。具体来说,我们需要实现一个递归函数,该函数的参数包括当前遍历结点的下标、二叉树数组以及数组长度。 下面是基于这些思路的具体实现: c #include <stdio.h> // 二叉树结点的结构体 typedef struct TreeNode { char data; // 二叉树结点的数据 struct TreeNode *leftChild; // 左子结点 struct TreeNode *rightChild; // 右子结点 } TreeNode, *Tree; // 先序遍历 void preorderTraversal(int index, char tree[], int len) { if (index > len || tree[index] == '#') { return; } printf("%c ", tree[index]); // 访问当前结点 preorderTraversal(index * 2, tree, len); // 遍历左子树 preorderTraversal(index * 2 + 1, tree, len); // 遍历右子树 } int main() { char tree[] = {'#', 'A', 'B', 'C', '#', 'D', '#', '#', 'E', '#', '#', 'F', '#', '#', '#'}; int len = sizeof(tree) / sizeof(tree[0]); preorderTraversal(1, tree, len - 1); return 0; } 上述代码中,我们使用字符 '#' 表示空结点。我们以一棵完全二叉树为例,演示了如何使用数组来存储二叉树,并实现先序遍历。当然,这种方法并不适用于非完全二叉树。
假设二叉树的结点数据类型为ElemType,其中包含一个字符型成员变量data,则可以使用以下代码实现对二叉树的先序遍历: c #include <stdio.h> #include <stdlib.h> #define MAX_SIZE 100 // 定义二叉树的最大结点数 // 定义二叉树结点数据类型 typedef struct BiTNode { char data; // 数据域 } BiTNode, *BiTree; // 创建二叉树 void createBiTree(BiTree *T, char *data, int *index) { char ch = data[*index]; (*index)++; if (ch == '#') { // 空结点 *T = NULL; } else { *T = (BiTree)malloc(sizeof(BiTNode)); // 创建新结点 (*T)->data = ch; createBiTree(&((*T)->lchild), data, index); // 递归创建左子树 createBiTree(&((*T)->rchild), data, index); // 递归创建右子树 } } // 先序遍历二叉树 void preOrderTraverse(BiTree T) { if (T != NULL) { printf("%c ", T->data); // 输出结点数据 preOrderTraverse(T->lchild); // 递归遍历左子树 preOrderTraverse(T->rchild); // 递归遍历右子树 } } int main() { char data[MAX_SIZE]; // 存储二叉树结点数据的数组 int n; // 二叉树结点数 printf("请输入二叉树的结点数:"); scanf("%d", &n); printf("请输入二叉树的结点数据(以先序遍历的顺序输入,空结点用#表示):"); for (int i = 0; i < n; i++) { scanf(" %c", &data[i]); } BiTree T = NULL; // 定义二叉树的根节点 int index = 0; // 二叉树结点数据的数组下标 createBiTree(&T, data, &index); // 创建二叉树 printf("先序遍历序列为:"); preOrderTraverse(T); // 先序遍历二叉树并输出序列 printf("\n"); return 0; } 在上述代码中,我们首先定义了二叉树结点的数据类型BiTNode,包含一个字符型数据域data。然后定义了一个指向BiTNode类型的指针BiTree,用来表示二叉树结点。接着,我们使用createBiTree函数创建了一个二叉树,该函数的输入参数包括指向二叉树根节点的指针T、二叉树结点数据的数组data,以及下标index,该函数使用递归的方式创建二叉树,并在遇到空结点时将其置为NULL。最后,我们使用preOrderTraverse函数对二叉树进行先序遍历,并输出遍历序列。
先序遍历的非递归实现: c void preOrderTraversal(BiTree root) { if (root == NULL) { return; } Stack stack; initStack(&stack); push(&stack, root); while (!isEmptyStack(&stack)) { BiTree node = pop(&stack); printf("%d ", node->data); if (node->rchild != NULL) { push(&stack, node->rchild); } if (node->lchild != NULL) { push(&stack, node->lchild); } } } 层序遍历的非递归实现: c void levelOrderTraversal(BiTree root) { if (root == NULL) { return; } Queue queue; initQueue(&queue); enqueue(&queue, root); while (!isEmptyQueue(&queue)) { BiTree node = dequeue(&queue); printf("%d ", node->data); if (node->lchild != NULL) { enqueue(&queue, node->lchild); } if (node->rchild != NULL) { enqueue(&queue, node->rchild); } } } 下面给出一组数据作为示例: 1 / \ 2 3 / \ / \ 4 5 6 7 对应的二叉树可以用以下代码构建: c BiTree createTree() { BiTree root = (BiTree)malloc(sizeof(TreeNode)); root->data = 1; root->lchild = (BiTree)malloc(sizeof(TreeNode)); root->lchild->data = 2; root->rchild = (BiTree)malloc(sizeof(TreeNode)); root->rchild->data = 3; root->lchild->lchild = (BiTree)malloc(sizeof(TreeNode)); root->lchild->lchild->data = 4; root->lchild->rchild = (BiTree)malloc(sizeof(TreeNode)); root->lchild->rchild->data = 5; root->rchild->lchild = (BiTree)malloc(sizeof(TreeNode)); root->rchild->lchild->data = 6; root->rchild->rchild = (BiTree)malloc(sizeof(TreeNode)); root->rchild->rchild->data = 7; return root; } 使用先序遍历和层序遍历函数,对以上二叉树进行遍历,输出结果如下: 先序遍历:1 2 4 5 3 6 7 层序遍历:1 2 3 4 5 6 7

最新推荐

高层住宅应急照明系统方案.dwg

高层住宅应急照明系统方案.dwg

php_phpMyAdmin v4.4.10.zip.zip

php_phpMyAdmin v4.4.10.zip.zip

matlab基础编程:11 matlab脚本文件和函数文件.zip

matlab基础编程:11 matlab脚本文件和函数文件.zip

生产产线监控大屏系统去

生产产线监控大屏系统去

代码随想录最新第三版-最强八股文

这份PDF就是最强⼋股⽂! 1. C++ C++基础、C++ STL、C++泛型编程、C++11新特性、《Effective STL》 2. Java Java基础、Java内存模型、Java面向对象、Java集合体系、接口、Lambda表达式、类加载机制、内部类、代理类、Java并发、JVM、Java后端编译、Spring 3. Go defer底层原理、goroutine、select实现机制 4. 算法学习 数组、链表、回溯算法、贪心算法、动态规划、二叉树、排序算法、数据结构 5. 计算机基础 操作系统、数据库、计算机网络、设计模式、Linux、计算机系统 6. 前端学习 浏览器、JavaScript、CSS、HTML、React、VUE 7. 面经分享 字节、美团Java面、百度、京东、暑期实习...... 8. 编程常识 9. 问答精华 10.总结与经验分享 ......

低秩谱网络对齐的研究

6190低秩谱网络对齐0HudaNassar计算机科学系,普渡大学,印第安纳州西拉法叶,美国hnassar@purdue.edu0NateVeldt数学系,普渡大学,印第安纳州西拉法叶,美国lveldt@purdue.edu0Shahin Mohammadi CSAILMIT & BroadInstitute,马萨诸塞州剑桥市,美国mohammadi@broadinstitute.org0AnanthGrama计算机科学系,普渡大学,印第安纳州西拉法叶,美国ayg@cs.purdue.edu0David F.Gleich计算机科学系,普渡大学,印第安纳州西拉法叶,美国dgleich@purdue.edu0摘要0网络对齐或图匹配是在网络去匿名化和生物信息学中应用的经典问题,存在着各种各样的算法,但对于所有算法来说,一个具有挑战性的情况是在没有任何关于哪些节点可能匹配良好的信息的情况下对齐两个网络。在这种情况下,绝大多数有原则的算法在图的大小上要求二次内存。我们展示了一种方法——最近提出的并且在理论上有基础的EigenAlig

怎么查看测试集和训练集标签是否一致

### 回答1: 要检查测试集和训练集的标签是否一致,可以按照以下步骤进行操作: 1. 首先,加载训练集和测试集的数据。 2. 然后,查看训练集和测试集的标签分布情况,可以使用可视化工具,例如matplotlib或seaborn。 3. 比较训练集和测试集的标签分布,确保它们的比例是相似的。如果训练集和测试集的标签比例差异很大,那么模型在测试集上的表现可能会很差。 4. 如果发现训练集和测试集的标签分布不一致,可以考虑重新划分数据集,或者使用一些数据增强或样本平衡技术来使它们更加均衡。 ### 回答2: 要查看测试集和训练集标签是否一致,可以通过以下方法进行比较和验证。 首先,

数据结构1800试题.pdf

你还在苦苦寻找数据结构的题目吗?这里刚刚上传了一份数据结构共1800道试题,轻松解决期末挂科的难题。不信?你下载看看,这里是纯题目,你下载了再来私信我答案。按数据结构教材分章节,每一章节都有选择题、或有判断题、填空题、算法设计题及应用题,题型丰富多样,共五种类型题目。本学期已过去一半,相信你数据结构叶已经学得差不多了,是时候拿题来练练手了,如果你考研,更需要这份1800道题来巩固自己的基础及攻克重点难点。现在下载,不早不晚,越往后拖,越到后面,你身边的人就越卷,甚至卷得达到你无法想象的程度。我也是曾经遇到过这样的人,学习,练题,就要趁现在,不然到时你都不知道要刷数据结构题好还是高数、工数、大英,或是算法题?学完理论要及时巩固知识内容才是王道!记住!!!下载了来要答案(v:zywcv1220)。

PixieDust:静态依赖跟踪实现的增量用户界面渲染

7210PixieDust:通过静态依赖跟踪进行声明性增量用户界面渲染0Nick tenVeen荷兰代尔夫特理工大学,代尔夫特,荷兰n.tenveen@student.tudelft.nl0Daco C.Harkes荷兰代尔夫特理工大学,代尔夫特,荷兰d.c.harkes@tudelft.nl0EelcoVisser荷兰代尔夫特理工大学,代尔夫特,荷兰e.visser@tudelft.nl0摘要0现代Web应用程序是交互式的。反应式编程语言和库是声明性指定这些交互式应用程序的最先进方法。然而,使用这些方法编写的程序由于效率原因包含容易出错的样板代码。在本文中,我们介绍了PixieDust,一种用于基于浏览器的应用程序的声明性用户界面语言。PixieDust使用静态依赖分析在运行时增量更新浏览器DOM,无需样板代码。我们证明PixieDust中的应用程序包含的样板代码比最先进的方法少,同时实现了相当的性能。0ACM参考格式:Nick ten Veen,Daco C. Harkes和EelcoVisser。2018。通过�

pyqt5 QCalendarWidget的事件

### 回答1: PyQt5中的QCalendarWidget控件支持以下事件: 1. selectionChanged:当用户选择日期时触发该事件。 2. activated:当用户双击日期或按Enter键时触发该事件。 3. clicked:当用户单击日期时触发该事件。 4. currentPageChanged:当用户导航到日历的不同页面时触发该事件。 5. customContextMenuRequested:当用户右键单击日历时触发该事件。 您可以使用QCalendarWidget的connect方法将这些事件与自定义槽函数连接起来。例如,以下代码演示了如何将selectionC