数据结构之堆(java实现,有排序功能)

/*
 * 文 件 名:  HeapNode.java
 * 修改时间:  2012-12-24
 */
package heap;

/**
 * 堆节点
 * @version  [版本号, 2012-12-24]
 */
public class HeapNode
{
    /**
     * 用于排序的关键字
     */
    int key;
    /**
     * 节点的数据
     */
    double dData;
    
    /**
     * <默认构造函数>
     */
    public HeapNode(int key, double dData)
    {
        this.key = key;
        this.dData = dData;
    }
    
    /** {@inheritDoc} */
    
    @Override
    public String toString()
    {
        return "HeapNode [dData=" + dData + ", key=" + key + "]";
    }
    
}
/*
 * 文 件 名:  Heap.java
 * 修改时间:  2012-12-24
 */
package heap;

/**
 * 数据结构之堆
 * @version  [版本号, 2012-12-24]
 */
public class Heap
{
    /**
     * 
     * 堆类型枚举
     * @version  [版本号, 2012-12-24]
     */
    enum HeapType
    {
        MAX, MIN
    }
    
    /**
     * 堆节点数组
     */
    private HeapNode[] data;
    /**
     * 堆得类型
     */
    private HeapType heapType;
    /**
     * 元素个数,如果大于数组长度,需要扩容
     */
    private int elementN;
    
    /**
     * <默认构造函数>
     */
    public Heap(HeapType heapType)
    {
        this(heapType, 20);
    }
    
    /**
     * <默认构造函数>
     */
    public Heap(HeapType heapType, int capacity)
    {
        this.heapType = heapType;
        data = new HeapNode[capacity];
        elementN = 0;
    }
    
    /**
     * 判断堆是否为空
     * @return
     * @see [类、类#方法、类#成员]
     */
    public boolean isEmpty()
    {
        return elementN == 0;
    }
    
    /**
     * 向堆中添加元素
     * @see [类、类#方法、类#成员]
     */
    public void addElement(int key, double dData)
    {
        HeapNode heapNode = new HeapNode(key, dData);
        //如果数组容量已满,则扩大一倍
        if (elementN >= data.length)
        {
            HeapNode[] newArray = new HeapNode[data.length * 2];
            System.arraycopy(data, 0, newArray, 0, data.length);
            data = newArray;
        }
        int currentIndex = elementN;
        data[elementN++] = heapNode;
        //下面从currentIndex索引开始回朔看看是否符合堆得特性
        while (currentIndex > 0)
        {
            //这里需要判断堆得类型,是最大堆还是最小堆
            if (heapType == HeapType.MAX && data[currentIndex].key <= data[(currentIndex - 1) / 2].key)
            {
                break;
            }
            else if (heapType == HeapType.MIN && data[currentIndex].key >= data[(currentIndex - 1) / 2].key)
            {
                break;
            }
            else
            {
                swapNode(currentIndex, (currentIndex - 1) / 2);
                currentIndex = (currentIndex - 1) / 2;
            }
        }
    }
    
    /**
     * 删除堆顶元素
     * @return
     * @see [类、类#方法、类#成员]
     */
    public HeapNode removeRoot()
    {
        HeapNode temp = null;
        if (!isEmpty())
        {
            temp = data[0];
            if (elementN > 1)
            {
                data[0] = data[elementN - 1];
                //下面向下遍历各节点保持堆特性,从0开始遍历到elementN-2
                reHeap(elementN - 2);
            }
            else
            {
                data[0] = null;
            }
            elementN--;
        }
        return temp;
    }
    
    /**
     * 将0到lastIndex的堆重新排列以符合堆得特性
     * @param lastIndex
     * @see [类、类#方法、类#成员]
     */
    private void reHeap(int lastIndex)
    {
        int currentIndex = 0;
        while (currentIndex * 2 + 1 <= lastIndex)
        {
            //如果有右节点
            if (currentIndex * 2 + 2 <= lastIndex)
            {
                //如果右节点的值大于左节点的
                if (data[currentIndex * 2 + 2].key >= data[currentIndex * 2 + 1].key)
                {
                    if (heapType == HeapType.MAX && data[currentIndex].key <= data[currentIndex * 2 + 2].key)
                    {
                        swapNode(currentIndex, currentIndex * 2 + 2);
                        currentIndex = currentIndex * 2 + 2;
                    }
                    else if (heapType == HeapType.MIN && data[currentIndex].key >= data[currentIndex * 2 + 1].key)
                    {
                        swapNode(currentIndex, currentIndex * 2 + 1);
                        currentIndex = currentIndex * 2 + 1;
                    }
                    else
                    {
                        break;
                    }
                }
                else
                {
                    if (heapType == HeapType.MAX && data[currentIndex].key <= data[currentIndex * 2 + 1].key)
                    {
                        swapNode(currentIndex, currentIndex * 2 + 1);
                        currentIndex = currentIndex * 2 + 1;
                    }
                    else if (heapType == HeapType.MIN && data[currentIndex].key >= data[currentIndex * 2 + 2].key)
                    {
                        swapNode(currentIndex, currentIndex * 2 + 2);
                        currentIndex = currentIndex * 2 + 2;
                    }
                    else
                    {
                        break;
                    }
                }
            }
            //如果没有右节点
            else
            {
                if (heapType == HeapType.MAX && data[currentIndex].key <= data[currentIndex * 2 + 1].key)
                {
                    swapNode(currentIndex, currentIndex * 2 + 1);
                    currentIndex = currentIndex * 2 + 1;
                }
                else if (heapType == HeapType.MIN && data[currentIndex].key >= data[currentIndex * 2 + 1].key)
                {
                    swapNode(currentIndex, currentIndex * 2 + 1);
                    currentIndex = currentIndex * 2 + 1;
                }
                else
                {
                    break;
                }
            }
        }
    }
    
    /**
     * 交换两个节点
     * @see [类、类#方法、类#成员]
     */
    private void swapNode(int index1, int index2)
    {
        HeapNode node = data[index1];
        data[index1] = data[index2];
        data[index2] = node;
    }
    
    /**
     * 返回堆中得元素个数
     * @return
     * @see [类、类#方法、类#成员]
     */
    public int getSize()
    {
        return elementN;
    }
    
    /**
     * 查看根元素
     * @return
     * @see [类、类#方法、类#成员]
     */
    public HeapNode getRoot()
    {
        HeapNode root = null;
        if (!isEmpty())
        {
            root = data[0];
        }
        return root;
    }
    
    /**
     * 遍历堆
     * @see [类、类#方法、类#成员]
     */
    public void displayHeap()
    {
        if (!isEmpty())
        {
            for (int i = 0; i <= elementN - 1; i++)
            {
                System.out.println(data[i].toString());
            }
        }
    }
    
    /**
     * 将堆中的元素排序
     * @see [类、类#方法、类#成员]
     */
    public void sort()
    {
        if (elementN > 1)
        {
            for (int i = elementN; i > 1; i--)
            {
                swapNode(0, i - 1);
                reHeap(i - 2);
            }
        }
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值