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

抖音网站网络营销推广的特点

抖音网站,网络营销推广的特点,做网站费用怎么记分录,网站推广方法海豚湾一、概念 之前在队列的时候讲过,队列是先进先出的,是根据你的插入顺序来确定优先级的。 而有时候我们希望可以通过元素内容来确定优先级。 比如:在手机上玩游戏的时候,如果有来电,那么系统应该优先处理打进来的电话&am…

一、概念

之前在队列的时候讲过,队列是先进先出的,是根据你的插入顺序来确定优先级的。

而有时候我们希望可以通过元素内容来确定优先级。

比如:在手机上玩游戏的时候,如果有来电,那么系统应该优先处理打进来的电话;初中那会班主任排座位时可能会让成绩好的同学先挑座位。
在这种情况下, 数据结构应该提供两个最基本的操作,一个是返回最高优先级对象,一个是添加新的对象 。这种数据结构就是优先级队列 (Priority Queue)

 堆的性质:

  • 堆总是一棵完全二叉树。
  • 堆中某个节点的值总是不大于或不小于其父节点的值。如果是某个节点值大于左右结点就是大根堆如果是某个节点值小于左右结点,就是小根堆

二、堆的底层结构

堆实际上是二叉树的顺序存储,就是用数组的方式,来表示二叉树。

小根堆:

而且我们可以发现,数组中的存储顺序是层序遍历的结果

大根堆:

从堆的概念可知,堆是一棵完全二叉树,因此可以层序的规则采用顺序的方式来高效存储

如果不是完全二叉树:

中间就会浪费许多空间,所以并不是一个好的选择

如果是一个完全二叉树:

不仅不会浪费空间,我们还可以利用完全二叉树的一些公式:

  • 如果i0,则i表示的节点为根节点,否则i节点的父亲节点为 (i - 1)/2
  • 如果2 * i + 1 小于节点个数,则节点i的左孩子下标为2 * i + 1,否则没有左孩子
  • 如果2 * i + 2 小于节点个数,则节点i的右孩子下标为2 * i + 2,否则没有右孩子

三、堆的实现和创建

我们一边写代码一边进行画图介绍

首先创建一个堆类,指定堆初始大小为10,可以传入数组:

public class MyHeap {//存放数组元素private int[] elem;//记录有效数据个数private int usedSize;//初始化为10public MyHeap() {elem = new int[10];}//初始化public void init(int[] array) {for (int i = 0; i < elem.length && i < array.length; i++) {elem[i] = array[i];usedSize++;}}
}

1.将数据转化为堆的存储

那么我们如何把数组转化为,表示堆的逻辑呢?

我们要将现在的这串数据转化为堆,相信大家想到的是通过逆序排序就直接Ok了。

那我问你

所以单纯的逆序排序是不太ok的

正确的排序方式:

我们现在就可以写一部分代码了:

    public void createHeap() {for (int parent = (usedSize-1-1) / 2; parent >= 0; parent--) {//用来调整siftDown();}}private void siftDown() {}

继续之前的操作:

最终代码实现:

    public void createHeap() {for (int parent = (usedSize-1-1) / 2; parent >= 0; parent--) {//用来调整siftDown(parent,usedSize);}}private void siftDown(int parent, int end) {//假设左孩子是最大值//通过 i * 2 + 1 = 左子树int child = (parent * 2) + 1;//孩子节点越界就说明结束了while (child < end) {//右孩子没有越界的情况     左孩子       <    右孩子 吗?if (child + 1 < end && elem[child] < elem[child+1]) {//右孩子比左孩子大child++;}//孩子节点大于父亲节点if (elem[child] > elem[parent]) {swap(parent,child);parent = child;child = (child * 2) + 1;}else {//说明不需要调整了break;}}}private void swap(int i, int j) {int tmp = elem[i];elem[i] = elem[j];elem[j] = tmp;}

那么来测试一下:

    public static void main(String[] args) {int [] array = {27,15,19,18,28,34,65,49,25,37};MyHeap myHeap = new MyHeap();myHeap.init(array);myHeap.createHeap();}

结果:

2.在堆中添加数据

由于我们本质是通过数组存储的,所以还是会存在数组满的情况,那就需要判断一下是不是满了,满了就扩容。

那我们就当是已经解决了长度不够的问题:

代码:

    public void offer(int val) {if (isFull()) {elem = Arrays.copyOf(elem,elem.length * 2);}elem[usedSize] = val;usedSize++;siftUp(usedSize-1);}private void siftUp(int child) {//计算父亲节点位置int parent = (child - 1) / 2;while (parent >= 0) {if (elem[parent] < elem[child]) {swap(parent,child);child = parent;parent = (child - 1) / 2;}else {break;}}}

测试:

    public static void main(String[] args) {int [] array = {27,15,19,18,28,34,65,49,25,37};MyHeap myHeap = new MyHeap();myHeap.init(array);myHeap.createHeap();myHeap.offer(70);}

结果:

 如果我们直接通过offer方法来创建堆呢?是不是每一次都是堆,测试一下:

    public static void main(String[] args) {MyHeap myHeap = new MyHeap();myHeap.offer(27);myHeap.offer(15);myHeap.offer(19);myHeap.offer(18);myHeap.offer(28);myHeap.offer(34);myHeap.offer(65);myHeap.offer(49);myHeap.offer(25);myHeap.offer(37);}

根据结果看虽然顺序会有不同,但是仍然是满足大根堆条件的。

3.堆中删除数据

 代码实现:

    public int poll() {//判断是否为nullif (isEmpty()) {return -1;}int old = elem[0];//交换后逻辑删除swap(0,usedSize-1);usedSize--;//向下调整siftDown(0,usedSize);return old;}private boolean isEmpty() {return usedSize == 0;}

四、PriorityQueue

1.特性

Java 集合框架中提供了 PriorityQueue PriorityBlockingQueue 两种类型的优先级队列, PriorityQueue 是线 程不安全的, PriorityBlockingQueue 是线程安全的 ,本文主要介绍 PriorityQueue

关于PriorityQueue的使用要注意:

  1. PriorityQueue中放置的元素必须要能够比较大小,不能插入无法比较大小的对象,否则会抛出ClassCastException异常
  2. 不能插入null对象,否则会抛出NullPointerException
  3. 没有容量限制,可以插入任意多个元素,其内部可以自动扩容(理论上的,实际肯定是不可以无限插入的)
  4. 插入和删除元素的时间复杂度为O(log2N)
  5. PriorityQueue底层使用了堆数据结构
  6. PriorityQueue默认情况下是小堆---即每次获取到的元素都是最小的元素
  7. 使用时必须导入PriorityQueue所在的包,即:
import java.util.PriorityQueue;

2.常用方法函数名

函数名功能介绍
boolean offer(E e)
插入元素 e ,插入成功返回 true ,如果 e 对象为空,抛出 NullPointerException 异常,时
间复杂度,注意:空间不够时候会进行扩容
E peek()
获取优先级最高的元素,如果优先级队列为空,返回 null
E poll()
移除优先级最高的元素并返回,如果优先级队列为空,返回 null
int size() 
获取有效元素的个数
void clear()
清空
boolean isEmpty()
检测优先级队列是否为空,空返回 true

    public static void main(String[] args) {PriorityQueue<Integer> queue = new PriorityQueue<>();//判断是否为nullSystem.out.println(queue.isEmpty());//入堆queue.offer(21);queue.offer(56);queue.offer(44);queue.offer(23);//看一下堆顶元素System.out.println(queue.peek());//返回堆顶元素并退出System.out.println(queue.poll());System.out.println(queue.poll());//返回堆中元素个数System.out.println(queue.size());//清控堆中元素queue.clear();//再次判断是否为nullSystem.out.println(queue.isEmpty());}

 结果:

3.PriorityQueue的构造方法

构造函数功能介绍
PriortiyQueue()创建一个空的优先级队列,默认容量是11
PriortiyQueue(int initialCapacity)
创建一个初始容量为 initialCapacity 的优先级队列,注意:initialCapacity不能小于 1 ,否则会抛 IllegalArgumentException 异 常
PriortiyQueue(Collection<? extends E> c)用一个集合来创建优先级队列

它们多数都调用了,有两个参数的构造方法。这两个参数的构造方法,给了一个比较器,你可以通过这个比较器来控制大根堆或小根堆。(两个参数的构造方法后面再做介绍他的作用)

3.1 参数为 Collection<? extends E> c 的构造方法

意思是只要实现了Collection的数据结构都可以转换为堆:

    public static void main(String[] args) {LinkedList<Integer> list = new LinkedList<>();list.add(23);list.add(34);list.add(45);list.add(56);list.add(67);list.add(78);//将链表PriorityQueue<Integer> queue = new PriorityQueue<>(list);System.out.println(queue.toString());}

 结构:

3.2 通过Comparator实现大根堆小根堆的控制

有这样一个构造方法,传入构造器就可以对控制元素的比较:

我们需要创建一个比较器:

class IntCmp implements Comparator<Integer> {//大根堆写法@Overridepublic int compare(Integer o1, Integer o2) {return o2.compareTo(o1);}//小根堆写法
//    @Override
//    public int compare(Integer o1, Integer o2) {
//        return o1.compareTo(o2);
//    }
}

 测试一下:

    public static void main(String[] args) {PriorityQueue<Integer> queue = new PriorityQueue<>(new IntCmp());queue.offer(23);queue.offer(34);queue.offer(45);queue.offer(56);queue.offer(67);queue.offer(78);System.out.println(queue.toString());}

那代码是如何实现的呢?我们来看一下

大家可能compare和compareTo看懵了,我们来查看一下Integer里面实现的:

 如果是我们自己的类如何比较呢?

我们有这样一个学生类:

class Student {public int age;public Student(int val) {age = val;}
}
    public static void main(String[] args) {PriorityQueue<Student> queue = new PriorityQueue<>();queue.offer(new Student(9));queue.offer(new Student(12));queue.offer(new Student(45));queue.offer(new Student(43));}

我们并没有指定Student的比较方式,这是不被允许的

那我们就就处理一下:

class Student implements Comparable<Student>{public int age;public Student(int val) {age = val;}@Overridepublic int compareTo(Student o) {return this.age - o.age;}@Overridepublic String toString() {return age + " ";}
}
class IntCmp implements Comparator<Student> {//大根堆写法@Overridepublic int compare(Student o1, Student o2) {//这里去调用Student的compareToreturn o2.compareTo(o1);}//小根堆写法
//    @Override
//    public int compare(Student o1, Student o2) {
//        return o1.compareTo(o2);
//    }
}

测试:

        public static void main(String[] args) {PriorityQueue<Student> queue = new PriorityQueue<>(new IntCmp());queue.offer(new Student(9));queue.offer(new Student(12));queue.offer(new Student(45));queue.offer(new Student(43));System.out.println(queue.toString());}

五、堆排序

经过上面这么多图的讲解,我们现在就知道了,如果是大根堆,堆顶元素一定是最大值,反之就是最小值。那我们就可以像删除元素那样,把最后第一个元素和最后一个元素交换再进行操作保证仍然是堆,那么现在堆底元素就是最大值。下一次堆顶元素就是第二大的值了,以此类推。

图解:

 代码:

    /*** 堆排序* 时间复杂度:O(log2n * n)* 空间复杂度:O(N)* 稳定性:不稳定*/public void heapSort(int[] array) {//先调整为大根堆createHeap(array);//end控制未排序数据的末尾int end = array.length - 1;while (end >= 0) {//交换堆首和堆尾元素swap(array,0,end);//向下调整siftDown(array,0,end);//有效数据已经放到末尾end--;}}private void createHeap(int[] array) {for (int parent = (array.length-1-1) / 2; parent >= 0; parent--) {//用来调整siftDown(array,parent,array.length);}}private void siftDown(int[] array, int parent, int end) {//假设左孩子是最大值//通过 i * 2 + 1 = 左子树int child = (parent * 2) + 1;//孩子节点越界就说明结束了while (child < end) {//右孩子没有越界的情况     左孩子       <    右孩子 吗?if (child + 1 < end && array[child] < array[child+1]) {//右孩子比左孩子大child++;}//孩子节点大于父亲节点if (array[child] > array[parent]) {swap(array,parent,child);parent = child;child = (child * 2) + 1;}else {//说明不需要调整了break;}}}private void swap(int[] array, int i, int j) {int tmp = array[i];array[i] = array[j];array[j] = tmp;}

测试:

    public static void main(String[] args) {MyHeap heap = new MyHeap();int[] array = {27,15,19,18,28,34,65,49,25,37};heap.heapSort(array);}

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

相关文章:

  • seo的特点是什么seo快速排名外包
  • 做企业网站的研究现状查网站流量查询工具
  • 公务员做网站品牌策划
  • 企业网站的建设目的是什么百度竞价品牌广告
  • 河北注册公司流程和费用seo可以从哪些方面优化
  • 进入这个网站企业seo关键字优化
  • 南昌网站优化昆明网站开发推广公司
  • 什么是伪静态网站青岛seo
  • 大连手机自适应网站建设维护福建seo学校
  • 互联网装饰网站经典软文广告
  • 国外做油画的网站百度搜索风云榜排行榜
  • 微商加人神器360优化大师官方免费下载
  • 淮安汽车集团网站建设中国腾讯和联通
  • 网站推广优化外包公司哪家好搜索引擎排名优化建议
  • 徐州网站建设要多少钱惠州百度seo
  • 如何用一个域名做多个网站百度收录网站链接入口
  • 模板网站源码南京seo网站优化
  • 产品推广网站设计深圳app推广平台
  • 华企网站建设推广优化友点企业网站管理系统
  • 英文版网站制作公司建设网站哪家好
  • 网络营销的基本特征百度seo教程视频
  • 学做缝纫的网站百度首页排名代发
  • 制作网站需要哪些素材百度快照有什么用
  • 服装定制费用东莞外贸优化公司
  • 网站图片设置全网整合营销推广系统
  • 织梦电影网站模板郑州网络推广哪个好
  • 做saas平台网站seo排名推广工具
  • wordpress文章小尾巴北京推广优化公司
  • 网页制作网站建设seo关键词软件
  • 网站代码优化网站友情链接自动上链