当前位置: 首页 > wzjs >正文

专业做pc+手机网站seo关键词排名优化专业公司

专业做pc+手机网站,seo关键词排名优化专业公司,网站pc和手机端,100种晚上禁用的app大全1.二叉树的顺序结构及实现 1.1 二叉树的顺序结构 普通的二叉树是不适合用数组来存储的,因为可能会存在大量的空间浪费。而完全二叉树更适合使用顺序结构存储。现实中我们通常把堆(一种二叉树)使用顺序结构的数组来存储,需要注意的是这里的堆和操作系统…

1.二叉树的顺序结构及实现

1.1 二叉树的顺序结构

普通的二叉树是不适合用数组来存储的,因为可能会存在大量的空间浪费。而完全二叉树更适合使用顺序结构存储。现实中我们通常把堆(一种二叉树)使用顺序结构的数组来存储,需要注意的是这里的堆和操作系统虚拟进程地址空间中的堆是两回事,一个是数据结构,一个是操作系统中管理内存的一块区域分段

在这里插入图片描述
左图就是完全二叉树的数组存储
右图是非完全二叉树的数组顺序存储,会造成浪费
数组存储不适合,因为会浪费很多空间。数组存储表示二叉树只适合完全二叉树

  • 逻辑结构:想像出来的
  • 物理结构:实实在在的在内存中是如何存储

表示二叉树的值在数组位置中父子下标关系:

  • parent =(child-1)/2
  • leftchild = parent*2+1
  • rightchild = parent*2+2

1.2 堆的概念及结构

如果有一个关键码的集合K = { k0,k1 ,k2 ,…,kn-1 },把它的所有元素按完全二叉树的顺序存储方式存储在一个一维数组中,并满足: ki<=k2*i+1 且 ki <=k2*i+2 ( ki>= k2*i+1且 ki>=k2*i+2 ) i = 0,1,2…,则称为小堆(或大堆)。将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。

堆的性质:

  • 堆中某个节点的值总是不大于或不小于其父节点的值;
  • 堆总是一棵完全二叉树。

在这里插入图片描述

小根堆:树中所有父亲都小于或等于孩子
大根堆:树中所有父亲都大于或等于孩子

1.2.1 堆的时间复杂度

因为堆是完全二叉树,而满二叉树也是完全二叉树,此处为了简化使用满二叉树来证明(时间复杂度本来看的就是近似值,多几个节点不影响最终结果):

在这里插入图片描述
因此:堆的时间复杂度为O(N)。

1.3 堆的实现思路(均以大顶堆为例后面实现也是)

  • 难点:你实际操作的是数组,但是你要会画图,清晰的知道你实现的是二叉树。
typedef int HPDataType;
typedef struct Heap
{HPDataType* a;int size;int capacity;
}HP;
//堆的初始化
void HeapInit(HP* php);
// 堆的插入
void HeapPush(HP* php, HPDataType x);
// 堆的删除
void HeapPop(HP* php);
// 取堆顶的数据
HPDataType HeapTop(HP* php);
// 堆的数据个数
bool HeapEmpty(HP* php);
// 堆的判空
int HeapSize(HP* php);

1.3.0 堆的初始化

初始化,先断言,然后malloc开辟空间,初始化大小和容量

void HeapInit(HP* php)
{assert(php);//断言php->a = (HPDataType*)malloc(sizeof(HPDataType)*4);//开辟初始空间if (php->a == NULL){perror("HeapInit::malloc fail!");return;}php->size = 0;//目前堆内没有数据,所以size = 0php->capacity = 4;//默认初始容量是4
}

1.3.1 堆向上调整算法

  • 在数组上看起来是毫无章法的交换数据,但是把二叉树画出来,就清晰的知道为什么这么换。

在这里插入图片描述

从孩子向上调整,从刚刚插入的数据位置进行调整
结束条件,是我们的最后交换到堆顶,堆顶结点也就是父亲结点>=0,
在这里插入图片描述

  • 向上调整算法代码实现
void swap(HPDataType* p1, HPDataType* p2)
{HPDataType x = *p1;*p1 = *p2;*p2 = x;
}void AdjustUp(HPDataType* a, int child)
{int parent = (child - 1) / 2;//根据孩子位置,计算父亲位置while (child > 0)//child = 0,说明parent不存在了,已经到堆顶了{if (a[child] > a[parent]) //当孩子大小大于父亲大小的时候就交换{swap(&a[child], &a[parent]);//因为其他地方也要用到交换,封装了一个交换函数child = parent; //现在把父亲的值给孩子。parent = (child - 1) / 2;//继续计算现在节点的父亲结点,}else//孩子<=父亲 没必要往上走,直接break就行。		{break;}}
}

1.2.1 堆向下调整算法

现在我们给出一个数组,逻辑上看做一颗完全二叉树。我们通过从根节点开始的向下调整算法可以把它调整成一个小堆。向下调整算法有一个前提:左右子树必须是一个堆,才能调整。

int array[] = {27,15,19,18,28,34,65,49,25,37};

在这里插入图片描述

void swap(HPDataType* p1, HPDataType* p2)
{HPDataType x = *p1;*p1 = *p2;*p2 = x;
}
void AdjustDown(HPDataType* a, int n ,int parent)
{int child = parent*2+1;//根据父亲位置,计算孩子位置while (child <n)//走到没有孩子的时候,结束,{// 选出左右孩子中大的那一个if (child + 1 < n && a[child + 1] > a[child])//必须把child+1<n放前面,否则后面a[child+1]就越界了!{++child;}//交换if (a[child] > a[parent]){swap(&a[child],&a[parent]);parent = child;child = parent * 2 + 1;}else{break;}}
}

1.2.4 堆的插入

先判断是否要扩容
然后进行数据插入
判断是否满足大根堆条件,不满足就要进行交换

  • 先插入一个10到数组的尾上,再进行向上调整算法,直到满足堆。

在这里插入图片描述

  • 堆的插入代码实现
void HeapPush(HP* php, HPDataType x)
{assert(php);//扩容判断if (php->size == php->capacity){HPDataType* tmp = (HPDataType*)realloc(php->a, sizeof(HPDataType) * php->capacity * 2);if (tmp == NULL){perror("HeapPush::realloc fail!");return;}php->a = tmp;php->capacity *= 2;}php->a[php->size] = x;	//在数组尾巴插入数据php->size++;//给size++//封装一个调整函数,在函数内判断是否进行交换,交换就直接换。AdjustUp(php->a,php->size-1);
}
  • 代码验证,打开调试窗口,在监视1中输入ph.a,5,就能看到我们插入的堆的值。看着数组值自己手动画图,就能看到我们的大顶堆成功实现了。

在这里插入图片描述

1.2.5 堆的删除

  • 删除堆是删除堆顶的数据,将堆顶的数据根最后一个数据一换,然后删除数组最后一个数据,再进行向下调整算法。

在这里插入图片描述

  • 堆的删除代码实现
void HeapPop(HP * php)
{assert(php);assert(!HeapEmpty(php));//删除数据//(1)交换堆顶和最后一个数据 直接删掉。swap(&php->a[0], &php->a[php->size-1]);php->size--;//新的堆顶元素向下调整AdjustDown(php->a, php->size,0);
}

1.2.6 其他

HPDataType HeapTop(HP* php)
{assert(php);return php->a[0];
}bool HeapEmpty(HP* php)
{assert(php);return php->size == 0;
}int HeapSize(HP* php)
{assert(php);return php->size;
}
  • 验证。调试,在监控窗口输入:hp.a,3

在这里插入图片描述

2 附录:堆的代码实现

2.1 20250312_heap.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>typedef int HPDataType;
typedef struct Heap
{HPDataType* a;int size;int capacity;
}HP;//堆的初始化
void HeapInit(HP* php);
// 堆的插入
void HeapPush(HP* php, HPDataType x);
// 堆的删除
void HeapPop(HP* php);
// 取堆顶的数据
HPDataType HeapTop(HP* php);
// 堆的数据个数
bool HeapEmpty(HP* php);
// 堆的判空
int HeapSize(HP* php);

2.2 20250312_heap.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"20250312_heap.h"void HeapInit(HP* php)
{assert(php);php->a = (HPDataType*)malloc(sizeof(HPDataType)*4);if (php->a == NULL){perror("HeapInit::malloc fail!");return;}php->size = 0;php->capacity = 4;
}void swap(HPDataType* p1, HPDataType* p2)
{HPDataType x = *p1;*p1 = *p2;*p2 = x;
}void AdjustUp(HPDataType* a, int child)
{int parent = (child - 1) / 2;//根据孩子位置,计算父亲位置while (child > 0)//child = 0,说明parent不存在了,已经到堆顶了{if (a[child] > a[parent]) //当孩子大小大于父亲大小的时候就交换{swap(&a[child], &a[parent]);//因为其他地方也要用到交换,封装了一个交换函数child = parent; //现在把父亲的值给孩子。parent = (child - 1) / 2;//继续计算现在节点的父亲结点,}else//孩子<=父亲 没必要往上走,直接break就行。		{break;}}
}void HeapPush(HP* php, HPDataType x)
{assert(php);//扩容判断if (php->size == php->capacity){HPDataType* tmp = (HPDataType*)realloc(php->a, sizeof(HPDataType) * php->capacity * 2);if (tmp == NULL){perror("HeapPush::realloc fail!");return;}php->a = tmp;php->capacity *= 2;}php->a[php->size] = x;	//在数组尾巴插入数据php->size++;//给size++//封装一个调整函数,在函数内判断是否进行交换,交换就直接换。AdjustUp(php->a,php->size-1);
}void AdjustDown(HPDataType* a, int n ,int parent)
{int child = parent*2+1;//根据父亲位置,计算孩子位置while (child <n)//走到没有孩子的时候,结束,{// 选出左右孩子中大的那一个if (child + 1 < n && a[child + 1] > a[child])//必须把child+1<n放前面,否则后面a[child+1]就越界了!{++child;}//交换if (a[child] > a[parent]){swap(&a[child],&a[parent]);parent = child;child = parent * 2 + 1;}else{break;}}
}void HeapPop(HP * php)
{assert(php);assert(!HeapEmpty(php));//删除数据//(1)交换堆顶和最后一个数据 直接删掉。swap(&php->a[0], &php->a[php->size-1]);php->size--;//新的堆顶元素向下调整AdjustDown(php->a, php->size,0);
}HPDataType HeapTop(HP* php)
{assert(php);return php->a[0];
}bool HeapEmpty(HP* php)
{assert(php);return php->size == 0;
}int HeapSize(HP* php)
{assert(php);return php->size;
}

2.3 test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"20250312_heap.h"int main()
{HP hp;HeapInit(&hp);HeapPush(&hp, 1);HeapPush(&hp, 24);HeapPush(&hp, 7);HeapPush(&hp, 9);HeapPush(&hp, 4);HeapPop(&hp);HeapPop(&hp);return 0;
}
http://www.dtcms.com/wzjs/305648.html

相关文章:

  • 京东网站网站建设是什么网站建设费用明细表
  • 注册公司代理费用多少钱百度手机seo软件
  • 首页制作搜索引擎优化作业
  • 家纺网站建设合肥做网站公司哪家好
  • 东莞企石网站建设优化网站教程
  • 哪个网站可以做围棋作业百度应用搜索
  • 义务网网站建设方案微信小程序怎么做店铺
  • 申请付费网站百度网络科技有限公司
  • 设计定制型网站建设企业培训课程名称
  • 瑞金网站建设推广网络品牌营销
  • 乌鲁木齐的网站建设杭州旺道企业服务有限公司
  • 网站开发程序流程图北京网络推广公司wyhseo
  • 做聊天网站的视频教程免费发布平台
  • 手机网站管理系统软文营销的技巧有哪些?
  • 宝宝投票网站怎么做的全媒体广告加盟
  • 怎样做的英文网站广告公司网站制作
  • 廊坊网站网站建设千锋培训学费多少钱
  • 长沙公司做网站seo含义
  • 新手java语言学做网站企业为何选择网站推广外包?
  • 合肥网站建设网站制作推广项目
  • icp网站备案流程百度外推代发排名
  • 商务网站运营与管理免费搭建网站平台
  • 网站推广需要几个人做网站名称查询
  • 怎么可以建网站网站搜索排名靠前
  • 网站建设管理相关规定无锡网站制作优化
  • 无锡网站排名优化公司哪家好郑州网络营销排名
  • 招聘H5在什么网站做最好一份完整的品牌策划方案
  • 企业查询天眼查入口seo排名优化推广报价
  • 当今做啥网站致富网络营销策划模板
  • 全国网站制作公司排名北京seo优化方案