C语言树数据结构

1.定义:树是一种非线性的数据结构,它是由n(n>=0)个有限结点组成一个具有层次关系的集合。

  • 节点的度:一个节点含有的子树的个数称为该节点的度;
  • 树的度:一棵树中,最大的节点的度称为树的度;
  • 节点的层次:节点的层次:从根开始定义起,根为第1层,根的子节点为第2层,以此类推;

  • 树的深度:树中节点的最大层次 ;

  • 叶节点:度为0的节点。

  • 二叉树:是指树中节点的度不大于2的有序树,它是一种最简单且最重要的树。

    • 二叉树的子树有左右之分,次序不能颠倒,因此二叉树是有序树

2.满二叉树:除在二叉树最下层的节点外,每层的节点都有两个子节点。

3.完全二叉树:除最后一层外,其他各层的节点数都达到最大个数,且最后一层节点是从左到右的连续存在。满二叉树是一种特殊的完全二叉树。

  • 有n个节点的完全二叉树,若从上往下,从左到右,从0开始给节点编号,那么:

    • parent = (child-1)/2;

    • leftchild = parent*2 + 1; 若结果大于n,则无左孩子。

    • rightchild = parent*2 + 2; 若结果大于n,则无右孩子。

4.树的存储方式:

  • 顺序存储:顺序结构存储就是使用数组来存储,如果节点为空,要把空间留出来。会造成空间浪费,适合存储满二叉树和完全二叉树。

  • 链式存储:二叉树的链式存储结构是指,用链表来表示一棵二叉树,即用链来指示元素的逻辑关系。链式存储结构的结点包含三个部分,分别是数据域、左指针域、右指针域。

5.C语言二叉树的链式存储的实现:

1.二叉树的创建以及销毁
typedef int BTDataType;
typedef struct BinaryTreeNode{
    BTDataType data;//数据
    struct BinaryTreeNode *lNode;//左子节点
    struct BinaryTreeNode *rNode;//右子节点
}BTNode;
//创建一个节点
BTNode * NodeCreate(BTDataType data){
    BTNode * node = (BTNode *) malloc(sizeof(BTNode));
    if(node == NULL){
        printf("malloc failed\n");
        exit(-1);
    }
    node->data = data;
    node->lNode = NULL;    
    node->rNode = NULL;    
    return node;
}
//二叉树的销毁
void BTDestory(BTNode * root){
    if(root==NULL){
        return;
    }
    BTDestory(root->lNode);
    BTDestory(root->rNode);
    free(root);
}
2.二叉树的遍历
//前序遍历:输出顺序:根节点、左子树、右子树;
//中序遍历:输出顺序:左子树、根节点、右子树,将打印函数往后放一句;
//后序遍历:输出顺序:左子树、右子树、根节点,将打印函数往后放两句;
void prevOrder(BTNode * root){    //前序遍历
    if(root==NULL){
        return;
    }
    printf("%d\n",root->data);
    prevOrder(root->lNode);
    prevOrder(root->rNode);
}

//层序遍历:需要用到队列相关知识,具体参考队列一章
void levelOrder(BTNode * root){
  if(root==NULL){
        return;
  }
    Queue *queue = QueueCreate();
  QueuePush(queue,root);
    while( !IsEmpty(queue) ){
        BTNode *cur = QueueFront(queue);
        QueuePop(queue);
        printf("%d\n",cur->data);
        if(cur->lNode != NULL){
            QueuePush(queue,cur->lNode);
        }
      if(cur->rNode != NULL){
            QueuePush(queue,cur->rNode);
      }
    }
    QueueDestory(queue);
}

3.二叉树非空节点个数
//1.如果是空树,则返回0
//2.不是空,节点个数=左子树节点个数+右子树节点个数+1(自己)
int BTSize(BTNode *root){
    return root==NULL ? (0) : BTSize(root->lNode)+ BTSize(root->rNode) + 1;
}
4.二叉树叶子节点个数
​​​​​​​//1.如果是空树,则返回0
//2.如果根节点的左右子节点都是空则返回1
//3.否则=左子树的叶子结点个数+右子树的叶子节点个数
int BTLeafSize(BTNode *root){
   if(root==NULL){
       return 0;
   }
   if(root->rNode == NULL && root->lNode ==NULL){
       return 1;
   }
   return BTLeafSize(root->lNode) + BTLeafSize(root->rNode);
}
5.二叉树第k层节点个数
//1.空树,返回0
//2.k=1,返回1
//3.k>1;等于左子节点k-1层节点个数 + 右子节点k-1层节点个数
int BTlevelSize(BTNode * root, int k){
    if(root==NULL){
        return 0;
    }
    if(k==1){
        return 1;
    }
    return BTlevelSize(root->lNode,k-1) + BTlevelSize(root->rNode,k-1);
}
6.查找第一个值为k的节点
​​​​​​​//1.空树,返回空
//2.判断根节点是不是
//3.在左子节点中寻找,如果没有,再去右子节点寻找,都没有返回空
BTNode * BTFind(BTNode *root,BTDataType k){
    if(root == NULL){
        return NULL;
    }
    if(root->data == k){
        return root;
    }
    BTNode *lRes = BTFind(root->lNode,k);
    if(lRes != NULL){
        return lRes;
    }
    BTNode *rRes = BTFind(root->rNode,k);
    if(rRes != NULL){
        return rRes;
    }
    return NULL;
}
7.二叉树的深度
//1.空树,返回0
//2.非空=左右子树深度最大的 + 1
int BTDepth(BTNode * root){
    if(root==NULL){
        return 0;
    }
    int r = BTDepth(root->rNode);
    int l = BTDepth(root->lNode);
    return r > l ? (r+1) : (l+1);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值