王道408---数据结构--用数组实现二叉树--并查集及其优化代码

这篇具有很好参考价值的文章主要介绍了王道408---数据结构--用数组实现二叉树--并查集及其优化代码。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、数组实现二叉树(下标从0开始)

#include <stdio.h>
typedef struct _TreeNode{
    int data;
    bool IsEmpty;       //结点是否为空  // 因为我们的二叉树不一定是满二叉树,中间可能有一些节点不存在 // 值为1代表空
}TreeNode;


// 初始化
void InitTreeNode(TreeNode t[],int len){
    for(int i=0;i<len;i++)
        t[i].IsEmpty = 1;
}


bool IsEmpty(TreeNode t[],int len,int idx){
    if(idx >= len || idx < 0) return 1;         // 修改为0
    
    return t[idx].IsEmpty;
}

// father = (child-1)/2   or  father = child/2 - 1
int findFather(TreeNode t[],int len,int idx){
    if(idx == 0) return -1;         //特判根节点没有父节点      // 特判也修改为0
    int fatheridx = (idx-1) / 2;
    if(IsEmpty(t,len,fatheridx)) return -1;
    return fatheridx;
}

// lchild = father*2 + 1
int findLchild(TreeNode t[],int len,int idx){
    int lchild = idx*2 + 1;
    if(IsEmpty(t,len,lchild)) return -1;
    return lchild;
}

// rchild = father*2+2
int findRchild(TreeNode t[],int len,int idx){
    int rchild = idx*2 + 2;
    if(IsEmpty(t,len,rchild)) return -1;
    return rchild; 
}

//实现前序遍历, 从下表为idx的节点开始前序遍历
int PreorderTree(TreeNode t[],int len,int idx){
    if(IsEmpty(t,len,idx)) return 0;
    printf("%d\n",t[idx].data);
    PreorderTree(t,len,findLchild(t,len,idx));
    PreorderTree(t,len,findRchild(t,len,idx));
    return 0;
}

int InorderTree(TreeNode t[],int len,int idx){
    if(IsEmpty(t,len,idx)) return 0;
    InorderTree(t,len,findLchild(t,len,idx));
    printf("%d\n",t[idx].data);
    InorderTree(t,len,findRchild(t,len,idx));
    return 0;
}
int PostorderTree(TreeNode t[],int len,int idx){
    if(IsEmpty(t,len,idx)) return 0;
    PostorderTree(t,len,findLchild(t,len,idx));
    PostorderTree(t,len,findRchild(t,len,idx));
    printf("%d\n",t[idx].data);
    return 0;
}


int main(){
    TreeNode Td[100];            // 这里的二叉树节点要从0开始
    int fatheridx;
    int testLen = 7;          // IsEmpty 的判断是 >=Len 所以这里加一个1
    for(int i=0;i<=testLen;i++){
        Td[i].data = i+1;
        Td[i].IsEmpty = 0;
    }
    PreorderTree(Td,testLen,0);
    // InorderTree(Td,testLen,0);
    // PostorderTree(Td,testLen,0);
    return 0;
}

二、数组实现二叉树(下标从1开始)

#include <stdio.h>
typedef struct _TreeNode{
    int data;
    bool IsEmpty;       //结点是否为空  // 因为我们的二叉树不一定是满二叉树,中间可能有一些节点不存在 // 值为1代表空
}TreeNode;


// 初始化
void InitTreeNode(TreeNode t[],int len){
    for(int i=0;i<len;i++)
        t[i].IsEmpty = 1;
}


bool IsEmpty(TreeNode t[],int len,int idx){
    if(idx >= len || idx < 1) return 1;
    
    return t[idx].IsEmpty;
}

// father = child / 2
int findFather(TreeNode t[],int len,int idx){
    // if(idx == 1) return -1;         //特判根节点没有父节点 ,不加也没事,但下表从0开始的时候必须加
    int fatheridx = idx / 2;
    if(IsEmpty(t,len,fatheridx)) return -1;
    return fatheridx;
}

// lchild = father*2
int findLchild(TreeNode t[],int len,int idx){
    int lchild = idx*2;
    if(IsEmpty(t,len,lchild)) return -1;
    return lchild;
}

// rchild = father*2+1
int findRchild(TreeNode t[],int len,int idx){
    int rchild = idx*2+1;
    if(IsEmpty(t,len,rchild)) return -1;
    return rchild; 
}

//实现前序遍历, 从下表为idx的节点开始前序遍历
int PreorderTree(TreeNode t[],int len,int idx){
    if(IsEmpty(t,len,idx)) return 0;
    printf("%d\n",t[idx].data);
    PreorderTree(t,len,findLchild(t,len,idx));
    PreorderTree(t,len,findRchild(t,len,idx));
    return 0;
}

int InorderTree(TreeNode t[],int len,int idx){
    if(IsEmpty(t,len,idx)) return 0;
    InorderTree(t,len,findLchild(t,len,idx));
    printf("%d\n",t[idx].data);
    InorderTree(t,len,findRchild(t,len,idx));
    return 0;
}
int PostorderTree(TreeNode t[],int len,int idx){
    if(IsEmpty(t,len,idx)) return 0;
    PostorderTree(t,len,findLchild(t,len,idx));
    PostorderTree(t,len,findRchild(t,len,idx));
    printf("%d\n",t[idx].data);
    return 0;
}


int main(){
    TreeNode Td[100];            // 这里的二叉树节点要从一开始
    int fatheridx;
    int testLen = 7+1;          // IsEmpty 的判断是 >=Len 所以这里加一个1
    for(int i=1;i<=testLen;i++){
        Td[i].data = i;
        Td[i].IsEmpty = 0;
    }
    PreorderTree(Td,testLen,1);
    // InorderTree(Td,testLen,1);
    // PostorderTree(Td,testLen,1);
    return 0;
}

三、并查集及其优化思路

#include <stdio.h>
#define MAXSIZE 50
int UFSets[MAXSIZE];

void InitUFSets(int S[]){
    for(int i=0;i<MAXSIZE;i++){
        S[i] = -1;
    }
}

int find(int S[],int x){
    if(S[x] == -1) return x;           // -1说明到底了
    return find(S,S[x]);
}

int pathCompFind(int S[],int x){         // 路径压缩策略优化Find 操作
    if(S[x] >= 0){
        S[x] = find(S,S[x]); 
        return S[x];
    }
    return x;
}


bool UnionElem(int S[],int elem1,int elem2){    //王道书上是直接合并的root,而不是元素成员
    int first = find(S,elem1);
    int second = find(S,elem2);
    if(first != second){
        printf("%d -- %d\n",first,second);
        S[second] = first;
        return 1;
    }
    return 0;
}

bool UnionRoot(int S[],int Root1,int Root2){
    if(Root1 == Root2) return 0;    //比较两个根是否来自同一集合
    S[Root2] = Root1;               // 将根Root2连接到Root1上
    return 1;
}

bool optUnionRoot(int S[],int Root1,int Root2){
    if(Root1 == Root2) return 0;
    if(S[Root2] > S[Root1]){   // Root2 结点数更少         // 因为初始化的时候S的值全为 -1  所以 若S[Root1]与S[Root2]相加后为更小的负数
                                                            //较小的树,树较大,这也是为什么 S[Root1] >= S[Root2]时 却把Root2合并到Root1中的原因
        S[Root1] += S[Root2];       // 累加节点个数
        S[Root2] = Root1;
    }else{
        S[Root2] += S[Root1];
        S[Root1] = Root2;
    }
    return 1;
}

void debug(){
    for(int i=0;i<MAXSIZE;i++){
        printf("%d ",UFSets[i]);
    }
    puts("");
}

int main(){
    InitUFSets(UFSets);
    int arr[100] = {0,1,2,3,4,5,6,7,8,9};
    for(int i=0;i<=10;i++){
        UnionElem(UFSets,arr[i*2],arr[i*2+1]);
        // 0 -- 1
        // 2 -- 3
        // 4 -- 5
        // 6 -- 7
        // 8 -- 9
    }
    UnionElem(UFSets,1,3);
    UnionElem(UFSets,5,7);
    // 0 -- 1
    // 2 -- 3
    // 4 -- 5
    // 6 -- 7
    // 8 -- 9
    // 0 -- 2
    // 4 -- 6

    UnionElem(UFSets,1,6);
    UnionElem(UFSets,2,7);
    // debug();



    return 0;
}

 文章来源地址https://www.toymoban.com/news/detail-631037.html

 

到了这里,关于王道408---数据结构--用数组实现二叉树--并查集及其优化代码的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 一篇学完:王道考研408数据结构(全)

    PDF版本附在  lengyueling.cn 对应 文章结尾,欢迎下载访问交流 数据结构在学什么 如何用程序代码把现实世界的问题信息化 如何用计算机高效地处理这些信息从而创造价值 数据结构的基本概念 什么是数据: 数据是信息的载体,是描述客观事物属性的数、字符及所有能输入到

    2023年04月08日
    浏览(46)
  • 【数据结构】【王道408】——PPT截图与思维导图

    自用视频PPT截图 视频网址王道B站链接 23考研 408新增考点: 并查集,红黑树 2023年408真题数据结构篇 408考纲解读 考纲变化 希尔排序 冒泡排序 快速排序 简单排序算法 堆排序

    2024年02月15日
    浏览(34)
  • 数据结构之二叉树的数组表示

    若某节点的索引为 i ,则该节点的左子节点的索引为 2i+1 ,右子节点的索引为 2i+2 给定某节点,获取它的左右字节点,父节点 获取前序遍历,中序遍历,后序遍历,层序遍历

    2024年01月18日
    浏览(51)
  • Java常见的数据结构:栈、队列、数组、链表、二叉树、二叉查找树、平衡二叉树、红黑树

    数据结构是计算机底层存储、组织数据的方式。是指数据相互之间是以什么方式排列在一起的。 通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率 栈 队列 数组 链表 二叉树 二叉查找树 平衡二叉树 红黑树... 后进先出,先进后出 数据进入栈模型的过程称为

    2024年02月07日
    浏览(45)
  • 【23考研】计算机408数据结构代码题强化阶段划重点(王道书)

    视频链接:【23考研】10分钟带你整理408数据结构强化阶段代码题复习重点 本篇只适合考408的同学,请自主命题的同学自觉右上角×掉 因为王道书为了照顾自主命题的同学,所以很多算法也给出了代码实现,实际上对于考408的同学,很多代码是不需要掌握的,毕竟408的代码题没

    2024年02月15日
    浏览(49)
  • 【数据结构大全】你想要的都有,数组、链表、堆栈、二叉树、红黑树、B树、图......

    作者简介: 目录 1.概述 2.线性结构 3.时间复杂度 4.查找算法 5.树 6.图 博主之前写过一个完整的关于数据结构的系列文章,一共十三篇,内容包含,数组、链表、堆栈、队列、时间复杂度、顺序查找、二分查找、二叉树、二叉搜索树、平衡二叉树、红黑树、B树、B+树、大顶堆

    2024年02月10日
    浏览(46)
  • 【数据结构和算法】--- 二叉树(3)--二叉树链式结构的实现(1)

    在学习二叉树的基本操作前,需先要创建一棵二叉树,然后才能学习其相关的基本操作。由于现在大家对二叉树结构掌握还不够深入,且为了方便后面的介绍,此处手动快速创建一棵简单的二叉树,快速进入二叉树操作学习,等二叉树结构了解的差不多时,我们反过头再来研

    2024年01月25日
    浏览(63)
  • 【数据结构】树、二叉树的概念和二叉树的顺序结构及实现

    之前我们学习了顺序表、链表以及栈和队列这些数据结构,但这些数据结构都是线性的(一对一)。接下来要学习 非线性的数据结构——树(二叉树) ,相比前面的,树的结构更加复杂,话不多说,直接进入正题吧。 树是一种 非线性的数据结构 ,它是 一对多(也有可能是

    2024年02月07日
    浏览(41)
  • 【数据结构 —— 二叉树的链式结构实现】

    树是一种非线性的数据结构,它是由n(n=0)个有限结点组成一个具有层次关系的集合。 把它叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。 1.有一个 特殊的结点,称为根结点 ,根节点没有前驱结点 2.除根节点外, 其余结点被分成M(M0)个互不相交

    2024年02月05日
    浏览(56)
  • 数据结构-二叉树·堆(顺序结构的实现)

    🎉个人名片: 🐼作者简介:一名乐于分享在学习道路上收获的大二在校生 🐻‍❄个人主页🎉:GOTXX 🐼个人WeChat : ILXOXVJE 🐼本文由GOTXX原创,首发CSDN🎉🎉🎉 🕊系列专栏:零基础学习C语言----- 数据结构的学习之路 🐓每日一句:如果没有特别幸运,那就请特别努力!🎉

    2024年02月05日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包