A star前置算法优先队列

A* 寻路算法 其中最重要的就是如何确保我们每次走的都是权值最小的路径这样就可以保证我们寻找的路径是最优的。

优先队列

优先队列是实现A*寻路算法的时候根据权重找出对应的结点很好的方法。

什么是优先队列

优先队列是0个元素和多个元素的集合,每一个元素都有一个优先权限,我们可以对这个队列进行的操作有 插入,删除,当我们
首先优先队列 一般是由满二叉堆来实现的 而二叉堆逻辑上是一个满二叉树。

什么是满二叉树

假设一个二叉树由k层 ,在k-1层之前 每一层的结点的都是2^(k-1-1) 而且第二层的结点都是从最左边网友排列的
根据子节点和父节点的关系 又可以分为最大堆,最小堆
最大堆:每一个结点的值总是大于或者等于子节点的值,因此最大堆的跟节点就是堆的最大值
最小堆:每一个结点的值总是小于或者等于子节点的值,因此最小堆的跟节点就是堆的最小值

假节点为i
父节点 (i-1)/ 2
左子结点 2i+1
右子结点 2i+2

因此代码中,逻辑结构上基于完全二叉树实现,数据存储基于数组实现

namespace UIRANK;
class Program
{static void Main(string[] args){PriorityQueue<int> priorityQueue = new PriorityQueue<int>();priorityQueue.EnQuene(1);priorityQueue.EnQuene(2);priorityQueue.EnQuene(3);priorityQueue.EnQuene(4);priorityQueue.EnQuene(5);priorityQueue.EnQuene(6);priorityQueue.EnQuene(5);priorityQueue.EnQuene(5);priorityQueue.EnQuene(5);priorityQueue.EnQuene(5);priorityQueue.EnQuene(9);Console.WriteLine(priorityQueue.Size);Console.WriteLine(priorityQueue.Capacity);Console.WriteLine(priorityQueue.Peek());Console.WriteLine(priorityQueue.DeQuene());Console.WriteLine(priorityQueue.Size);Console.WriteLine(priorityQueue.Peek());Console.ReadKey();}}
/// 使用的是范型类,并且规定了T只能是可以比较的类型
class PriorityQueue<T> where T : IComparable<T> {// 数组的范围private int _capacity;public int Capacity {get {if (_capacity < 0) {_capacity = 0;}return _capacity;}set {_capacity = value;}}// 当前数组内存了多少个元素private int _size;public int Size {get {if (_size < 0) {_size = 0;}return _size;}set => _size = value;}private T[] elements;IComparer<T> _comparer;// 介绍一下这个构造函数,首先是已经给参数一个默认为10的范围,因为这里要使用到比较函数可能有的时候需要我们根据需求自定义比较所以就用到IComparer这个接口用来让我们使用自定义的比较函数// 这个this 表示的调用了第二个构造函数 ,只是传了一个默认的比较器(不想自定义的时候使用)public PriorityQueue(int capacity = 10) : this(Comparer<T>.Default, capacity) { }public PriorityQueue(IComparer<T> comparer, int capacity = 10) {_comparer = comparer ?? Comparer<T>.Default;Size = 0;Capacity = capacity;elements = new T[capacity];}// 是否为空public bool isEmpty => Size == 0;private T Top => elements[0];// 获得队列最前面的元素(最大值)public T Peek() {if (isEmpty) {throw new Exception("当前队列中没有元素");}return Top;}/// 添加元素public void EnQuene(T data) {if (Size == Capacity) {ExtendCapacity();}elements[Size] = data;HeapInsert(Size);Size++;}/// 删除队列最前面的元素 public T? DeQuene() {if (Size == 0) {return default(T);}T element = elements[0];// 删除栈顶的元素然后交换到栈尾Swap(elements,0,Size-1);Size--;//将剩下的元素继续保持原来的优先队列 Heapify(0,Size);return element;}/// <summary>/// 删除掉队列最上面的值之后需要重新找到最大的值补上并且保证我们的数据结构还是优先队列。/// </summary>/// <param name="index"></param>/// <param name="size"></param>private void Heapify(int index,int size) {int left = index * 2 + 1;while (left < size) {int Customsize = left + 1 < size && _comparer.Compare(elements[left + 1], elements[left]) > 0 ? left + 1 : left;if (_comparer.Compare(elements[Customsize], elements[index]) ==0) {break;}Swap(elements, Customsize, index);index = Customsize;left = index * 2 + 1;}}/// <summary>/// 当我们 增加元素之后将该元素与父节点对应的元素进行比较如果比父节点对应的元素大 则进行替换/// </summary>/// <param name="index"></param>private void HeapInsert(int index) {while (index > 0 && _comparer.Compare(elements[index], elements[(index-1)/2]) > 0) {Swap(elements, index, (index - 1) / 2);index = (index - 1) / 2;}}/// 动态扩容private void ExtendCapacity() {Capacity = Capacity * 2;T[] newElements = new T[Capacity];for (int i = 0; i < elements.Length; i++) {newElements[i] = elements[i];}elements = newElements;}/// 转换两个元素的位置private void Swap(T[] tempElements ,int i,int j) {var temp = tempElements[i];tempElements[i] = tempElements[j];tempElements[j] = temp;}
}

这里坐一下提醒:这里使用的是 vs2023 使用的是.net7 其中namespace 没有大括号了,并且没有使用using System; 和 using System.Collections.Generic;
其实.net7 已经有内置的优先队列了,但是unity最新版也只支持 c# 9 对应.net 5 而优先队列是从 .net6 开始支持的。大家感兴趣的可以去官网查看具体信息。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/6941.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

访学/博后/联培博士关注|不同国家的英语口音辨识度训练

在访问学者、博士后及联合培养的申请过程中&#xff0c;接收方多数都要求英文面试。如果导师的母语为非英语国家&#xff0c;将会带有口音&#xff0c;这样更增加了英语面试难度。如何提升不同国家的英语口音辨识度&#xff0c;使自己的英语表达更加流利&#xff0c;知识人网小…

KEIL 5.38的ARM-CM3/4 ARM汇编设计学习笔记13 - STM32的SDIO学习5 - 卡的轮询读写擦

KEIL 5.38的ARM-CM3/4 ARM汇编设计学习笔记13 - STM32的SDIO学习5 - 卡的轮询读写擦 一、前情提要二、目标三、技术方案3.1 读写擦的操作3.1.1 读卡操作3.1.2 写卡操作3.1.3 擦除操作 3.2 一些技术点3.2.1 轮询标志位的选择不唯一3.2.2 写和擦的卡状态查询3.2.3 写的速度 四、代…

轨道交通巡检机器人的应用范围

在现代轨道交通系统的庞大网络中&#xff0c;无数的轨道、设备和设施交织在一起&#xff0c;如同一个精密的机器在高效运转。而在这背后&#xff0c;轨道交通巡检机器人正悄然登场&#xff0c;它们如同一个个智能的守护者&#xff0c;穿梭于各个场景之中。那么&#xff0c;这些…

python从0开始学习(三)

目录 前言 1、类型转换 1.1 隐式类型转换 1.2 显式类型转换 2、eval函数 总结 前言 上篇我们讲了python中的变量与常量&#xff0c;以及变量类型。本篇文章将接着往下讲。 1、类型转换 python中的数据类型转换包括两种&#xff1a;隐式类型转换和显式类型转换。 1.1 隐式…

SAPUI5基础知识1 - 概览,库,支持工具,自学教程

1. SAPUI5 概览 1.1 SAPUI5 SAPUI5是一种用于构建企业级Web应用程序的开发框架。它是由SAP开发的&#xff0c;基于HTML5、CSS3和JavaScript技术。 SAPUI5提供了一套丰富的UI控件和工具&#xff0c;使开发人员能够快速构建现代化、可扩展和可定制的应用程序。 它还提供了数据…

西门子数控网络IP设定配置

总结&#xff1a;menuselect-诊断-屏幕下方右翻页找到tcp/ip&#xff0c;进去选择tcp/ip诊断&#xff0c;进去选择x130网口&#xff0c;点击更改&#xff0c; 如果没有更改&#xff0c;menuselect-调试-口令&#xff0c;输入口令 sunrise 然后重新配置tcp/ip&#xff0c;配置完…

Qt 6 开源版(免费) -- 在线安装图解

经常遇到询问&#xff1a;有没有Qt6安装包&#xff1f; ......&#xff0c;真没有呢~~ 从Qt6起&#xff0c;它整了两个重大改变&#xff08;并非指技术&#xff09;&#xff1a; 在线安装&#xff0c;不再提供单独的安装包主推收费的商业版 当然的&#xff0c;为了培养市场…

SPSS之聚类分析

SPSS中系统聚类分析功能在【分析】—【分类】—【系统聚类】中完成。系统聚类有两种类型&#xff0c;一种是对样本进行聚类&#xff0c;称为Q型聚类&#xff1b;一种是对变量进行聚类&#xff0c;称为R型聚类。在【系统聚类分析】—【聚类】框下选择【个案】——Q型聚类&#x…

微信小程序生成二维码加密(CryptoJS4.0加密PHP8.0解密)AES方式加密

1、小程序创建 crypto-js.js和crypto.js两个文件&#xff08;点击文件即可&#xff09; 2、小程序js页面引入 var crypto require(../../utils/crypto.js);//注意路径是否正确3、使用 let data {id: that.data.id,name: dx}console.log(JSON.stringify(data))console.log(&…

iOS - Undefined symbols: 解决方法

Undefined symbols: 是让人苦恼的报错&#xff0c;如何知道是 哪个 symbols 不对呢&#xff1f; 今天探索到下面的方法&#xff1a; 1、点击导航上方 最右侧的按钮&#xff0c;查看历史报错 2、选中报错信息&#xff0c;右键选择 Expand All Transcripts 在出现的详细信息面…

FreeRTOS软件定时器(1-18)

软件定时器简介 定时器&#xff1a;从指定的时刻开始&#xff0c;经过一个指定时间&#xff0c;然后触发一个超时事件&#xff0c;用户可以自定义 定时器周期。 硬件定时器&#xff1a;芯片本身自带的定时器模块&#xff0c;硬件定时器的精度一般很高&#xff0c;每次在定时时…

Java常用命令总结 持续更新中!!!

蓝桥杯JAVA组 推荐输入输出示例 // 基础输入 import java.util.*;public class Main{public static void main(String[] args){} }// 非静态方法调用 new Main.Solution();//static函数里面调用非static函数 类.函数// 更快的输入方式 BufferedReader // 更快的输出方式 Print…

js监听页面的显示和隐藏

下方微信公众号 和微信小程序推荐 js监听页面的显示和隐藏 在JavaScript中&#xff0c;监听页面的显示和隐藏可以通过监听visibilitychange事件来实现。visibilitychange事件会在页面的可见性发生变化时触发。 以下是一个简单的示例&#xff0c;演示如何使用visibilitychan…

打招呼得不到回复,跟头像还有关系?

现在很多人有个想法,那就是觉得某些公司是不是为了某些目的才往出发的招聘信息啊,其实他们并不需要招聘新员工。 目录 已读不回? 头像很重要 选择自己的精修照片 已读不回? 很有这种可能,但你细心观察会发现,的确有很多大公司,

再学Java基础——垃圾回收

在Java中&#xff0c;垃圾回收&#xff08;Garbage Collection&#xff0c;简称GC&#xff09;是一个自动的内存管理机制&#xff0c;它用于自动释放那些不再被程序使用的对象所占用的内存空间。这种机制有助于防止内存泄漏和内存溢出等问题&#xff0c;使程序员能够更专注于业…

《面向对象程序设计及C++》实验报告

《面向对象程序设计及C》实验报告 一、实验目的与实验要求 &#xff08;1&#xff09;掌握类的定义、类中成员函数的定义和使用、构造函数和析构函数的定义、功能&#xff1b;掌握对象的使用方法。 &#xff08;2&#xff09;掌握静态数据成员、静态成员函数的功能和使用方法…

什么是新能源汽车热管理?

前言 新能源汽车热管理是指针对电动汽车等新型动力系统所涉及的热量控制和调节技术&#xff0c;其包括散热、冷却、加热、温度控制等方面。在新能源汽车中&#xff0c;电池、电动机、控制器等部件都会产生一定的热量&#xff0c;如果不进行有效的热管理&#xff0c;将会影响汽…

Java中多线程间的通信机制:初学者指南

Java中多线程间的通信机制&#xff1a;初学者指南 在Java中&#xff0c;多线程编程是构建高效、响应迅速的应用程序的关键。然而&#xff0c;当多个线程需要共享数据或协作完成任务时&#xff0c;就需要考虑线程间的通信问题。线程间的通信是指一个线程需要等待另一个线程完成…

Cocos Creator UICanvas详解与2D游戏配置详解

前言 Cocos Creator是一款强大的2D游戏开发引擎&#xff0c;提供了丰富的工具和组件来帮助开发者快速制作出优秀的游戏作品。其中&#xff0c;UICanvas是Cocos Creator中一个非常重要的组件&#xff0c;用于管理游戏中的UI界面。 在本文中&#xff0c;我们将深入探讨Cocos Cr…

python 学习: 矩阵运算

摘要: 本贴通过例子描述 python 的矩阵运算. 1. 一般乘法 (mm 与 matmul) 代码: input_mat1 torch.tensor([[1, 2, 3, 4],[1, 2, 2, 3]])input_mat2 torch.tensor([[1, 2, 3, 3],[2, 1, 2, 3],[3, 1, 2, 2],[2, 3, 2, 3]])print("input_mat1: ", input_mat1)prin…