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

怎么建设自己收费网站做淘宝客网站流量选择

怎么建设自己收费网站,做淘宝客网站流量选择,神鹰网站建设公司,创意简约啤酒徽章logo设计目录 一、堆的概念及结构 二、堆的实现 1.堆的定义 2堆的初始化 3堆的插入 ​编辑 4.堆的删除 5堆的其他操作 6代码合集 三、堆的应用 (一)堆排序(重点) (二)TOP-K问题 一、堆的概念及结构 堆的…

目录

一、堆的概念及结构

二、堆的实现

1.堆的定义

2堆的初始化

3堆的插入

​编辑 4.堆的删除

5堆的其他操作

6代码合集

三、堆的应用

(一)堆排序(重点)

(二)TOP-K问题


一、堆的概念及结构

堆的性质:

  • 堆中某个节点的值总是不大于或不小于其父节点的值;

  • 堆总是一棵完全二叉树(但实现起来是线性表)。

二、堆的实现

1.堆的定义

//大堆
typedef int HPDataType;
typedef struct Heap
{HPDataType* a;int size;int capacity;
}HP;

2堆的初始化

//堆的初始化
void HeapInit(HP* php)
{assert(php);php->a = (HPDataType*)malloc(sizeof(HPDataType)*4);if (php->a == NULL){perror("malloc fail");return;}php->size = 0;php->capacity = 4;
}

3堆的插入

//从孩子的位置向上调整函数
void AdjustUp(HPDataType* a, int child)//child是向上调整数的下标
{int parent = (child - 1) / 2;while (child>0){if (a[child] > a[parent]){Swap(&a[child], &a[parent]);child = parent;parent = (child - 1) / 2;}else{break;}}
}
//堆的插入
void HeapPush(HP* php, HPDataType x)
{assert(php);if (php->size == php->capacity){HPDataType* tmp = (HPDataType*)malloc(sizeof(HPDataType) *  php->capacity*2);if (php->a == NULL){perror("malloc fail");return;}// 将旧数据拷贝到新内存中for (int i = 0; i < php->size; i++){tmp[i] = php->a[i];}free(php->a);php->a = tmp;php->capacity *= 2;}php->a[php->size] = x;php->size++;AdjustUp(php->a, php->size - 1);//刚才size++了,所以向上调整的孩子的位置是size-1
}

 4.堆的删除

删除堆顶,用处:可用来排序选出前几名

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

难点:

  • 向下比怎么比?下面哪个儿子大就和谁比

  • 怎么判断已经到叶子节点了?计算该节点的孩子节点有没有超出范围

//向下调整
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;}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));Swap(&php->a[0], &php->a[php->size - 1]);//交换堆顶和最后一个数php->size--;AdjustDown(php->a, php->size,0);
}

如果想要取前k个,那么修改如下: 

5堆的其他操作

//显示堆顶元素
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;
}
//销毁
void HeapDestroy(HP* php)
{assert(php);free(php->a);php->a = NULL;php->size = php->capacity = 0;
}

6代码合集

Heap.h

#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdlib.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);
//销毁
void HeapDestroy(HP* php);
//从孩子的位置向上调整函数
void AdjustUp(HPDataType* a, int child);
//向下调整
void AdjustDown(HPDataType* a, int n, int parent);

Heap.c

#include"Heap.h"
//堆的初始化
void HeapInit(HP* php)
{assert(php);php->a = (HPDataType*)malloc(sizeof(HPDataType)*4);if (php->a == NULL){perror("malloc fail");return;}php->size = 0;php->capacity = 4;
}
void Swap(HPDataType* p1, HPDataType* p2)
{HPDataType temp = *p1;*p1 =*p2;*p2 = temp;
}
//从孩子的位置向上调整函数
void AdjustUp(HPDataType* a, int child)//child是向上调整数的下标
{int parent = (child - 1) / 2;while (child>0){if (a[child] > a[parent]){Swap(&a[child], &a[parent]);child = parent;parent = (child - 1) / 2;}else{break;}}
}
//堆的插入
void HeapPush(HP* php, HPDataType x)
{assert(php);if (php->size == php->capacity){HPDataType* tmp = (HPDataType*)malloc(sizeof(HPDataType) *  php->capacity*2);if (php->a == NULL){perror("malloc fail");return;}// 将旧数据拷贝到新内存中for (int i = 0; i < php->size; i++){tmp[i] = php->a[i];}free(php->a);php->a = tmp;php->capacity *= 2;}php->a[php->size] = x;php->size++;AdjustUp(php->a, php->size - 1);//刚才size++了,所以向上调整的孩子的位置是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;}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));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;
}
//销毁
void HeapDestroy(HP* php)
{assert(php);free(php->a);php->a = NULL;php->size = php->capacity = 0;
}

test.c

#include"Heap.h"
int main()
{HP hp;HeapInit(&hp);HeapPush(&hp, 4);HeapPush(&hp, 18);HeapPush(&hp, 42);HeapPush(&hp, 12);HeapPush(&hp, 2);HeapPush(&hp, 3);int k = 0;scanf_s("%d", &k);while (!HeapEmpty(&hp)&&k--){printf("%d ", HeapTop(&hp));HeapPop(&hp);//和栈非常相似,想把老二取出来就得把老大干掉}printf("\n");return 0;
}

三、堆的应用

(一)堆排序(重点)

①. 建堆
  • 升序:建大堆
  • 降序:建小堆
建堆方式:
向上调整建堆:模拟的是插入数据的过程
//排升序建大堆
void HeapSort(int* a, int n)
{//建大堆for (int i = 1; i < n; i++){AdjustUp(a, i);}
}

向下调整建堆(左右子树必须是大堆或小堆(插入之前得是堆)):

void HeapSort(int* a, int n)
{//向下调整建堆for (int i = (n - 1 - 1) / 2; i >= 0;--i)//先找到最后一个非叶子结点即上图的6 n-1是最后一个数据的下标,再-1除以2就是父节点{AdjustDown(a, n, i);}
}

注:向下建堆的效率O(N)比向上建堆的效率O(N*logN)高

数学证明如下:

②. 利用堆删除思想来进行排序

建堆和堆删除中都用到了向下调整,因此掌握了向下调整,就可以完成堆排序。

代码实现:

#include<stdlib.h>void Swap(HPDataType* p1, HPDataType* p2)
{HPDataType temp = *p1;*p1 =*p2;*p2 = temp;
}
//从孩子的位置向上调整函数
void AdjustUp(HPDataType* a, int child)//child是向上调整数的下标
{int parent = (child - 1) / 2;while (child>0){if (a[child] > a[parent]){Swap(&a[child], &a[parent]);child = parent;parent = (child - 1) / 2;}else{break;}}
}//向下调整
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;}if (a[child] > a[parent]){Swap(&a[child], &a[parent]);parent = child;child = parent * 2 + 1;}else{break;}}
}//O(n*logn)
//排升序建大堆
void HeapSort(int* a, int n)
{//向下调整建堆
for (int i = (n - 1 - 1) / 2; i >= 0;--i)//n-1是最后一个数据的下标,再-1除以2就是父节点
{AdjustDown(a, n, i);
}int end = n - 1;while (end>0){Swap(&a[end], &a[0]);AdjustDown(a, end, 0);--end;}
}
int main()
{int a[10] = { 2,1,5,7,6,8,0,9,3 };HeapSort(a, 9);return 0;
}

③堆排序的时间复杂度

所以如果用来排序的话,无论是向上调整还是向下调整建堆,总的时间复杂度都是O(N*logN)

(二)TOP-K问题

TOP-K 问题:即求数据结合中前 K 个最大的元素或者最小的元素,一般情况下数据量都比较大
比如:专业前 10 名、世界 500 强、富豪榜、游戏中前 100 的活跃玩家等。
对于 Top-K 问题,能想到的最简单直接的方式就是排序,但是:如果数据量非常大,排序就不太可取了 ( 可能
数据都不能一下子全部加载到内存中 ) 。最佳的方式就是用堆来解决,基本思路如下:
1. 用数据集合中前 K 个元素来建堆
k 个最大的元素,则建小堆
k 个最小的元素,则建大堆(和堆排序有点反过来的意思)
2. 用剩余的 N-K 个元素依次与堆顶元素来比较,不满足则替换堆顶元素
将剩余 N-K 个元素依次与堆顶元素比完之后,堆中剩余的 K 个元素就是所求的前 K 个最小或者最大的元素
#define _CRT_SECURE_NO_WARNINGS 1
#include"Heap.h"
void PrintTopK(const char* file, int k)
{// 1. 建堆--用a中前k个元素建小堆int* topk = (int*)malloc(sizeof(int) * k);assert(topk);//读文件FILE* fout = fopen(file, "r");if (fout == NULL){perror("fopen error");return;}//读出前K个数建堆for (int i = 0; i < k; ++i){fscanf(fout, "%d", &topk[i]);}//向下调整建堆for (int i = (k - 1 - 1) / 2; i >= 0; --i){AdjustDown(topk, k, i);}// 2. 将剩余n-k个元素依次与堆顶元素交换,不满则则替换int val = 0;int ret= fscanf(fout, "%d", &val);while (ret != EOF){if (val > topk[0])//如果新元素大于堆顶元素,那么替换堆顶元素{topk[0] = val;AdjustDown(topk, k, 0);}ret = fscanf(fout, "%d", &val);}//打印这个数组for (int i = 0; i < k; i++){printf("%d ", topk[i]);}printf("\n");free(topk);fclose(fout);
}
void TestTopk()
{//为了测试而造数据int n = 10000;srand(time(0));const char* file = "data.txt";FILE* fin = fopen(file, "w");if (fin == NULL){perror("fopen error");return;}for (size_t i = 0; i < n; ++i){int x = rand() % 10000;fprintf(fin, "%d\n", x);}fclose(fin);PrintTopK(file,10);
}
int main()
{TestTopk();return 0;
}

注意:这里是建小堆,AdjustDown里面需要调一下,之前是建大堆用的AdjustDown

http://www.yayakq.cn/news/712663/

相关文章:

  • 1000M双线网站空间凡科代理平台
  • 专业创业服务平台网站建设需求网站推广公司转型方向
  • 各省备案网站国际招聘人才网
  • 哪里有做网站的公司用php做的网站有
  • 初学网站建设免费网站空间php
  • 山东省建设部官方网站网上书城网站建设功能定位
  • 安徽工程建设信息网站南宁网站开发培训
  • 昆明网站建设有限公司问卷调查网站赚钱
  • 生成链接的网站攻击静态网站
  • 网站开发研究热点广州建筑集团有限公司科研成果
  • 互联网app网站建设方案模板商丘网 商丘网络第一媒体
  • 中国勘察设计行业信息化建设网站百度建站系统
  • 温州网站推广seo应该如何做
  • 东莞市长安网站建设公司中铁建设集团有限公司下属公司
  • 到哪查找网站域名郑州网站建设找三牛
  • 深圳市律师网站建设怎么样iis7wordpress伪静态
  • 福州闽侯网站建设网站建设调查表
  • 网站的文案西安建设工程信息网官网xiancin
  • 单页淘客网站怎么建设wordpress 使用ip访问
  • 百度网站建设上饶公司网站建设
  • 大埔做网站西安企业seo外包服务公司
  • 基于微信公众号开发网站开发网站解封原因
  • 政务网站建设实施方案wordpress主题模板中国
  • 正确建设企业网站24免费妇科在线咨询
  • 查询网站是否正规怎么用PS做珠宝网站
  • 崇左网站建设公司有哪些html网页设计的比赛
  • 网站建设软著网站建设的参考文献
  • 永川网站建设熊掌号关于建设网站的通知
  • 青海省住房城乡建设厅网站可以申请免费的个人网站吗
  • asp网站如何实现伪静态中企动力公司上班好不好