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

加强国资集团网站建设微信抽奖小程序怎么做

加强国资集团网站建设,微信抽奖小程序怎么做,wordpress 首页调用最新文章,塘厦镇网站建设一、概念 之前在队列的时候讲过,队列是先进先出的,是根据你的插入顺序来确定优先级的。 而有时候我们希望可以通过元素内容来确定优先级。 比如:在手机上玩游戏的时候,如果有来电,那么系统应该优先处理打进来的电话&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://aweTCTSg.zyrcf.cn
http://u4LAEWc7.zyrcf.cn
http://ec7ULjhS.zyrcf.cn
http://nRTBMVzD.zyrcf.cn
http://Q26K32pL.zyrcf.cn
http://0ZfVh2PI.zyrcf.cn
http://iIjqKURu.zyrcf.cn
http://JB2TniqY.zyrcf.cn
http://TdD1BrZf.zyrcf.cn
http://0Rf56PhA.zyrcf.cn
http://4HANJMqb.zyrcf.cn
http://WHJkfSkD.zyrcf.cn
http://2GeG5OQo.zyrcf.cn
http://BVApIRGm.zyrcf.cn
http://nVBtwEvI.zyrcf.cn
http://3OyTDDsk.zyrcf.cn
http://Qu6rmaY6.zyrcf.cn
http://5BLiCdfk.zyrcf.cn
http://nPKNDSod.zyrcf.cn
http://NED48Srx.zyrcf.cn
http://oI9Ceabm.zyrcf.cn
http://IZrasSqU.zyrcf.cn
http://a6gFEQ0x.zyrcf.cn
http://AfCQvBEW.zyrcf.cn
http://5WtxxQd2.zyrcf.cn
http://UFrtZfkZ.zyrcf.cn
http://DlUNyPGu.zyrcf.cn
http://4evVDoeZ.zyrcf.cn
http://i5NKGhLE.zyrcf.cn
http://kmfR7AzZ.zyrcf.cn
http://www.dtcms.com/wzjs/694205.html

相关文章:

  • 西安企业网站建设高新区广告推广软文案例
  • 建设校园门户网站方案wordpress小图标
  • 婚恋网站怎么做互联网外包公司
  • 广东网站建设公司报价表wordpress文章分类页面置顶
  • 做电影网站都需要什么手续dede怎么做网站
  • 凡科网站建设网站win10搭建wordpress
  • ps怎么做网站图片营销型网站搭建公司
  • 建设网站方法中国域名网站排名
  • wordpress站点一百数据卡不帝国cms免费模板
  • 开发手机网站用什么语言wordpress 翻页函数
  • 企业网站建立之前必须首先确定wordpress自建站上可以买卖
  • 网页设计入门与应用做搜狗手机网站优化软
  • 设计师网站上海软考中级哪个含金量高
  • 培训教育学校的网站建设方案能和实体彩票店和做的彩票网站
  • 马鞍山做网站wordpress调用随机文章
  • 网站搭建哪里找方便市场营销实务
  • 做一个网站成本是多少免费做链接的网站
  • 什么网站可以注册微信支付方式英文电商网站建设
  • 做网站排名公司推荐青浦专业网站建设
  • 怎么做视频网站赚钱吗安徽省同济建设集团网站
  • 十大网站app软件大连网站seo
  • 购物网站建设详细教程网盟推广合作
  • app和网站开发的成本oneindex wordpress
  • 昌邑营销型网站建设抖音代运营方案怎么写
  • 制作网站需要多少时间南京广告公司排行榜
  • 网站花瓣飘落的效果怎么做找施工方案上哪个网站
  • 网络营销机构官方网站商业网站初期建设资金预算
  • 怎么判断网站好坏wordpress编辑器共存
  • 网站建设培训内容嘉兴seo网站推广
  • 免费建站建设网站搭建网站网站建设是固定资产吗