数据结构——简单实现优先队列(维护大小堆)

class PriorityQueue
    {
        private int[] Heap = new int[20];
        private int count;

        public void push(int num)
        {
            if (count > 19)
            {
                Console.WriteLine("堆满");
                return;
            }

            Heap[count] = num;
            shiftUp(count);
            count++;
        }

        private void shiftUp(int count)
        {
            //Console.WriteLine("count:"+count);
            while ((count+1)/2>0)
            {
                if (Heap[count] > Heap[count / 2])
                {
                    //Console.WriteLine("Changed");
                    int temp = Heap[count];
                    Heap[count] = Heap[count / 2];
                    Heap[count / 2] = temp;
                }
                count /= 2;
            }

            /*foreach (int it in Heap)
            {
                if(it!=0)
                  Console.WriteLine(it);
            }*/
        }

        public int top()
        {
            if (count == 0)
            {
                Console.WriteLine("堆空");
            }

            return Heap[0];
        }

        public int pop()
        {
            int top = Heap[0];
            Heap[0] = Heap[count];
            shiftDown();
            count--;
            return top;
        }

        private void shiftDown()
        {
            int curC = 0;
            while (curC < count)
            {
                //右孩子大于左孩子
                if (Heap[(curC + 1) * 2] > Heap[(curC + 1) * 2 - 1])
                {
                    int temp = Heap[curC];
                    Heap[curC] = Heap[(curC + 1) * 2];
                    Heap[(curC + 1) * 2] = temp;
                    curC = (curC + 1) * 2;
                }
                else
                {
                    int temp = Heap[curC];
                    Heap[curC] = Heap[(curC + 1) * 2-1];
                    Heap[(curC + 1) * 2-1] = temp;
                    curC = (curC + 1) * 2-1;
                }
            }
            foreach (int it in Heap)
            {
                if(it!=0)
                    Console.WriteLine(it);
            }
        }
    }
    
    internal class Program
    {
        public static void Main(string[] args)
        {
            PriorityQueue que = new PriorityQueue();
            que.push(1);
            que.push(2);
            que.push(4);
            que.push(5);
            que.push(7);
            Console.WriteLine(que.top());
            Console.WriteLine(que.pop());
            Console.WriteLine(que.pop());
        }
    }

在这里插入图片描述
主要思想是堆排序里面的维护大/小堆。
Top一直指向堆顶,而push/pop要维护堆,pop出的值是Top。(注意:大根堆和小根堆只需要堆顶最大/小就行!

伪代码方法:

push(参数)
{1.加入队尾
2.维护大/小根堆}

pop()
{1.返回堆顶
2.维护大/小根堆}
下面引用自:24只羊
堆和优先队列

2.1 堆中添加元素和Shift Up

img

现在我们要添加元素52,先添加到索引为10的位置,然而现在不满足二叉堆的性质,所以要调整52的位置,所以让52和自己的父亲节点依次与父亲节点相比较,如52大于父亲节点,就交换52与父亲节点的位置-------Shift
up

2.2 堆中取出元素(最大值)和Shift Down

img

img

我们先取出最大值62,因为将两颗子树融合成一棵树比较复杂,所以我们可以把最小值16换到根节点,然后在采用shift-down操作,

shift-down:把16与左右两个孩子节点相比较,选择两个孩子中最大的那个元素,如果最大的那个元素比16大,则将16与它交换,很显然52与16做交换

img

探后继续与41做交换

img

因为16比15大,所以就完成啦

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值