设为首页 加入收藏

TOP

二叉堆【转】(二)
2019-09-14 00:50:56 】 浏览:108
Tags:
,请参考下面的二叉堆的实现。

二叉堆的C实现(完整源码)

二叉堆的实现同时包含了"最大堆"和"最小堆",它们是对称关系;理解一个,另一个就非常容易懂了。

二叉堆(最大堆)的实现文件(max_heap.c)

/**
 * 二叉堆(最大堆)
 *
 * @author skywang
 * @date 2014/03/07
 */

#include <stdio.h>
#include <stdlib.h>

#define LENGTH(a) ( (sizeof(a)) / (sizeof(a[0])) )

static int m_heap[30];        // 数据
static int m_capacity=30;    // 总的容量
static int m_size=0;        // 实际容量(初始化为0)
 
/* 
 * 返回data在二叉堆中的索引
 *
 * 返回值:
 *     存在 -- 返回data在数组中的索引
 *     不存在 -- -1
 */
int get_index(int data)
{
    int i=0;

    for(i=0; i<m_size; i++)
        if (data==m_heap[i])
            return i;

    return -1;
}

/* 
 * 最大堆的向下调整算法
 *
 * 注:数组实现的堆中,第N个节点的左孩子的索引值是(2N+1),右孩子的索引是(2N+2)。
 *
 * 参数说明:
 *     start -- 被下调节点的起始位置(一般为0,表示从第1个开始)
 *     end   -- 截至范围(一般为数组中最后一个元素的索引)
 */
static void maxheap_filterdown(int start, int end)
{
    int c = start;          // 当前(current)节点的位置
    int l = 2*c + 1;     // 左(left)孩子的位置
    int tmp = m_heap[c];    // 当前(current)节点的大小

    while(l <= end)
    {
        // "l"是左孩子,"l+1"是右孩子
        if(l < end && m_heap[l] < m_heap[l+1])
            l++;        // 左右两孩子中选择较大者,即m_heap[l+1]
        if(tmp >= m_heap[l])
            break;        //调整结束
        else
        {
            m_heap[c] = m_heap[l];
            c = l;
            l = 2*l + 1;   
        }       
    }   
    m_heap[c] = tmp;
}

/*
 * 删除最大堆中的data
 *
 * 返回值:
 *      0,成功
 *     -1,失败
 */
int maxheap_remove(int data)
{
    int index;
    // 如果"堆"已空,则返回-1
    if(m_size == 0)
        return -1;

    // 获取data在数组中的索引
    index = get_index(data); 
    if (index==-1)
        return -1;

    m_heap[index] = m_heap[--m_size];        // 用最后元素填补
    maxheap_filterdown(index, m_size-1);    // 从index位置开始自上向下调整为最大堆

    return 0;
}

/*
 * 最大堆的向上调整算法(从start开始向上直到0,调整堆)
 *
 * 注:数组实现的堆中,第N个节点的左孩子的索引值是(2N+1),右孩子的索引是(2N+2)。
 *
 * 参数说明:
 *     start -- 被上调节点的起始位置(一般为数组中最后一个元素的索引)
 */
static void maxheap_filterup(int start)
{
    int c = start;            // 当前节点(current)的位置
    int p = (c-1)/2;        // 父(parent)结点的位置 
    int tmp = m_heap[c];        // 当前节点(current)的大小

    while(c > 0)
    {
        if(m_heap[p] >= tmp)
            break;
        else
        {
            m_heap[c] = m_heap[p];
            c = p;
            p = (p-1)/2;   
        }       
    }
    m_heap[c] = tmp;
}
  
/* 
 * 将data插入到二叉堆中
 *
 * 返回值:
 *     0,表示成功
 *    -1,表示失败
 */
int maxheap_insert(int data)
{
    // 如果"堆"已满,则返回
    if(m_size == m_capacity)
        return -1;
 
    m_heap[m_size] = data;        // 将"数组"插在表尾
    maxheap_filterup(m_size);    // 向上调整堆
    m_size++;                    // 堆的实际容量+1

    return 0;
}
  
/* 
 * 打印二叉堆
 *
 * 返回值:
 *     0,表示成功
 *    -1,表示失败
 */
void maxheap_print()
{
    int i;
    for (i=0; i<m_size; i++)
        printf("%d ", m_heap[i]);
}
    
void main()
{
    int a[] = {10, 40, 30, 60, 90, 70, 20, 50, 80};
    int i, len=LENGTH(a);

    printf("== 依次添加: ");
    for(i=0; i<len; i++)
    {
        printf("%d ", a[i]);
        maxheap_insert(a[i]);
    }

    printf("\n== 最 大 堆: ");
    maxheap_print();

    i=85;
    maxheap_insert(i);
    printf("\n== 添加元素: %d", i);
    printf("\n== 最 大 堆: ");
    maxheap_print();

    i=90;
    maxheap_remove(i);
    printf("\n== 删除元素: %d", i);
    printf("\n== 最 大 堆: ");
    maxheap_print();
    printf("\n");
}

二叉堆(最小堆)的实现文件(min_heap.c)

/**
 * 二叉堆(最小堆)
 *
 * @author skywang
 * @date 2014/03/07
 */

#include <stdio.h>
#include <stdlib.h>

#define LENGTH(a) ( (sizeof(a)) / (sizeof(a[0])) )

static int m_heap[30];
static int m_capacity=30;    // 总的容量
static int m_size=0;        // 实际容量(初始化为0)
 
/* 
 * 返回data在二叉堆中的索引
 *
 * 返回值:
 *     存在 -- 返回data在数组中的索引
 *     不存在 -- -1
 */
int get_index(int data)
{
    int i=0;

    for(i=0; i<m_size; i++)
        if (data==m_heap[i])
            return i;

    return -1;
}

/* 
 * 最小堆的向下调整算法
 *
 * 注:数组实现的堆中,第
首页 上一页 1 2 3 下一页 尾页 2/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇C语言链表初级 下一篇malloc,free,calloc,realloc函数

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目