数据结构------二叉树的构建以及前、中、后、层次遍历(递归实现+非递归实现)

在这里插入图片描述

代码实现

#include "stdio.h"
#include "stdlib.h"
#include "stdbool.h"



typedef int DataType;


// 结点
typedef struct Node {
    DataType data;
    struct Node* left;
    struct Node* right;
}Node;


void create(int *arr, Node **pNode, int index, int len);
void preOrder(Node *pNode);
void inOrder(Node *pNode);
void postOrder(Node *pNode);

void inOrder2(Node *pNode);
void preOrder2(Node *pNode);
void postOrder2(Node *pNode);

void levelOrder(Node *pNode);



int main() {
    // 数的节点数组
    DataType treeArr[] = {1, 2, 3, -1, 4, -1, 5, -1, -1, 6, -1};
    int *ptr = treeArr;

    Node* tree = NULL;
    create(ptr, &tree, 1, 11);      // 构建一个二叉树


    // 递归方式的前、中、后序遍历
    printf("前序:");
    preOrder(tree);
    printf("NULL\n");
    printf("中序:");
    inOrder(tree);
    printf("NULL\n");
    printf("后序:");
    postOrder(tree);
    printf("NULL\n\n");


    // 非递归方式的前、中、后序遍历
    printf("前序:");
    preOrder2(tree);
    printf("NULL\n");
    printf("中序:");
    inOrder2(tree);
    printf("NULL\n");
    printf("后序:");
    postOrder2(tree);
    printf("NULL\n");

	// 层次遍历
    printf("\n层次:");
    levelOrder(tree);
    printf("NULL\n");

    return 0;
}

void levelOrder(Node *pNode) {

    // 使用数组模拟队列
    Node* arr[30];
    int front = 0;
    int rear = 0;

    // 根节点入队
    arr[rear++] = pNode;
    while (front != rear) {
        // 队首节点出队
        Node *temp = arr[front++];
        printf("%d --> ", temp->data);
        if (temp->left != NULL)
            arr[rear++] = temp->left;

        if (temp->right != NULL)
            arr[rear++] = temp->right;
    }
}


/**
 * 后序遍历(非递归)
 * 当前节点的左右子树都为NULL或者都被访问过才能访问当前节点
 * 若不是上述两种情况则入栈
 * @param pNode
 */
void postOrder2(Node *pNode) {
    // 利用数组模拟栈
    Node* stack[30];
    int top = -1;

    Node* r = NULL;

    Node *temp = pNode;
    // 节点不为NULL,访问节点,该结点进栈,指针指向左节点
    // 结点为NULL,栈顶节点出栈,指针指向出栈节点的右节点
    while (temp || top != -1) {
        if (temp) {
            stack[++top] = temp;
            temp = temp->left;
        } else {
            // 右节子树存在且没有被访问过
            if(stack[top]->right && r != stack[top]->right) {
                Node* aa = stack[top]->right;
                stack[++top] = aa;
                temp = stack[top]->left;
            } else {
                // 右节点为NULL或者被访问过
                Node *p = stack[top--];
                printf("%d --> ", p->data);
                r = p;
                temp = NULL;
            }
        }
    }
}




/**
 * 中序遍历(非递归)
 * @param pNode
 */
void inOrder2(Node *pNode) {
    // 利用数组模拟栈
    Node* stack[30];
    int top = -1;

    Node *temp = pNode;
    // 节点不为NULL,该结点进栈,指针指向左节点
    // 结点为NULL,栈顶节点出栈并访问,指针指向出栈节点的右节点
    while (temp || top != -1) {
        if (temp) {
            stack[++top] = temp;
            temp = temp->left;
        } else {
            Node *p = stack[top--];
            printf("%d --> ", p->data);
            temp = p->right;
        }
    }
}






/**
 * 先序遍历(非递归)
 * @param pNode
 */
void preOrder2(Node *pNode) {
    // 利用数组模拟栈
    Node* stack[30];
    int top = -1;

    Node *temp = pNode;
    // 节点不为NULL,访问节点,该结点进栈,指针指向左节点
    // 结点为NULL,栈顶节点出栈,指针指向出栈节点的右节点
    while (temp || top != -1) {
        if (temp) {
            // 先访问节点再进栈(因为要先序遍历先访问根节点)
            printf("%d --> ", temp->data);
            stack[++top] = temp;
            temp = temp->left;
        } else {
            // 访问右子树
            Node *p = stack[top--];
            temp = p->right;
        }
    }
}








/**
 * 后序遍历(递归)
 * @param pNode
 */
void postOrder(Node *pNode) {
    if(pNode == NULL) return;
    postOrder(pNode->left);
    postOrder(pNode->right);
    printf("%d --> ", pNode->data);
}


/**
 * 中序遍历(递归)
 * @param pNode
 */
void inOrder(Node *pNode) {
    if(pNode == NULL) return;
    inOrder(pNode->left);
    printf("%d --> ", pNode->data);
    inOrder(pNode->right);
}


/**
 * 先序遍历(递归)
 * @param pNode
 */
void preOrder(Node *pNode) {
    if(pNode == NULL) return;
    printf("%d --> ", pNode->data);
    preOrder(pNode->left);
    preOrder(pNode->right);
}


/**
 * 构建一颗二叉树
 * @param arr       // 节点数组
 * @param pNode     // 二叉树指针的指针
 * @param index     // 当前访问数组的下标
 * @param len       // 数组长度
 */
void create(int *arr, Node **pNode, int index, int len) {

    if (index > len || arr[index - 1] < 0) {
        *pNode = NULL;
        return;
    }

    *pNode = (Node *) malloc(sizeof(Node));
    (*pNode)->data = arr[index - 1];
    (*pNode)->left = NULL;
    (*pNode)->right = NULL;

    create(arr, &((*pNode)->left), index * 2, len);
    create(arr, &((*pNode)->right), index * 2 + 1, len);
}

结果:

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值