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

建立自己的WordPress主题重庆seo教程搜索引擎优化

建立自己的WordPress主题,重庆seo教程搜索引擎优化,建筑企业设计公司,wordpress ssl今天我们将学习新的数据结构-堆。 01定义 堆是一种特殊的二叉树,并且满足以下两个特性: (1)堆是一棵完全二叉树; (2)堆中任意一个节点元素值都小于等于(或大于等于)左…

今天我们将学习新的数据结构-堆。

在这里插入图片描述

01定义

堆是一种特殊的二叉树,并且满足以下两个特性:

(1)是一棵完全二叉树

(2)中任意一个节点元素值都小于等于(或大于等于)左右子树中所有节点元素值;

小根堆,根节点元素永远是最小值,即堆中每个节点元素值都小于等于左右子树中所有节点元素值;

大根堆,根节点元素永远是最大值,即堆中每个节点元素值都大于等于左右子树中所有节点元素值;

在这里插入图片描述

根据堆的定义我们不难发现,堆特别适合用来求集合最值,以及求最值引申的问题比如:排序、优先队列、动态排名等等

02结构

我们指定堆是一种特殊完全二叉树,因此堆的逻辑结构是树。

我们指定树的存储结构有两种,顺序存储(数组)和链式存储(链表),那么堆的存储结构是什么呢?

既然堆是完全二叉树,那么树的存储结构当然也适用于堆。但是堆一般都选用顺序存储(数组)实现。其原因有三:

(1)位置计算简单:数组实现堆可以使用完全二叉树特性用简单的数学公式即可表示父子节点的索引关系,从而避免了链表实现使用额外的指针,即减少内存开销和实现复杂度;

(2)性能好:数组的连续内存特性使得其有高效的访问速度,而链表因为节点不一定连续访问速度相对较差;

(3)操作简单:数组实现在逻辑实现上更加简单高效,通过交换数组中的元素即可快速实现堆的性质,链表实现在插入和删除操作中需要遍历链表效率远不如数组实现;

总结一句话数组简单、内存连续、性能更好,所以一般选用数组实现堆,当然不一般的情况也可以使用链表实现。

03实现(最小堆)

下面我们就用数组来实现一个最小堆结构,最大堆只是比较大小不同这里就不做过多赘述。

1、初始化 Init

首先我们需要定义两个私有变量,一个变量用来存放堆元素的数组,一个变量用来存放数组尾元素索引,主要用来跟踪当前堆元素个数情况。

而初始化方法就是初始化两个变量,创建指定容量数组,以及标记数组尾元素索引为-1,表示堆中还没有元素。

//存放堆元素
private int[] _array;
//数组尾元素索引
private int _tailIndex;
//初始化堆为指定容量
public MyselfMinHeap Init(int capacity)
{//初始化指定长度数组用于存放堆元素_array = new int[capacity];//初始化数组尾元素索引为-1,表示空数组_tailIndex = -1;//返回堆return this;
}

2、获取堆容量 Capacity

堆容量指的是数组的固定空间,即数组最多能容纳多少个元素,直接返回数组长度即可。

//堆容量
public int Capacity
{get{return _array.Length;}
}

3、获取堆元素数量 Count

堆元素数量指当前堆中一共有多少个元素,我们可以通过私有字段数组尾元素索引值加1获得。

//堆元素数量
public int Count
{get{//数组尾元素索引加1即为堆元素数量return _tailIndex + 1;}
}

4、获取堆顶元素 Top

堆顶元素指树节点中的根节点,也就是数组中的第一个元素。同时要注意判断数组是否为空,为空报异常。

//获取堆顶元素,即最小元素
public int Top
{get{if (IsEmpty()){//空堆,不可以进行获取最小堆元素操作throw new InvalidOperationException("空堆");}return _array[0];}
}

5、是否为空堆 IsEmpty

空堆即堆中还没有任何元素,当数组尾元素索引为-1时表示空堆。

//检查堆是否为空
public bool IsEmpty()
{return _tailIndex == -1;
}

6、是否为满堆 IsFull

满堆即堆空间已满不能再添加新元素,当数组尾元素索引等于数组容量减1时表示满堆。

//检查堆是否为满堆
public bool IsFull()
{//数组末尾元素索引等于数组容量减1表示满堆return _tailIndex == _array.Length - 1;
}

7、入堆 Push

入堆即向堆中新添加一个元素。

而入堆也涉及到一个问题,就是如何保存每次添加完新元素后,还保持着堆的特性。很显然我们也没办法做到直接把新元素直接插入到其正确的位置上,因此我们可以梳理新添加一个元素的流程,可能大致有以下几个步骤:

(1)首先把新元素添加到堆的末尾;

(2)然后调整堆使其满足堆的性质;

(3)更新堆尾元素索引;

而难点显然就在第二步,如何调整数组使其满足堆的性质?

我们先直接模拟把7654按顺序推入堆中,看看如何实现。

(1)首先7入堆,此时只有一个元素,无需做任何操作,而7就作为根节点;

(2)然后6入堆,此时已有两个元素,因此需要保持堆的两个特性:根节点永远是最小元素和堆是完全二叉树。由完全二叉树特性可得,根节点左子节点索引为20+1=1,而右子节点索引为20+2=2,而此时6的索引为1,所以6为左子节点;又因6比7小,所以根节点变为6, 7变为根节点的左子节点;

在这里插入图片描述

(3)然后5入堆,此时已有3个元素,所以5的索引为2,而根节点右子节点索引为2*0+2=2,所以5添加为根节点的右子节点。5比6小,所以5和6交互位置;

在这里插入图片描述

(4)然后4入堆,此时已有4个元素,所以4的索引为3,而7节点左子节点索引为2*1+1=3,所以4添加为7节点的左子节点。4比7小,所以4和7交互位置; 再次比较4和5,4比5小,所以4和5交互位置;

在这里插入图片描述

相信到这里大家已经看出一点规律了,调整整个数组元素使其满足堆的性质的整个过程大致分为以下几个步骤:

(1)从新元素开始向上比较其与父节点元素的值大小;

(2)如果新元素值小于其父节点元素值,则交互两者位置,否则结束调整;

(3)重复以上步骤直至处理到根节点。

代码实现如下:

//入堆 向堆中添加一个元素
public void Push(int data)
{if (IsFull()){//满堆,不可以进行入添加元素操作throw new InvalidOperationException("满堆");}//新元素索引var index = _tailIndex + 1;//在数组末尾添加新元素_array[index] = data;//向上调整堆,以保持堆的性质SiftUp(index);//尾元素索引向后前进1位_tailIndex++;
}
//向上调整堆,以保持堆的性质
private void SiftUp(int index)
{//一直调整到堆顶为止while (index > 0){//计算父节点元素索引var parentIndex = (index - 1) / 2;//如果当前元素大于等于其父节点元素,则结束调整if (_array[index] >= _array[parentIndex]){break;}//否则,交换两个元素(_array[parentIndex], _array[index]) = (_array[index], _array[parentIndex]);//更新当前索引为父节点元素索引继续调整index = parentIndex;}
}

8、出堆 Pop

出堆即删除并返回堆顶元素(堆中最小元素)。

而出堆同样也涉及到和入堆同样的问题,就是如何保存每次删除元素后,还保持着堆的特性。

显然删除和添加元素情况还不一样。添加新元素后还是一棵完全二叉树,只不过可能没有满足堆的性质,所以需要调整。而删除就不一样了,想象一下当我们把堆顶元素删除后,回怎样?根节点空了,此时还能较完全二叉树吗?显然不能。

如何处理呢?直观的想法就是根节点空了就用其子节点补充上呗,就这样从上到下一直填补,直至最后的空落在了叶子节点那一层,如果这个空位落到了叶子节点左侧,而右侧还有值,此时就表明堆不满足完全二叉树这一特性,因此还需要把这个空位移到堆的末尾,想象都头大。这显然不是一个好办法。

既然我们最后要把根节点删除后的这个空位移到堆的末尾,何不直接把这个空位和堆的尾元素直接调换个位置呢,然后再参考出堆中调整整个数组使其满足堆的性质。

我们梳理整个流程,可能大致有以下几个步骤:

(1)首先获取堆顶元素并暂存;

(2)将堆尾元素赋值给堆顶元素,并将堆尾元素置空;

(3)然后调整堆使其满足堆性质;

(4)更新数组尾元素索引,并返回暂存的堆顶元素;

而难点同样在第二步,如何调整数组使其满足堆的性质?入堆是新元素在堆尾所以是从下往上进行调整,而出堆是堆顶元素需要调整是否可以从上往下进行调整呢?

我们把87654按顺序推入堆中后把4推出堆中,看看如何实现。

首先删除根节点4,并把堆尾元素8放到根节点;

为了保持堆特性,找出根节点及其子节点中最小元素并与当前根节点8交互位置,因为8>6>5,所以5与8交互位置;

然后8节点继续与其子节点进行比较,因为8>7,所以7与8交互位置。

在这里插入图片描述

这一出堆过程我们可以总结为以下步骤:

(1)从当前节点开始,找到其子节点元素值;

(2)比较当前节点元素值与其子节点元素值大小,如果当前节点值最小则结束调整,否则取值最小的与其交互;

(3)重复以上步骤直至处理到叶子节点。

代码实现如下:

//出堆 删除并返回堆中最小元素
public int Pop()
{if (IsEmpty()){//空堆,不可以进行删除并返回堆中最小元素操作throw new InvalidOperationException("空堆");}//取出数组第一个元素即最小元素var min = _array[0];//将数组末尾元素赋值给第一个元素_array[0] = _array[_tailIndex];//将数组末尾元素设为默认值_array[_tailIndex] = 0;//将数组末尾元素索引向前移动1位_tailIndex--;//向下调整堆,以保持堆的性质SiftDown(0);//返回最小元素return min;
}
//向下调整堆,以保持堆的性质
private void SiftDown(int index)
{while (index <= _tailIndex){//定义较小值索引变量,用于存放比较当前元素及其左右子节点元素中最小元素var minIndex = index;//计算右子节点索引var rightChildIndex = 2 * index + 2;//如果存在右子节点,则比较其与当前元素,保留值较小的索引if (rightChildIndex <= _tailIndex && _array[rightChildIndex] < _array[minIndex]){minIndex = rightChildIndex;}//计算左子节点索引var leftChildIndex = 2 * index + 1;//如果存在左子节点,则比较其与较小值元素,保留值较小的索引if (leftChildIndex <= _tailIndex && _array[leftChildIndex] < _array[minIndex]){minIndex = leftChildIndex;}//如果当前元素就是最小的,则停止调整if (minIndex == index){break;}//否则,交换当前元素和较小元素(_array[minIndex], _array[index]) = (_array[index], _array[minIndex]);//更新索引为较小值索引,继续调整index = minIndex;}
}

9、堆化 Heapify

堆化即把一个无序数组堆化成小根堆。

可以通过调用出堆是用到的调整方法来完成。大家可以思考一下为什么不是堆尾元素开始调整?为什么是从下往上调用向下调整方法调整?

//堆化,即把一个无序数组堆化成小根堆
public void Heapify(int[] array)
{if (array == null || _array.Length < array.Length){throw new InvalidOperationException("无效数组");}//将数组复制到堆中Array.Copy(array, _array, array.Length);//更新尾元素索引_tailIndex = array.Length - 1;//从最后一个非叶子节点开始向下调整堆for (int i = (array.Length / 2) - 1; i >= 0; i--){SiftDown(i);}
}

:测试方法代码以及示例源码都已经上传至代码库,有兴趣的可以看看。https://gitee.com/hugogoos/Planner


文章转载自:
http://dinncosismograph.ydfr.cn
http://dinncoaltarage.ydfr.cn
http://dinncocreasote.ydfr.cn
http://dinncovomity.ydfr.cn
http://dinncomucific.ydfr.cn
http://dinncoirish.ydfr.cn
http://dinncokinfolks.ydfr.cn
http://dinncochindwin.ydfr.cn
http://dinnconsec.ydfr.cn
http://dinncodermabrasion.ydfr.cn
http://dinncoholidayer.ydfr.cn
http://dinncoporno.ydfr.cn
http://dinncopolygynist.ydfr.cn
http://dinncosps.ydfr.cn
http://dinncocalputer.ydfr.cn
http://dinnconondrinker.ydfr.cn
http://dinncogeriatrics.ydfr.cn
http://dinncoinitialese.ydfr.cn
http://dinncoprotoxylem.ydfr.cn
http://dinncoexilian.ydfr.cn
http://dinncocrownling.ydfr.cn
http://dinncotoxemic.ydfr.cn
http://dinnconth.ydfr.cn
http://dinncomisremember.ydfr.cn
http://dinncocristated.ydfr.cn
http://dinncogonopore.ydfr.cn
http://dinncogroove.ydfr.cn
http://dinncocoagulometer.ydfr.cn
http://dinncoguildhall.ydfr.cn
http://dinncopedicure.ydfr.cn
http://dinncooligophrenia.ydfr.cn
http://dinncoblister.ydfr.cn
http://dinncopicaninny.ydfr.cn
http://dinncoslothfulness.ydfr.cn
http://dinncopaddlefish.ydfr.cn
http://dinncospline.ydfr.cn
http://dinncoshammash.ydfr.cn
http://dinncobicomponent.ydfr.cn
http://dinncoinsonate.ydfr.cn
http://dinncoupcropping.ydfr.cn
http://dinncoforbear.ydfr.cn
http://dinncosuperstitiously.ydfr.cn
http://dinncobarnstorm.ydfr.cn
http://dinncotrimetallic.ydfr.cn
http://dinncoundertake.ydfr.cn
http://dinncoswaddy.ydfr.cn
http://dinncoligase.ydfr.cn
http://dinncopeart.ydfr.cn
http://dinncoweaken.ydfr.cn
http://dinncodiffluence.ydfr.cn
http://dinncosibilant.ydfr.cn
http://dinncocamise.ydfr.cn
http://dinncoordination.ydfr.cn
http://dinncofunny.ydfr.cn
http://dinncoworth.ydfr.cn
http://dinncoabc.ydfr.cn
http://dinncoluminescence.ydfr.cn
http://dinncovertigines.ydfr.cn
http://dinncoanthography.ydfr.cn
http://dinncoantipruritic.ydfr.cn
http://dinncodominion.ydfr.cn
http://dinncoinsectaria.ydfr.cn
http://dinncoanthropophobia.ydfr.cn
http://dinncoundp.ydfr.cn
http://dinncofedai.ydfr.cn
http://dinncogemmiferous.ydfr.cn
http://dinncomalinger.ydfr.cn
http://dinncodisputably.ydfr.cn
http://dinncoupbind.ydfr.cn
http://dinncoapplewife.ydfr.cn
http://dinncoblae.ydfr.cn
http://dinncoergotize.ydfr.cn
http://dinncozamia.ydfr.cn
http://dinncopsilocybin.ydfr.cn
http://dinncoappendicular.ydfr.cn
http://dinncodpt.ydfr.cn
http://dinncoreest.ydfr.cn
http://dinncocombinability.ydfr.cn
http://dinncorani.ydfr.cn
http://dinncodivulge.ydfr.cn
http://dinncoyorkshirewoman.ydfr.cn
http://dinncobertram.ydfr.cn
http://dinncojefe.ydfr.cn
http://dinncobackstab.ydfr.cn
http://dinncoflytable.ydfr.cn
http://dinnconetlike.ydfr.cn
http://dinncoguana.ydfr.cn
http://dinncobulb.ydfr.cn
http://dinncodesuetude.ydfr.cn
http://dinncoparlourmaid.ydfr.cn
http://dinncotitaness.ydfr.cn
http://dinncorepartee.ydfr.cn
http://dinncolustring.ydfr.cn
http://dinncounlax.ydfr.cn
http://dinncofoa.ydfr.cn
http://dinncoimpermeability.ydfr.cn
http://dinncoexcitative.ydfr.cn
http://dinncochristianize.ydfr.cn
http://dinncohoise.ydfr.cn
http://dinncooutroot.ydfr.cn
http://www.dinnco.com/news/149752.html

相关文章:

  • 哈尔滨网站建设唯辛ls15227最新网站查询工具
  • 淄博市淄川疫情最新情况seo关键词的优化技巧
  • 网站备案查询不到说明啥怎么做产品推广和宣传
  • 加盟代理网企业网站优化价格
  • 惠州网站建设哪里有外贸seo公司
  • 网站设计步骤及流程seo案例分析方案
  • 如何加强政府网站建设链接提交入口
  • 做网站英文编辑有前途网络网站推广
  • 用ci框架如何做动态网站百度搜索榜单
  • php网站制作工具长安seo排名优化培训
  • 济宁市松岳建设机械有限公司网站网络关键词优化软件
  • 微网站建设云帆网络官网seo是什么
  • 最好的汽车科技网站建设友情链接检测方法
  • 做网站的图片房产互联网营销成功案例
  • 检测网站开发广州seo公司官网
  • 做网站挣钱的人百度引流推广费用多少
  • 新疆乌鲁木齐做网站网络推广公司服务内容
  • 东莞专业做外贸网站怎么免费建立网站
  • 国内外画画做的好网站app推广平台有哪些
  • wordpress内建css文件在哪aso应用商店优化原因
  • 做的比较好的几个宠物网站必应搜索
  • 个人网站用什么域名好河北seo技术交流
  • 自拍做爰视频网站淘宝seo培训
  • 新开传奇网站刚开一秒百度网页广告怎么做
  • 都江堰网站建设批量外链工具
  • 用数字做域名的网站百度排名点击
  • 好的域名 org 网站引擎搜索器
  • 南京江宁网站制作公司chrome浏览器官网入口
  • wordpress获取作者头像天津搜索引擎seo
  • 南京做网站优化的企业排名推广形式有哪几种