数据结构7—树(顺序存储二叉树—堆)含TOPK问题

1.树

1.1树的概念与结构

树是一种非线性的数据结构,它是由 n(n >= 0)个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一颗倒挂的树,也就是说它是根朝上,而叶朝下的。

  • 有一个特殊的结点,称之为根结点(只能有一个),根结点没有前驱结点。
  • 每颗字树的根结点有且只有一个前驱,可以有0个或多个后继。因此,树是递归定义的。
  • 子树是不相交的(如果存在相交,那就变成图了)
  • 除了根结点外,每个结点有且仅有一个父结点
  • 一颗N个结点的树有N-1个边

1.2相关术语

  • 父结点/双亲结点:若一个结点含义子节点,则这个结点称为其子结点的父结点。A是B的父结点,A是C的父结点。
  • 子结点/孩子结点:一个结点含有的子树的根结点称为该结点的子结点。B是A的子结点。
  • 结点的度:一个结点有几个孩子,它的度就是多少。A的度为2,B的度为3。
  • 树的度:一棵树中,最大的结点的度。上图:树的度为3。
  • 叶子结点/终端结点:度为0的结点称为叶结点。D、H、I、F、G。
  • 分支结点/非终端结点:度不为0的结点。B、C、E。
  • 兄弟结点:具有相同父结点的结点互称为兄弟结点(亲兄弟)。B和C就是兄弟结点。
  • 结点的层次:从根开始定义起,根为第1层,根的子结点为第2层,以此类推。
  • 树的高度或深度:树中结点的最大层次。上图为4。
  • 结点的祖先:从根到该结点所经分支上的所有结点。A是所有结点的祖先。
  • 路径:一条从树中任意结点出发,沿父结点—子结点连接,达到任意结点的序列。比如A到H:A—B—E—H。
  • 子孙:以某结点为根的子树中任一结点都称为该结点的子孙。所有结点都是A的子孙。
  • 森林:有m(m > 0)棵互不相交的树集合称为森林。

1.3树的表示

孩子兄弟表示法:

树结构相对线性表就比较复杂了,要存储表示起来就比较麻烦,既要保存值域,也要保存结点和结点之间的关系,实际中树有很多种表示方法如:双亲表示法,孩子表示法,孩子双亲表示法以及孩子兄弟教师法等。但此刻就介绍最常用的:孩子兄弟表示法。

struct TreeNode
{struct TreeNode* child;    //左边开始的第一个孩子结点struct TreeNode* brother;  //指向其右边的下一个兄弟结点int data;                  //结点中的数据域
}

1.4树形结构实际运用场景

文件系统是计算机存储和管理文件的一种方式,它利用树形结构来组织和管理文件和文件夹。在文件系统中,树的结构被广泛应用,它通过父结点和子结点之间的关系来表示不同层级的文件和文件夹之间的关联。

2.二叉树

2.1概念与结构

在树形结构中,我们最常用的就是二叉树,一颗二叉树是结点的一个有限集合,该集合由一个根结点加上两颗别称为左子树和右子树的二叉数组组成或者为空。 

2.2特殊的二叉树

2.2.1满二叉树

一个二叉树,如果每一层的结点数都达到最大值,则这个二叉树就是满二叉树。也就是说,如果一个二叉树的层数为k,且结点总数是2的k次方-1,则它就是满二叉树。

2.2.2完全二叉树

完全二叉树是效率很高的数据结构,完全二叉树是由满二叉树而引出来。对于深度为k的,有n个结点的二叉树,当且仅当其每一个结点都与深度为k的满二叉树中编号从1至n的结点一一对应时称之为完全二叉树。满二叉树是一种特殊的完全二叉树。(假设有K层,最后一层从左到右放,但是K-1包括K-1之前的层数都达到了最大)

2.3二叉树存储结构

二叉树一般可以使用两种结构存储,一种顺序结构,一种链式结构。

2.3.1顺序结构

顺序结构存储就是使用数组来存储,一般使用数组只适合表示完全二叉树,因为不是完全二叉树会有空间的浪费,完全二叉树更适合使用顺序结构存储。

2.3.2链式结构

二叉树的链式结构是指,用链表来表示一颗二叉树,即用链来指示元素的逻辑关系。通常的方法是链表中每个结点由三个域组成,数据域和左右指针域,左右指针分别用来给出该结点左孩子和右孩子所在的链结点的存储地址。

3.实现顺序结构的二叉树

一般堆使用顺序结构的数组来存储数据,堆是一种特殊的二叉树,具有二叉树的特性的同时,还具备其他的特性。

3.1堆

  • 若 i > 0,i 位置结点的双亲序号:(i - 1)/ 2;i = 0,i 为根结点编号,无双亲结点
  • 若 2i +1 < n,左孩子序号:2i+1       右孩子序号:2i+2

4.源代码

Heap.h

#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
#include <time.h>typedef int DataType;
//定义堆的结构——数组
typedef struct Heap
{DataType* arr;int size;//有效数据个数int capacity;//空间大小
}HP;void HPInit(HP* php);//初始化void HPDestroy(HP* php);//销毁void HPPush(HP* php,DataType x);//插入void HPPop(HP* php);//删除DataType HPTop(HP* PHP);//出堆顶元素bool HPEmpty(HP* php);//true为空,false为不空void ADJustDown(DataType* arr, int parent, int n);//向下调整算法void ADJustUp(DataType* arr, int child);//向上调整算法

Heap.c

#include "Heap_Tree.h"void HPInit(HP* php)
{assert(php);php->arr = NULL;php->size = php->capacity = 0;
}void HPDestroy(HP* php)
{assert(php);if(php->arr)free(php->arr);php->arr = NULL;php->size = php->capacity = 0;
}void Swap(int* x, int* y)
{int temp = *x;*x = *y;*y = temp;
}
void ADJustUp(DataType* arr,int child)
{int parent = (child - 1) / 2;while (child > 0){//大堆:>//小堆:<if (arr[child] < arr[parent]){Swap(&arr[child], &arr[parent]);child = parent;parent = (child - 1) / 2;}else{break;}}
}void HPPush(HP* php, DataType x)
{assert(php);//判断空间是否足够if (php->size == php->capacity){//扩容int newcapacity = php->capacity == 0 ? 4 : 2 * php->capacity;DataType* tmp = (DataType*)realloc(php->arr, newcapacity*sizeof(DataType));if (tmp == NULL){perror("realloc fail!");exit(1);}php->arr = tmp;php->capacity = newcapacity;}php->arr[php->size] = x;ADJustUp(php->arr, php->size);php->size++;
}void ADJustDown(DataType* arr,int parent,int n)
{int child = parent * 2 + 1;//左孩子while (child<n){if (child+1<n && arr[child] > arr[child + 1]){child++;}if (arr[child] < arr[parent]){Swap(&arr[child], &arr[parent]);parent = child;child = parent * 2 - 1;	}else{break;}}
}void HPPop(HP* php)
{assert(php && php->size);Swap(&php->arr[0], &php->arr[php->size - 1]);php->size--;ADJustDown(php->arr,0,php->size);
}bool HPEmpty(HP* php)
{assert(php);return php->size == 0;
}DataType HPTop(HP* php)
{assert(php && php->size);return php->arr[0];
}//堆排序
void HeapSort(int* arr,int n)
{//向上调整算法建堆(小堆)for (int i = 0; i < n; i++){ADJustUp(arr,i);}//向下调整算法建堆(大堆)for (int i=(n-2)/2;i>=0;i--){ADJustDown(arr,i,n);}//升序(用大堆+向下调整算法)int end = n - 1;while (end>0){Swap(&arr[0],&arr[end]);ADJustDown(arr, 0, end);end--;}
}

4.1 TOPK问题

#include "Heap_Tree.h"void test01()
{HP hp;HPInit(&hp);int arr[] = {17,20,10,13,19,15 };for (int i = 0; i < 6; i++){HPPush(&hp,arr[i]);}while (!HPEmpty(&hp)){printf("%d ", HPTop(&hp));HPPop(&hp);}HPDestroy(&hp);
}void CreateNDate()
{//造数据int n = 100000;srand(time(0));const char* file = "data.txt";FILE* fin = fopen(file,"w");if (fin == NULL){perror("fopen error");return;}for (int i=0;i<n;i++){int x = (rand() + i) % 100000;fprintf(fin, "%d\n", x);}fclose(fin);
}void TOPK()
{int k = 0;printf("请输入K:");scanf("%d",&k);//从文件中读取前K个数据,建堆const char* file = "data.txt";FILE* fout = fopen(file, "r");if (fout == NULL){perror("fepen fail");exit(1);}int* minHeap = (int*)malloc(k * sizeof(int));if (minHeap == NULL){perror("malloc fail");exit(2);}//从文件读取k个数据,开始建堆for (int i=0;i<k;i++){fscanf(fout,"%d",&minHeap[i]);}//建小堆for (int i = (k-1-1)/2; i >=0 ; i--){ADJustDown(minHeap,i,k);}int x = 0;while (fscanf(fout,"%d",&x)!=EOF){//读取到的数据跟堆顶的数据进行比较//比堆顶大,就交换入堆if (x > minHeap[0]){minHeap[0] = x;ADJustDown(minHeap, 0, k);}}for (int i = 0; i < k; i++){printf("%d ", minHeap[i]);}fclose(fout);
}int main()
{//test01();//CreateNDate();TOPK();return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/148340.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

并发编程---线程安全

一.三大特性 1.原子性&#xff08;线程任务不可再分&#xff09; 一个操作或者多个操作要么全部执行&#xff0c;要么全部不执行。这确保了数据的一致性&#xff0c;避免了部分执行导致的数据错误。 原子类&#xff08;Atomic&#xff09; // static int x 1;static Atomic…

yub‘s Algorithmic Adventures_Day1

Day 1 二分查找 如理解有误欢迎指正交流~ link&#xff1a;704. 二分查找 - 力扣&#xff08;LeetCode&#xff09; 思路分析 题目给出数组升序 &#xff0c;想到二分查找&#xff08;好吧其实题目也给出来了w&#xff09; 找到mid&#xff0c;根据逻辑大小缩小范围比较. …

大模型价格战,打到了负毛利,卷or不卷?

国产大模型淘汰赛在加速。这轮淘汰赛会持续一两年&#xff0c;只有少数真正具备实力的基础模型企业能继续活下去 中国市场的大模型价格战已经打了近半年。这轮价格战已经打到了负毛利&#xff0c;而且暂时没有停止迹象。头部云厂商仍在酝酿新一轮降价。这轮降价会在今年9月下旬…

270万骑手,如何“送”出一个IPO?

2018年美团上市&#xff0c;敲钟之后的王兴在致辞中&#xff0c;特别感谢了「重新发明手机」的乔布斯&#xff1a; “如果没有移动互联网&#xff0c;没有智能手机&#xff0c;我们今天所做的一切都是不可能的事情。” 彼时的中国市场&#xff0c;庞大的人口红利和快速发展的…

mov转gif怎么快速转换?5个软件帮助你轻松进行文件格式转换

mov转gif怎么快速转换&#xff1f;5个软件帮助你轻松进行文件格式转换 将 MOV 格式的视频转换为 GIF 动图是一项非常实用的任务&#xff0c;无论是为了在社交媒体上分享&#xff0c;还是用于创建简短的演示。以下是五款能够快速、高效地将 MOV 转换为 GIF 的软件和工具&#x…

Java浅谈Java String内幕

​ 博客主页: 南来_北往 系列专栏&#xff1a;Spring Boot实战 前言 Java中的String类是一个不可变的、用于表示字符串的类。在Java中&#xff0c;字符串是通过字符数组来实现的&#xff0c;而String类则是对这个字符数组进行封装&#xff0c;并提供了一系列操作字符串的…

c++ 类中特殊成员函数

作业&#xff1a; 仿照string类&#xff0c;自己手动实现 My_string&#xff0c;分文件编译 fun.h代码 #ifndef FUN_H #define FUN_H#include <iostream>using namespace std;class My_string { private:char *ptr; // 指向字符数组的指针int size; // 字符串的最大…

计算机毕业设计推荐-基于python的游戏资讯分享平台

精彩专栏推荐订阅&#xff1a;在下方主页&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f496;&#x1f525;作者主页&#xff1a;计算机毕设木哥&#x1f525; &#x1f496; 文章目录 一、基于python的…

2024重生之回溯数据结构与算法系列学习(4)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】

目录 数据结构王道第2.3章节之线性表精题汇总一 &#xff08;10&#xff09;题目:​编辑 解题思路&#xff1a; 实现代码&#xff1a; &#xff08;11&#xff09;题目&#xff1a; 解题思路&#xff1a; &#xff08;12&#xff09;题目&#xff1a; 解题思路&#xff1a; 实…

Set 和 Map 的模拟实现

1、引言 在数据结构与算法的学习与实践中&#xff0c;关联容器&#xff08;associative containers&#xff09;是不可忽视的重要工具。作为高效管理数据的一类容器&#xff0c;C 标准库中的 set 和 map 在现代软件开发中扮演着关键角色。这两个容器通过平衡二叉搜索树&#x…

软件测试常见面试题

目录 1、什么是测试用例? 2、什么是BUG?(BUG的生命周期) 3、软件开发五大模型 4、软件测试的生命周期 5、测试模型(V模型、W模型) 6、软件开发的生命周期 7、如何描述一个BUG? 8、BUG的级别(线上出现崩溃级别的BUG怎么办) 9、 BUG的生命周期 10、发现一个BUG…

Qt系统相关——QFile和QFileInfo

文章目录 文件操作QFile使用示例QFileInfo 文件操作 C语言&#xff1a; fopen打开文件fread、fwrite读写文件fclose关闭文件 C&#xff1a; fstream打开文件<<、>>流式操作符读写 Linux&#xff1a; open打开文件read、write读写文件close关闭文件 Qt自己也…

把任务管理器里面的vmware usb arbitrition停了,虚拟机一直识别不到手机设备了

在设备管理器--服务 里面找到VMware usb arbitrition服务&#xff0c;点击“启用”就好了。 参考大佬的文章&#xff1a; 吐血经验&#xff01;&#xff01;&#xff01;解决虚拟机连不上USB&#xff01;最全&#xff01;_为什么vmware虚拟机不能连接上usb设备-CSDN博客

地平线静态目标检测 MapTR 参考算法-V1.0

简介 高清地图是自动驾驶系统的重要组件&#xff0c;提供精确的驾驶环境信息和道路语义信息。传统离线地图构建方法成本高&#xff0c;维护复杂&#xff0c;使得依赖车载传感器的实时感知建图成为新趋势。早期实时建图方法存在局限性&#xff0c;如处理复杂地图元素的能力不足…

品牌互鉴,融通中外|AORO遨游创始人受邀参加2024北京国际品牌周

2024年9月21日&#xff0c;第三届北京国际品牌周在北京金融街英蓝国际金融中心举办&#xff0c;本次盛会以“品牌互鉴&#xff0c;融通中外”为主题&#xff0c;由中国国际商会、中国国际公共关系协会、中国文化管理协会、北京国际设计周主办&#xff0c;中国外文局文化传播中心…

LSM-YOLO: A Compact and Effective ROI Detector for Medical Detection

LSM-YOLO: A Compact and Effective ROI Detector for Medical Detection LSM-YOLO: 一种紧凑且有效的医学检测ROI检测器1.介绍2.相关工作2.1医学感兴趣区域&#xff08;ROI&#xff09;检测2.2多尺度特征用于对象检测 3方法3.1LAE(轻量级自适应提取&#xff09;3.2MSFM(多路径…

GESP等级考试C++二级-switch...case的用法

在《GESP等级考试C二级if语句》中提到&#xff0c;可以使用if...else if...else语句来处理多种可能的情况。在C中&#xff0c;使用switch...case语句也可以来处理多种可能。 1 switch...case语句的格式 switch...case语句的格式如图1所示。 图1 switch...case语句的格式 其中…

鸿蒙开发(NEXT/API 12)【基础功能(使用剪贴板进行复制粘贴)】剪贴板服务

场景介绍 [剪贴板]为开发者提供数据的复制粘贴能力。 当需要使用复制粘贴等功能时&#xff0c;例如&#xff1a;复制文字内容到备忘录中粘贴&#xff0c;复制图库照片到文件管理粘贴&#xff0c;就可以通过剪贴板来完成。 约束限制 剪贴板内容大小<128MB。为保证剪贴板数…

【TabBar嵌套Navigation案例-产品推荐页面-UICollectionView-结合xib使用 Objective-C语言】

一、接下来,我们来说这个产品推荐页面 1.首先呢,它是一个CollectionViewController,当我点击这个产品推荐的时候, 这个Cell的时候,我要跳到一个CollectionViewController, 所以呢,我们需要先找到产品推荐,然后给它去添加一个targetVC,然后给它push到一个产品推荐的页面…

AI大模型的前十岗位薪资,谁还说读书没用?零基础入门到精通,收藏这一篇就够了

1. AI系统架构师 薪资范围&#xff1a;100万 - 200万/年 职位要求&#xff1a;需要具备全面的技术背景&#xff0c;精通系统架构设计&#xff0c;能够有效整合AI技术&#xff0c;提升系统性能。要求硕士及以上学历&#xff0c;计算机科学或相关专业背景。 目标院校&#xff1…