首页 > 其他分享 >树与二叉树

树与二叉树

时间:2022-10-15 23:14:14浏览次数:50  
标签:node Node return Tree void tree 二叉树

二叉树性质:度为0的节点比度为2的节点多一个。

解释:度为1的节点均可忽略;度为2的节点就相当于分割点,而度为0的节点就相当于线段;不分割时即有一条线段,当每多一个分割点时,线段也就相应会多一个。

二叉树分类(国际版):

  1. 完全二叉树(可编号):设二叉树的深度为 h,除第 h 层外,其它各层 (1~h-1) 的节点数都达到最大个数,第 h 层所有的节点都连续集中在最左边
  2. 满二叉树
  3. 完美二叉树

二叉树可用广义表进行表示:A(B(D, E), C(F,)) 或 1(2(4, 5), 3(6,))(完全二叉树)

深搜遍历(栈或递归):

  1. 前序遍历
  2. 中序遍历
  3. 后序遍历
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

//结构定义:链表节点
typedef struct Node {
    int data;
    Node *lchild, *rchild;
} Node;

//结构定义:树
typedef struct Tree {
    Node *root;
    int length;
} Tree;

//结构操作
Node *getNewNode(int val);
Tree *getNewTree();
void clear_node(Node *node);
void clear_tree(Tree *tree);
Node *insert_node(Node *node, int val, int *flag);
int insert(Tree *tree, int val);
void output_node(Node *node);
void output(Tree *tree);
void preorder_node(Node *node);
void preorder(Tree *tree);
void inorder_node(Node *node);
void inorder(Tree *tree);
void postorder_node(Node *node);
void postorder(Tree *tree);

int main() {
    srand(time(0));
    #define MAX_N 10
    Tree *tree = getNewTree();
    for (int i = 0; i < MAX_N; i++) {
        int val = rand() % 100;
        insert(tree, val);
        output(tree);
    }
    preorder(tree);
    inorder(tree);
    postorder(tree);
    #undef MAX_N
    clear_tree(tree);
    return 0;
}

//结构操作:获得一个新节点
Node *getNewNode(int val) {
    Node *node = (Node *)malloc(sizeof(Node));
    node->data = val;
    node->lchild = node->rchild = NULL;
    return node;
}

//结构操作:获得一棵新树
Tree *getNewTree() {
    Tree *tree = (Tree *)malloc(sizeof(Tree));
    tree->root = NULL;
    tree->length = 0;
    return tree;
}

//结构操作:释放一个节点
void clear_node(Node *node) {
    if (node == NULL) return;
    clear_node(node->lchild);
    clear_node(node->rchild);
    free(node);
    return;
}

//结构操作:销毁树
void clear_tree(Tree *tree) {
    if (tree == NULL) return;
    clear_node(tree->root);
    free(tree);
    return;
}

//结构操作:插入元素的递归操作(排序二叉树)
Node *insert_node(Node *node, int val, int *flag) {
    if (node == NULL) {
        *flag = 1;
        return getNewNode(val);
    }
    if (val == node->data) return node;
    if (val < node->data) node->lchild = insert_node(node->lchild, val, flag);
    else node->rchild = insert_node(node->rchild, val, flag);
    return node;
}

//结构操作:插入一个元素
int insert(Tree *tree, int val) {
    if (tree == NULL) return 0;
    int flag = 0;
    tree->root = insert_node(tree->root, val, &flag);
    tree->length += flag;
    return flag;
}

//结构操作:输出该树的递归操作
void output_node(Node *node) {
    if (node == NULL) return;
    printf("%d", node->data);
    if (node->lchild == NULL && node->rchild == NULL) return;
    printf("(");
    output_node(node->lchild);
    printf(", ");
    output_node(node->rchild);
    printf(")");
    return;
}

//结构操作:用广义表的形式输出该树
void output(Tree *tree) {
    if (tree == NULL) return;
    printf("tree(%d): ", tree->length);
    output_node(tree->root);
    printf("\n");
    return;
}

//结构操作:前序遍历的递归操作
void preorder_node(Node *node) {
    if (node == NULL) return;
    printf("%d ", node->data);
    preorder_node(node->lchild);
    preorder_node(node->rchild);
    return;
}

//结构操作:用前序遍历的方式输出所有元素
void preorder(Tree *tree) {
    if (tree == NULL) return;
    printf("preorder: ");
    preorder_node(tree->root);
    printf("\n");
    return;
}

//结构操作:中序遍历的递归操作
void inorder_node(Node *node) {
    if (node == NULL) return;
    inorder_node(node->lchild);
    printf("%d ", node->data);
    inorder_node(node->rchild);
    return;
}

//结构操作:用中序遍历的方式输出所有元素
void inorder(Tree *tree) {
    if (tree == NULL) return;
    printf("inorder: ");
    inorder_node(tree->root);
    printf("\n");
    return;
}

//结构操作:后序遍历的递归操作
void postorder_node(Node *node) {
    if (node == NULL) return;
    postorder_node(node->lchild);
    postorder_node(node->rchild);
    printf("%d ", node->data);
    return;
}

//结构操作:用后序遍历的方式输出所有元素
void postorder(Tree *tree) {
    if (tree == NULL) return;
    printf("postorder: ");
    postorder_node(tree->root);
    printf("\n");
    return;
}

标签:node,Node,return,Tree,void,tree,二叉树
From: https://www.cnblogs.com/Kelvin-Wu/p/16795300.html

相关文章

  • 广义表转二叉树
    前序遍历和中序遍历&后序遍历和中序遍历可以还原出唯一的二叉树,而前序遍历和后序遍历不行(满二叉树时貌似可以,但只有一个根节点和一个子孩子时一定不行)//输入:A(B(,D),......
  • 数据结构:二叉树
    定义特点每个节点最多有两棵子树,所以二叉树中不存在度大于2的节点。左子树和右子树是有区别的,次序不能颠倒。即使某个节点只有1个子节点,也是有左右之分的。特殊的......
  • 114. 二叉树展开为链表
    题目描述给你二叉树的根结点root,请你将它展开为一个单链表:展开后的单链表应该同样使用TreeNode,其中right子指针指向链表中下一个结点,而左子指针始终为null。展......
  • 二叉树(存储结构,三种遍历方式,构建树)——C语言描述
    二叉树(存储结构,三种遍历方式,构建树)——C语言描述目录二叉树(存储结构,三种遍历方式,构建树)——C语言描述0测试用例框架1定义2特殊二叉树3二叉树的性质4二叉树存储结构5......
  • 226. 翻转二叉树
    题目描述解题思路二叉树的题一般都有对应的模板,我们做题时可以参考对应模板二叉树解题的思维模式分两类:1、是否可以通过遍历一遍二叉树得到答案?如果可以,用一个trav......
  • 617. 合并二叉树
    /***Definitionforabinarytreenode.*structTreeNode{*intval;*TreeNode*left;*TreeNode*right;*TreeNode():val(0),left(......
  • 124.二叉树的最大路径和
    路径被定义为一条从树中任意节点出发,沿父节点-子节点连接,达到任意节点的序列。同一个节点在一条路径序列中至多出现一次。该路径至少包含一个节点,且不一定经过根节点......
  • 图的广度优先搜索和二叉树的层序遍历其实差不多
    图的广度优先搜索和二叉树的层序遍历其实差不多,不同的是在图中没有根节点,你可以随便选择一个节点,当作起始节点,和二叉树的一样入队,访问,出队,判断顶点是否有邻接顶点,如果有邻......
  • 94. 二叉树的中序遍历 (easy)
     递归:左根右 /***Definitionforabinarytreenode.*structTreeNode{*intval;*TreeNode*left;*TreeNode*right;*TreeNode():val(0),left(nul......
  • 计算二叉树的最大宽度
    求非空二叉树的宽度算法思想:层序遍历二叉树,并用两个队列A,B交替存储结点,当队列A中元素为空时队列B就存储了下一层的所有结点,同理,队列B为空时队列A也就存储了下一层的所有......