C#练习二叉堆算法。

namespace 算法
{
/// <summary>
/// 最大堆
/// </summary>
/// <typeparam name="T"></typeparam>
public class IndexMaxHeap<T> where T:IComparable<T>
{
/// <summary>
/// 堆空间大小
/// </summary>
private int capacity;
/// <summary>
/// 数据项
/// </summary>
private T[] items;
/// <summary>
/// 堆实际大小
/// </summary>
private int count; /// <summary>
/// 构造方法,由用户指定开辟空间大小,注意元素从1开始
/// </summary>
/// <param name="n"></param>
public IndexMaxHeap(int n)
{
capacity = n+1;
items = new T[capacity];
count = 0;
}
/// <summary>
/// 堆实际大小
/// </summary>
/// <returns>返回堆实际大小int类型</returns>
public int size()
{
return count;
}
/// <summary>
/// 堆中是否有数据
/// </summary>
/// <returns></returns>
public bool isEmpty()
{
return count == 0;
} /// <summary>
/// 堆中插入一个元素
/// </summary>
/// <param name="item"></param>
public void insert(T item)
{
if (count+1 > capacity)
{
throw new IndexOutOfRangeException("堆空间溢出");
}
items[++count] = item;
shiftUp(count);
} /// <summary>
/// 出堆
/// </summary>
public T extractMax()
{
if (count <= 0)
{
throw new IndexOutOfRangeException("空数据");
}
T maxItem = items[1];
//先交换位置
swap(ref items[1], ref items[count]);
count--;
//做一次shiftdown操作
shiftDown(1); return maxItem; } private void shiftDown(int n)
{
while (n*2<=count)
{
int des = 2*n;
if (2 * n + 1<=count && items[n * 2].CompareTo(items[2 * n + 1]) < 0)
{
des = 2 * n + 1;
}
if (items[n].CompareTo(items[des]) < 0)
{
swap(ref items[n], ref items[des]);
n = des;
}
else
{
break;
} } } public void print()
{
for(int i = 1; i <= count; i++)
{
Console.WriteLine(items[i]);
}
} /// <summary>
/// 将堆底元素向上提
/// </summary>
/// <param name="n"></param>
private void shiftUp(int n)
{
//只要父级元素大于它,就一直循环并交换
while (n>1 && items[n].CompareTo(items[n/2])>0)
{
int j = n / 2;
swap(ref items[n], ref items[j]);
n = j;
} } private void swap(ref T a,ref T b)
{
T c = a;
a = b;
b = c; } } public class Test
{
public static void Main()
{
IndexMaxHeap<int> heap = new IndexMaxHeap<int>(15); for (int i = 0; i < 10; i++)
{
Random rd = new Random();
int a = rd.Next(10, 100);
heap.insert(a);
// Console.WriteLine(a);
}
Console.WriteLine("---");
Console.WriteLine($"最大值:{heap.extractMax()}");
heap.print();
Console.WriteLine("+++++++++++++++");
HeapSort<int>(new int[5] { 3, 2, 4, 6, 7 });
Console.ReadKey();
} /// <summary>
/// 堆排序
/// </summary>
public static T[] HeapSort<T>(T[] arr ) where T:IComparable<T>
{
IndexMaxHeap<T> a = new IndexMaxHeap<T>(100);
for(int i = 0; i < arr.Length; i++)
{
a.insert(arr[i]);
}
//从小到大
for(int i = arr.Length-1; i >=0; i--)
{
T t = a.extractMax();
arr[i] = t;
}
return arr; } } public class a : IComparable<a>
{
public int CompareTo(a other)
{
throw new NotImplementedException();
}
}
}

C# 最大二叉堆算法的更多相关文章

  1. PHP利用二叉堆实现TopK-算法的方法详解

    前言 在以往工作或者面试的时候常会碰到一个问题,如何实现海量TopN,就是在一个非常大的结果集里面快速找到最大的前10或前100个数,同时要保证 内存和速度的效率,我们可能第一个想法就是利用排序,然后 ...

  2. PHP-利用二叉堆实现TopK-算法

    介绍 在以往工作或者面试的时候常会碰到一个问题,如何实现海量TopN,就是在一个非常大的结果集里面快速找到最大的前10或前100个数,同时要保证内存和速度的效率,我们可能第一个想法就是利用排序,然后截 ...

  3. 《Algorithms算法》笔记:优先队列(2)——二叉堆

    二叉堆 1 二叉堆的定义 堆是一个完全二叉树结构(除了最底下一层,其他层全是完全平衡的),如果每个结点都大于它的两个孩子,那么这个堆是有序的. 二叉堆是一组能够用堆有序的完全二叉树排序的元素,并在数组 ...

  4. 最短路径——Dijkstra算法以及二叉堆优化(含证明)

    一般最短路径算法习惯性的分为两种:单源最短路径算法和全顶点之间最短路径.前者是计算出从一个点出发,到达所有其余可到达顶点的距离.后者是计算出图中所有点之间的路径距离. 单源最短路径 Dijkstra算 ...

  5. 图论——Dijkstra+prim算法涉及到的优先队列(二叉堆)

    [0]README 0.1)为什么有这篇文章?因为 Dijkstra算法的优先队列实现 涉及到了一种新的数据结构,即优先队列(二叉堆)的操作需要更改以适应这种新的数据结构,我们暂且吧它定义为Dista ...

  6. 【数据结构与算法Python版学习笔记】树——利用二叉堆实现优先级队列

    概念 队列有一个重要的变体,叫作优先级队列. 和队列一样,优先级队列从头部移除元素,不过元素的逻辑顺序是由优先级决定的. 优先级最高的元素在最前,优先级最低的元素在最后. 实现优先级队列的经典方法是使 ...

  7. 数据结构与算法——优先队列类的C++实现(二叉堆)

    优先队列简单介绍: 操作系统表明上看着是支持多个应用程序同一时候执行.其实是每一个时刻仅仅能有一个进程执行,操作系统会调度不同的进程去执行. 每一个进程都仅仅能执行一个固定的时间,当超过了该时间.操作 ...

  8. 笔试算法题(46):简介 - 二叉堆 & 二项树 & 二项堆 & 斐波那契堆

    二叉堆(Binary Heap) 二叉堆是完全二叉树(或者近似完全二叉树):其满足堆的特性:父节点的值>=(<=)任何一个子节点的键值,并且每个左子树或者右子树都是一 个二叉堆(最小堆或者 ...

  9. 【算法与数据结构】二叉堆和优先队列 Priority Queue

    优先队列的特点 普通队列遵守先进先出(FIFO)的规则,而优先队列虽然也叫队列,规则有所不同: 最大优先队列:优先级最高的元素先出队 最小优先队列:优先级最低的元素先出队 优先队列可以用下面几种数据结 ...

随机推荐

  1. SQLSqlserver中如何将一列数据,不重复的拼接成一个字符串

    把一列数据拼接成一个字符串比较简单: declare @test varchar(500) set @test=''; select @test=@test+name+',' from person ...

  2. ubuntu 12.04 安装node.js

    在 Ubuntu 12.04 安裝 Node.js 使用 nvm(Node Version Manage) 來安裝 node.js, 預先需要 curl, git, g++ : $ sudo apt- ...

  3. openstack手动安装

    安装文档: https://github.com/yongluo2013/osf-openstack-training/blob/master/installation/openstack-iceho ...

  4. C# winform ListBox实现滚动条自动滚动至底部

    效果如图: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data ...

  5. 修改oracle默认监听端口

    修改oracle默认监听端口 oracle端口修改 主要是修改两个文件和修改oracle参数local_listener 1 查看当前监听状态 [oracle@test ~]$ lsnrctl sta ...

  6. webApp开发中的总结

    meta标签:  H5页面窗口自动调整到设备宽度,并禁止用户缩放页面 <meta name="viewport" content="width=device-wid ...

  7. 用mac的safari浏览器调试ios手机的网页

    iOS 6给Safari带来了远程的Web检查器工具. 一.参考链接 ios开发者文档 safari开发者工具 remote debugging safari 二.设置iphone 设置 -> ...

  8. SpringBoot配置文件application.properties详解

    喜欢的朋友可以关注下,粉丝也缺. 相信很多的码友在接触springboot时,不知道怎么去配置一些项目中需要的配置,比如数据源,tomcat调优,端口等等,下面我就给大家奉献出一些项目中常用的配置信息 ...

  9. linux 下NFS远程目录挂载

    NFS 是Network File System的缩写,中文意思是网络文件系统.它的主要功能是通过网络(一般是局域网)让不同的主机系统之间可以共享文件或目录.NFS客户端(一般为应用服务器,例如web ...

  10. Nginx单向认证的安装配置

    Nginx单向认证的安装配置 首先系统要已经安装了openssl,以下是使用openssl安装配置单向认证的执行步骤与脚本: #------------------------------------ ...