前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >.net core 中实现一个堆结构

.net core 中实现一个堆结构

作者头像
FreeTimeWorker
发布2021-04-02 08:05:22
2880
发布2021-04-02 08:05:22
举报
文章被收录于专栏:C#开发点点滴滴

堆结构的内部是以数组实现,表现形式为一个完全二叉树,对应关系上,上级节点的下标始终等于直接下级节点的下标(任意一个)除2的除数,下级节点的坐标左孩子为上级坐标的位置x2+1,右孩子为上级坐标的位置x2+2,这个条件始终满足 如下代码就是一个简易的堆结构实现

代码语言:javascript
复制
using System;

namespace test1
{
    public enum HeapType
    { 
        Max,
        Min
    }
    public class Heap<T> where T:IComparable<T>
    {
        private T[] _source;
        private int _heapSize;

        private HeapType _heapType;
        public Heap(HeapType heapType)
        {
            this._heapType = heapType;
            _source = new T[0];
            _heapSize = 0;//堆大小为0;
        }
        public Heap(HeapType heapType,T[] lst)
        {
            this._heapType = heapType;
            _source = lst;
            _heapSize = lst.Length;//堆大小为0;
            Heapfiy();
        }


        /// <summary>
        /// 获取当前最前边的值
        /// </summary>
        public T GetTopValue
        {
            get
            {
                if (_heapSize > 0)
                {
                    var result = _source[0];
                    swap(0, _heapSize-- - 1);//交换最后一个项,并调整堆大小
                    Heapfiy(0);
                    return result;
                }
                else
                {
                    return default(T);
                }
            }
        }
        /// <summary>
        /// 插入数据
        /// </summary>
        /// <param name="item"></param>
        public void HeapInsert(T item)
        {
            if (++_heapSize > _source.Length)
            {
                var newlst = new T[_heapSize];
                for (int i = 0; i < _source.Length; i++)
                {
                    newlst[i] = _source[i];
                }
                _source = newlst;
            }
            _source[_heapSize-1] = item;
            //与上级比较  父index= i-1/2
            var currentindex = _heapSize-1;
            var parrentindex = (currentindex - 1) >> 1;
            while (currentindex>0)
            {
                switch (_heapType)
                {
                    case HeapType.Max:
                        if (_source[currentindex].CompareTo(_source[parrentindex])>0)
                        {
                            swap(currentindex, parrentindex);
                        }
                        break;
                    case HeapType.Min:
                        if (_source[currentindex].CompareTo(_source[parrentindex]) < 0)
                        {
                            swap(currentindex, parrentindex);
                        }
                        break;
                }
                currentindex = parrentindex;
                parrentindex = (currentindex - 1) >> 1;
            }
        }
        /// <summary>
        /// 某一个位置的值下移到合适的位置
        /// </summary>
        /// <param name="index"></param>
        private void Heapfiy(int index)
        {
            var i = index;
            switch (_heapType)
            {
                case HeapType.Max:
                    while (i * 2 + 1 < _heapSize)//有子项就一路执行,并且小于子项
                    {
                        //找到目标孩子的i
                        int targetchlidi = i * 2 + 1;
                        if (i * 2 + 2 < _heapSize)//有右孩子
                        {
                            targetchlidi = _source[i * 2 + 1].CompareTo(_source[i * 2 + 2]) > 0 ? i * 2 + 1 : i * 2 + 2;
                        }
                        if (_source[i].CompareTo(_source[targetchlidi]) < 0)
                        {
                            swap(i, targetchlidi);
                            i = targetchlidi;
                        }
                        else
                        {
                            break;
                        }
                    }
                    break;
                case HeapType.Min:
                    while (i * 2 + 1 < _heapSize)//有子项就一路执行
                    {
                        //找到目标孩子的i
                        int targetchlidi = i * 2 + 1;
                        if (i * 2 + 2 < _heapSize)//有右孩子
                        {
                            targetchlidi = _source[i * 2 + 1].CompareTo(_source[i * 2 + 2]) < 0 ? i * 2 + 1 : i * 2 + 2;
                        }
                        if (_source[i].CompareTo(_source[targetchlidi]) > 0)
                        {
                            swap(i, targetchlidi);
                            i = targetchlidi;
                        }
                        else
                        {
                            break;
                        }
                    }
                    break;
                default:
                    break;
            }


          
        }
        /// <summary>
        /// 对所有位置执行下移操作
        /// </summary>
        private void Heapfiy()
        {
            for (int i = _heapSize >> 1; i >=0; i--)
            {
                Heapfiy(i);
            }
        }
        private void swap(int a, int b)
        {
            T r = _source[a];
            _source[a] = _source[b];
            _source[b] = r;
        }
    }
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-03-31 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档