赞
踩
目录
对于二叉树的非递归 深度优先遍历,使用的都是栈
对于二叉树的层次遍历,使用的是队列
依据前序遍历创建二叉树:,树结构如上图所示
输入: ABD##E##C##
- #include <stdio.h>
- #include <stdlib.h>
-
-
- // 二叉树的实现
-
- // 定义 二叉树的 结构体
- typedef struct node{
- char data;
- struct node *left;
- struct node *right;
- }Node, *Tree;
-
- // 依据前序遍历创建二叉树
- // 根左右: ABD##E##C##
-
- Tree create_tree(){
- Node *root = NULL;
- char ch;
- scanf("%c", &ch); // 输入 ABD##E##C##
-
- if (ch != '#'){
- root = (Node*)malloc(sizeof(Node));
- root->data = ch;
-
- root->left = create_tree(); // 递归创建
- root->right = create_tree();
- }
- else{
- root = NULL;
- }
-
- return root;
- }
- // 递归前序遍历二叉树
- void preOrderRec(Tree root){
- if (root != NULL){
- printf(" %c - ", root->data);
- preOrderRec(root->left);
- preOrderRec(root->right);
- }
- }
- // 递归中序遍历二叉树
- void inOrderRec(Tree root){
- if (root != NULL){
- inOrderRec(root->left);
- printf(" %c - ", root->data);
- inOrderRec(root->right);
- }
- }
- void backOrderRec(Tree root){
- if (root != NULL){
- backOrderRec(root->left);
- backOrderRec(root->right);
- printf(" %c - ", root->data);
-
- }
- }
- int main(){
-
- printf("starting ------ \n");
-
-
- Tree root = create_tree();
- printf("递归前序遍历--- \n");
- preOrderRec(root);
- printf("\n");
- printf("递归中序遍历--- \n");
- inOrderRec(root);
- printf("\n");
- printf("递归后序遍历--- \n");
- backOrderRec(root);
- printf("\n");
-
-
-
-
- return 0;
- }
前序遍历顺序是:根-左-右
先打印根节点的值,由于栈是先进后出,所以先将 右子树放进去,再将左子树放进去
- // 非-递归前序遍历二叉树
- void preOrderNRec(Tree root){
- Tree stack[MAXSIZE], node;
- int k = -1;
-
- if (root == NULL){
- printf("tree is empty-- \n");
- return;
- }
- else{
- k++;
- // 仿照一个栈
- stack[k] = root; // 将根节点入栈
- while (k > -1){
- //出栈
- node = stack[k--];
- printf(" %c - ", node->data);
-
- // 先把右子树放进去,栈是先进去后出,所以下面的左子树先出
- if (node->right != NULL){
- stack[++k] = node->right;
- }
- if (node->left != NULL){
- stack[++k] = node->left;
- }
-
- }
-
- }
- }
中序遍历的非递归方式实现思想是:
1. 从根结点开始,遍历左孩子同时压栈,当遍历结束,说明当前遍历的结点没有左孩子,
2. 从栈中取出来调用操作函数,然后访问该结点的右孩子,继续以上重复性的操作。
- // 非-递归实现中序遍历二叉树
- void inOrderNRec(Tree root){
- Tree stack[MAXSIZE], node;
- int top = 0;
- // 判断树是否为空
- if (root == NULL){
- printf("tree is empty-- \n");
- return;
- }
- node = root;
-
- while (node != NULL || top > 0){
-
- // 将所有的左子树节点入栈
- while (node != NULL){
- stack[++top] = node;
- node = node->left;
- }
- // 如果右节点为空的话,执行下列语句
- node = stack[top--];
- printf(" %c - ", node->data);
-
- // 扫描右节点
- node = node->right;
- }
-
- }
- void backOrderNRec(Tree root){
-
- Node *p = root;
- Node *stack[MAXSIZE];
- int num = 0;
- Node *have_visited = NULL;
-
- while (NULL != p || num>0)
- {
- while (NULL != p)
- {
- stack[num++] = p;
- p = p->left;
- }
- p = stack[num - 1];
- if (NULL == p->right || have_visited == p->right)
- {
- printf(" %c - ", p->data);
- num--;
- have_visited = p;
- p = NULL;
- }
- else
- {
- p = p->right;
- }
- }
-
- }
非递归实现后序遍历还是很复杂的,变来变去,指来指去的
但是,我发现一种简单的方法
我们知道 后序遍历的顺序为:
后序:左->右->根
那么可以把后序当作:根->右->左,最后再反转回来即可。
由于我们是使用的栈,所以先保存根节点, 然后先放进去 左节点,再放 进去 右节点
-
- void backOrderNRecSimple(Tree root){
- Tree stack[MAXSIZE], node;
- int top = 0;
- int count = 0;
- char array[MAXSIZE]; // 使用一个数组来保存数据,方便最后数组的反转
-
- if (root == NULL){
- printf("tree is empty-- \n");
- return;
- }
- else{
- top++;
- // 仿照一个栈
- stack[top] = root; // 将根节点入栈
- while (top > 0){
- //出栈
- node = stack[top--];
- array[count++] = node->data; // 将其保存在一个数组当中
-
- // 先把右子树放进去,栈是先进去后出,所以下面的左子树先出
- if (node->left != NULL){
- stack[++top] = node->left; // 入栈
- }
- if (node->right != NULL){
- stack[++top] = node->right;
- }
-
- }
-
- }
- // 反转数组,输出
- for (int i = count-1; i >= 0; i--){
- printf(" %c - ", array[i]);
- }
-
- }
附上java代码,更为简单:
- ArrayList<Integer> postOrder(TreeNode root) {
- ArrayList<Integer> list = new ArrayList<Integer>();
- if (root != null) {
- Stack<TreeNode> stack = new Stack<TreeNode>();
- stack.push(root);
- while (!stack.isEmpty()) {
- TreeNode node = stack.pop();
- list.add(node.val);
- if (node.left != null) {
- stack.push(node.left);
- }
- if (node.right != null) {
- stack.push(node.right);
- }
- }
- //反转
- Collections.reverse(list);
- }
- return list;
- }
层次遍历使用的是 队列来实现
- void Level_traversal(Tree root){
-
- if (root == NULL){
- printf("tree is empty-- \n");
- return;
- }
-
- Tree stack[MAXSIZE], node;
- node = root;
- int front = 0; // 使用 front, rear模拟队列
- int rear = 0;
-
- stack[rear++] = node;
-
- while (front != rear){
-
- node = stack[front++]; // 模拟队列,先获取front当前元素,然后在指向 front ++ 位元素
- printf(" %c - ", node->data);
-
- // 左右子树入队列
- if (node->left != NULL){
- stack[rear++] = node->left;
- }
-
- if (node->right != NULL){
- stack[rear++] = node->right;
- }
- }
-
- }
- #include <stdio.h>
- #include <stdlib.h>
-
- #define MAXSIZE 100
-
-
- // 二叉树的实现
-
- // 定义 二叉树的 结构体
- typedef struct node{
- char data;
- struct node *left;
- struct node *right;
- }Node, *Tree;
-
- // 依据前序遍历创建二叉树
- // 根左右: ABD##E##C##
-
- Tree create_tree(){
- Node *root = NULL;
- char ch;
- scanf("%c", &ch); // 输入 ABD##E##C##
-
- if (ch != '#'){
- root = (Node*)malloc(sizeof(Node));
- root->data = ch;
-
- root->left = create_tree(); // 递归创建
- root->right = create_tree();
- }
- else{
- root = NULL;
- }
-
- return root;
- }
-
-
- // 递归前序遍历二叉树
- void preOrderRec(Tree root){
- if (root != NULL){
- printf(" %c - ", root->data);
- preOrderRec(root->left);
- preOrderRec(root->right);
- }
- }
-
- // 非-递归前序遍历二叉树
- void preOrderNRec(Tree root){
- Tree stack[MAXSIZE], node;
- int top = 0;
-
- if (root == NULL){
- printf("tree is empty-- \n");
- return;
- }
- else{
- top++;
- // 仿照一个栈
- stack[top] = root; // 将根节点入栈
- while (top > 0){
- //出栈
- node = stack[top--];
- printf(" %c - ", node->data);
-
- // 先把右子树放进去,栈是先进去后出,所以下面的左子树先出
- if (node->right != NULL){
- stack[++top] = node->right; // 入栈
- }
- if (node->left != NULL){
- stack[++top] = node->left;
- }
-
- }
-
- }
- }
-
-
- // 递归中序遍历二叉树
- void inOrderRec(Tree root){
- if (root != NULL){
- inOrderRec(root->left);
- printf(" %c - ", root->data);
- inOrderRec(root->right);
- }
- }
-
- // 非-递归实现中序遍历二叉树
- void inOrderNRec(Tree root){
- Tree stack[MAXSIZE], node;
- int top = 0;
- // 判断树是否为空
- if (root == NULL){
- printf("tree is empty-- \n");
- return;
- }
- node = root;
-
- while (node != NULL || top > 0){
-
- // 将所有的左子树节点入栈
- while (node != NULL){
- stack[++top] = node;
- node = node->left;
- }
- // 如果右节点为空的话,执行下列语句
- node = stack[top--];
- printf(" %c - ", node->data);
-
- // 扫描右节点
- node = node->right;
- }
-
- }
-
-
- // 递归后序遍历二叉树
- void backOrderRec(Tree root){
- if (root != NULL){
- backOrderRec(root->left);
- backOrderRec(root->right);
- printf(" %c - ", root->data);
-
- }
- }
-
- // 非 - 递归实现后序遍历
- void backOrderNRec(Tree root){
-
- Node *p = root;
- Node *stack[MAXSIZE];
- int num = 0;
- Node *have_visited = NULL;
-
- while (NULL != p || num>0)
- {
- while (NULL != p)
- {
- stack[num++] = p;
- p = p->left;
- }
- p = stack[num - 1];
- if (NULL == p->right || have_visited == p->right)
- {
- printf(" %c - ", p->data);
- num--;
- have_visited = p;
- p = NULL;
- }
- else
- {
- p = p->right;
- }
- }
-
- }
-
- void backOrderNRecSimple(Tree root){
- Tree stack[MAXSIZE], node;
- int top = 0;
- int count = 0;
- char array[MAXSIZE]; // 使用一个数组来保存数据,方便最后数组的反转
-
- if (root == NULL){
- printf("tree is empty-- \n");
- return;
- }
- else{
- top++;
- // 仿照一个栈
- stack[top] = root; // 将根节点入栈
- while (top > 0){
- //出栈
- node = stack[top--];
- array[count++] = node->data; // 将其保存在一个数组当中
-
- // 先把右子树放进去,栈是先进去后出,所以下面的左子树先出
- if (node->left != NULL){
- stack[++top] = node->left; // 入栈
- }
- if (node->right != NULL){
- stack[++top] = node->right;
- }
-
- }
-
- }
- // 反转数组,输出
- for (int i = count-1; i >= 0; i--){
- printf(" %c - ", array[i]);
- }
-
- }
-
- // 层次遍历,打印出二叉树的值
- void Level_traversal(Tree root){
-
- if (root == NULL){
- printf("tree is empty-- \n");
- return;
- }
-
- Tree stack[MAXSIZE], node;
- node = root;
- int front = 0; // 使用 front, rear模拟队列
- int rear = 0;
-
- stack[rear++] = node;
-
- while (front != rear){
-
- node = stack[front++]; // 模拟队列,先获取front当前元素,然后在指向 front ++ 位元素
- printf(" %c - ", node->data);
-
- // 左右子树入队列
- if (node->left != NULL){
- stack[rear++] = node->left;
- }
-
- if (node->right != NULL){
- stack[rear++] = node->right;
- }
- }
-
- }
-
-
- int main(){
-
- printf("starting ------ \n");
-
-
- Tree root = create_tree();
- printf("递归前序遍历--- \n");
- preOrderRec(root);
- printf("\n");
- printf("递归中序遍历--- \n");
- inOrderRec(root);
- printf("\n");
- printf("递归后序遍历--- \n");
- backOrderRec(root);
- printf("\n");
- printf("------------------\n");
-
- printf("非递归实现前序遍历--- \n");
- preOrderNRec(root);
- printf("\n");
-
- printf("非递归实现中序遍历--- \n");
- inOrderNRec(root);
- printf("\n");
-
- printf("非递归实现后序遍历--- \n");
- backOrderNRec(root);
- printf("\n");
-
- printf("非递归实现后序遍历 简单的方法 --- \n");
- backOrderNRecSimple(root);
- printf("\n");
-
- printf("层次遍历 --- \n");
- Level_traversal(root);
- printf("\n");
-
-
-
- // ABD##E##C##
-
-
- return 0;
- }
Java微服务实战296集大型视频-谷粒商城【附代码和课件】
Java开发微服务畅购商城实战【全357集大项目】-附代码和课件
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。