您的位置:首页 > 编程语言 > C语言/C++

优先队列(堆)

2016-06-30 11:16 204 查看
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c语言 heap