优先队列(堆)

来源:互联网 发布:入驻淘宝需要什么条件 编辑:程序博客网 时间:2024/05/17 08:55

http://www.cnblogs.com/skywang12345/p/3610187.html二叉堆的C语言实现

http://www.cnblogs.com/skywang12345/p/3610382.html二叉堆的C++实现


二叉堆分为两种:最大堆和最小堆

最大堆:父节点的键值总是大于或等于任何一个子节点的键值

最小堆:父节点的键值总是小于或等于任何一个子节点的键值

二叉堆一般都通过数组来实现:

将二叉堆的第一个节点放在数组索引0的位置上,则:

1)索引为i的左孩子的索引为 2*i+1

2)索引为i的右孩子的索引为 2*i+2

3)索引为i的父亲的索引为 floor((i-1)/2)

将二叉堆的第一个节点放在数组索引1的位置上,则:

1)索引为i的左孩子的索引为 2*i

2)索引为i的右孩子的索引为 2*i+1

3)索引为i的父亲的索引为 floor(i/2)

后文采用将二叉堆第一个节点放在数组索引0的位置上实现:

1.添加:(最大堆的插入代码)

1)将值插入最大堆末尾

2)若插入值大于父节点的值,则将它与父节点交换

3)直到挪不动为止

void push_up(int start) {//从start开始向上直到0,调整堆    int c = start;//当前节点的位置    int p = (c-1)/2;//当前节点的父节点    int t = m_heap[c];//当前节点的值    while(c > 0) {        if(m_heap[p] >= m_heap[c]) {            break;        }        m_heap[c] = m_heap[p];        c = p;        p = (c-1)/2;    }    m_heap[c] = t;}int Insert(int n) {//成功返回0,失败返回-1    if(m_size == MAX_SIZE) {        return -1;    }    m_heap[m_size] = n;//将要插入的值放在数组末尾    push_up(m_size);//向上调整堆    m_size++;//堆的大小加1    return 0;}

2.删除(从最大堆中删除元素)

1)删除该数据

2)用最大堆的最后一个元素插入这个空位

3)把这个“空位”尽量上挪,直到剩下的元素变成一个最大堆

int get_index(int data) {    //寻找data,找到则返回下标值,找不到,返回-1    for(int i = 0; i < m_size; i++) {        if(m_heap[i] == data) {            return i;        }    }    return -1;}void push_down(int start, int end) {    //start 被下调节点的起始位置    //end 截止范围,一般为数组最后一个元素的索引    int c = start;//当前位置    int l = c*2+1;//当前位置的左孩子    int t = m_heap[c];//当前位置的值    while(l <= end) {        //l为左孩子, l+1为右孩子        if(l < end && m_heap[l] < m_heap[l+1]) {            l++;//选取左右孩子中的较大者        }        if(t >= m_heap[l]) {            break;        }        c = l;        l = c*2+1;    }    m_heap[c] = t;}int delete(int data) {//成功返回0, 失败返回-1    if(m_size == 0) return -1;    int index = get_index(data);    if(index == -1) return -1;    m_heap[index] = m_heap[--m_size];//用最后元素填补    push_down(index, m_size-1);//从index位置从上到下调整为最大堆    return 0;}








0 0
原创粉丝点击