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

陕西省交通建设集团公司西商分公司网站上海百度移动关键词排名优化

陕西省交通建设集团公司西商分公司网站,上海百度移动关键词排名优化,网站开发技术 文库,什么网站可免费发布信息目录 1 堆1.1 堆是什么1.2 基本操作1.2.1 向上调整(上浮)1.2.2 向下调整(下沉)1.2.3 构建堆 1.3 参考代码1.3.1 上浮1.3.2 下沉1.3.3 构建堆 2 优先队列2.1 基本操作2.1.1 出队2.1.2 入队 2.2 代码实现 3 总结 1 堆 1.1 堆是什么…

目录

  • 1 堆
    • 1.1 堆是什么
    • 1.2 基本操作
      • 1.2.1 向上调整(上浮)
      • 1.2.2 向下调整(下沉)
      • 1.2.3 构建堆
    • 1.3 参考代码
      • 1.3.1 上浮
      • 1.3.2 下沉
      • 1.3.3 构建堆
  • 2 优先队列
    • 2.1 基本操作
      • 2.1.1 出队
      • 2.1.2 入队
    • 2.2 代码实现
  • 3 总结

1 堆

1.1 堆是什么

    堆是一种特殊的完全二叉树,可以简洁地使用数组表示和维护。堆适合于需要维护最值的场景,根据其维护的最值种类,可分为 最小堆最大堆 两类,也有许多其它叫法。

  • 最大堆:每个父节点的值 ≥ 其子节点的值,根节点是最大值。
  • 最小堆:每个父节点的值 ≤ 其子节点的值,根节点是最小值。

1.2 基本操作

    堆的基本操作主要有 构建堆向上调整(上浮)向下调整(下沉) 等操作。其中 构建堆 操作是指将一个不是堆的数组转换为堆,本质上是由 下沉 操作组成的。
    下面以构建 最小堆 为例。

1.2.1 向上调整(上浮)

    如果某个元素 x 比其父结点的元素值 p 更小,则其不满足最小堆的定义,需要调整。以 x 为研究对象,则应该将 x 与其父结点元素值 p交换,直到满足最小堆的定义为止。
    以上操作从一棵树的角度来看,相当于将 x 向上调整了。下面是具体的算法步骤:
    1 堆 h 是一个整型数组,长度为 n,需要调整的元素下标为 i,注意下标从 0 开始;
    2 计算父结点下标,易知 i 的父结点下标 p(i-1)/2 向下取整,如果 p >= 0 && h[i] < h[p],则进行交换 swap(h[i], h[p]),然后将研究对象转移到父结点上:i = p,循环;否则退出循环,表示已经浮到顶了。其伪代码如下:

adjust_up(h, i):if i < 0 or i >= h.length:returnp = (i-1)/2while p >= 0 && h[i] < h[p]:swap(h[p], h[i])i = pp = (i-1)/2

1.2.2 向下调整(下沉)

    如果某个元素 a 比其父结点的元素值 p 更小,则其不满足最小堆的定义,需要调整。以其 父结点 p 为研究对象,则应该将 p 与其子结点元素值的最小值 x交换,直到满足最小堆的定义为止。
    以上操作从一棵树的角度来看,相当于将 p 向下调整了。下面是具体的算法步骤:
    1 堆 h 是一个整型数组,长度为 n,需要调整的元素下标为 i,注意下标从 0 开始;
    2 计算左子结点下标,易知 i 的左子结点下标 li * 2 + 1,如果 i 还有右子结点,则应该比较左右子结点的值的大小,取最小的那个结点 c,然后进行交换 swap(h[i], h[c]),然后将研究对象转移到该子结点上:i = c,循环;否则退出循环,表示已经沉到底了。其伪代码如下:

adjust_down(h, i):if i < 0 or i >= h.length:returnl = 2*i+1while l < h.length:if l + 1 < h.length && h[l+1] < h[l]:l++if h[i] <= h[l]:returnswap(h[l], h[i])i = ll = 2*i+1

1.2.3 构建堆

    给你一个无序数组,怎么将其变成堆呢?
    首先我们知道,堆是完全二叉树,其最后一个非叶结点的下标是可以确定的,假设堆 h 是一个整型数组,长度为 n,下标从 0 开始,则其最后一个非叶结点的下标是 (n-1)/2 向下取整。
    为什么要关注最后一个非叶结点呢?因为从这个结点按照从右到左的顺序依次将元素下沉,直到操作完成,一个堆就建立好了。(每一次只会在一个满足定义的“堆”上面增加一个不确定的结点,那么将这个结点向下沉即可保证以该结点为根的堆是满足定义的)。
    也就是调用大约 n/2 次下沉操作即可,算法步骤和伪代码省略。

1.3 参考代码

    假设堆中元素为 int 整数,堆为最小堆。

1.3.1 上浮

void adjust_up(int* h, int pos) {while (pos > 0 && h[pos] < h[(pos - 1) >> 1]) {swap(&h[pos], &h[(pos - 1) >> 1]);pos = (pos - 1) >> 1;}
}

1.3.2 下沉

void adjust_down(int* h, int pos, int n) {int k = (pos << 1) + 1;while (k < n) {if (k + 1 < n && h[k + 1] < h[k]) {k++;}if (h[pos] <= h[k]) {break;}swap(&h[pos], &h[k]);pos = k;k = (pos << 1) + 1;}
}

1.3.3 构建堆

void heaplify(int* arr, int n) {for (int i = (n - 1) / 2; i >= 0; i--) {adjust_down(arr, i);}
}

2 优先队列

    虽然我们常常将堆和优先队列混合在一起说,但不得不搞清楚的是,优先队列算是堆的一种应用。我们平时用的“堆”这种数据结构,大多数是指的优先队列。
    优先队列需要具备 上浮下沉 这两个堆的基本操作,还要有 入队出队 这两个队列的基本操作。

2.1 基本操作

2.1.1 出队

    优先队列的出队操作即将堆数组的第一个元素即堆顶返回,然后将堆数组的最后一个元素放到堆顶处,然后将堆顶的元素向下调整,并将堆的大小减一。

2.1.2 入队

    优先队列的入队操作即在堆数组的最后添加一个元素,堆的大小加一,然后将此时堆数组的最后一个元素(新元素)向上调整。

2.2 代码实现

    这里将记录一个通用的以 C 语言实现的优先队列代码。

// 头文件省略/** C 语言之 “泛型” **/
#define ElemType Message*/** 优先队列元素: 结构体 **/
typedef struct _msg {int priority;char s[15];
} Message;/** 优先队列结构体定义 **/
typedef struct _priority_queue {ElemType* data;int size, capacity;
} PriorityQueue;/** 自定义比较函数 **/
int cmp(ElemType a, ElemType b) { return a->priority - b->priority; }/** 交换两个元素 **/
void swap(ElemType* a, ElemType* b) {ElemType t = *a;*a = *b;*b = t;
}/** 初始化优先队列 **/
PriorityQueue* init_pq(int n) {PriorityQueue* pq = (PriorityQueue*)malloc(sizeof(PriorityQueue));if (!pq) {return NULL;}pq->capacity = n;pq->size = 0;pq->data = (ElemType*)malloc(pq->capacity * sizeof(ElemType));return pq;
}/** 销毁优先队列 **/
void destroy_pq(PriorityQueue* pq) {if (pq) {for (int i = 0; i < pq->size; i++) {free(pq->data[i]);}free(pq->data);free(pq);}
}/** 上浮 **/
void adjust_up(PriorityQueue* pq, int pos) {while (pos > 0 && cmp(pq->data[pos], pq->data[(pos - 1) >> 1]) < 0) {swap(&pq->data[pos], &pq->data[(pos - 1) >> 1]);pos = (pos - 1) >> 1;}
}/** 下沉 **/
void adjust_down(PriorityQueue* pq, int pos) {int k = 0;while ((pos << 1) + 1 < pq->size) {k = (pos << 1) + 1;if (k + 1 < pq->size && cmp(pq->data[k + 1], pq->data[k]) < 0) {k++;}if (cmp(pq->data[pos], pq->data[k]) <= 0) {break;}swap(&pq->data[pos], &pq->data[k]);pos = k;}
}/** 入队 **/
void push(PriorityQueue* pq, ElemType msg) {if (pq->size == pq->capacity) {pq->capacity <<= 1;pq->data =(ElemType*)realloc(pq->data, pq->capacity * sizeof(ElemType));}pq->data[pq->size] = msg;adjust_up(pq, pq->size++);
}/** 出队 **/
ElemType pop(PriorityQueue* pq) {if (pq->size == 0) {return NULL;}ElemType ans = pq->data[0];pq->data[0] = pq->data[--pq->size];adjust_down(pq, 0);return ans;
}

3 总结

    上面只是以最小堆作为例子,其它的情况可以此类推,并且数组下标从 0 开始,也可以将数组下标从 1 开始,这样做的唯一好处就是计算父亲和儿子的下标时的表达式更简洁一些,只需要选择一个自己喜欢的即可。
    关于优先队列的基本操作,这里省略了相对来说不太重要的基本操作(没有封装成函数),有兴趣可以自己封装一下。

http://www.dtcms.com/wzjs/333118.html

相关文章:

  • php网站开发案例教程平台做推广的技巧
  • 代理服务器上外网seo排名优化软件
  • 网站项目策划书方案搜索引擎优化seo什么意思
  • 专业网站建设网站站长平台网站
  • 去哪找做塑料的网站百度竞价课程
  • 昆明公司网站开发网站建设公司官网
  • 温州网站推广线上渠道推广怎么做
  • 做新闻网站如何河北网站seo外包
  • 济南电子商务网站建设网站建设技术外包
  • 河北做网站公司那家好seo的重要性
  • 河南网站建设公司排名网络销售好不好做
  • WordPress百科模板北京seo推广系统
  • 如何申请免费网站域名厦门百度seo排名
  • php做网站麻烦吗今天的热点新闻
  • 毕业设计是做网站设计济宁seo公司
  • 北京企业网站建设电话线下推广方式有哪些
  • 专业做微视频的网站seo sem是指什么意思
  • 贵阳网站托管洛阳seo博客
  • 我电脑做网站局域网怎么访问快速排名刷
  • 手机网站作用公司专业网站建设
  • 网站建设所需材料138ip查询网域名解析
  • 唐山论坛建站模板软服业营收破334亿
  • 做网站横幅的图片湖南seo优化价格
  • 电商大数据查询平台免费志鸿优化网下载
  • 教做黏土手工的网站竞价服务托管价格
  • 一键做网站广州seo网络优化公司
  • 陕西建设厅执业资格注册中心网站免费数据统计网站
  • 哪家微网站建设西安建站推广
  • 武汉网站建设多少钱淘宝推广费用一般多少
  • 创造与魔法官方网站做自己喜欢的事天津建站网