您的位置:首页 > 其它

堆实现

2015-07-08 00:00 309 查看
摘要: 堆排序算法

一、堆排序 (Heap sort)

定义: 完全二叉树的非终端节点的值均不大于(不小于)子节点的值

存储结构: 数组 | vector

逻辑结构: 完全二叉树

性质:

a. 节点编号 0...n-1

b. 节点i, 左字节点= 2*i+1, 右子节点 = 2*i + 2;

c. 最后一个非终端节点:n/2 - 1 (n为节点的个数)

要分析的问题:

1)如何由无序数组建立一个堆

for i = n/2 -1, n>=0; i--
heap_adjust(heap,i,n);   //向下调整当前i为根的树,从最后一个非终端节点开始

2)输出堆顶元素后如何继续调整剩余的堆

heap[0]= heap[n-1];
adjust(heap,0,n-1);  //从顶点向下开始调整

关键: heap_adjust (swift_down)向下调整函数

c语言实现

#include <stdio.h>
//从 1开始计数的最小堆
void heap_adjust(int heap[], int i,int len)
{
#if 0
//递归实现
int l = 2 * i + 1;
int r = l + 1;
int min = i;
if(l < len && heap[l] < heap[i])  min = l;
if(r < len && heap[r] < heap[min])  min = r;
if(min != i)
{
int tmp = heap[min];
heap[min] = heap[i];
heap[i] = tmp;
heap_adjust(heap,min,len);
}
#else
//非递归实现
int tmp = heap[i];  //暂时存储
int min;            //记录交换的节点
for(int k=i; k<len;)
{
int l = k * 2 + 1;
int r = l + 1;
min = k;
if(l < len && heap[l] < heap[k]) min = l;
if(r < len && heap[r] < heap[min]) min = k;

if(min == k)  break;
heap[k] = heap[min];
k = min;
}
heap[min] = tmp;
#endif
}
void build_heap(int heap[], int len)
{
for(int k = len/2-1; k >= 0; k--)
{
heap_adjust(heap,k,len);
}
}
void heap_sort(int heap[] ,int len)
{
build_heap(heap, len);

for(int i=len-1; i>0; i--){
printf("%d->%d.\n",len-i,heap[0]);
heap[0] = heap[i];
heap_adjust(heap,0,i);
}
}
int main()
{
int arr[] = {96,85,53,47,56,38,36,12,24};
heap_sort(arr,9);
//build_heap(arr,9);
return 0;
}

C++实现

ListNode* mergeKLists(vector<ListNode*>& lists) {   //合并K个sorted链表
if(lists.size() == 0)  return NULL;
// if(lists.size() == 1)  return lists[0];
vector<ListNode*> heap;
for(int i = 0; i<lists.size(); i++)
{
if(lists[i])
heap.push_back(lists[i]);
}
build_heap(heap);

ListNode dummy(-1);
ListNode *cur=&dummy;
ListNode *next;
while(!heap.empty())
{
cur->next = heap[0];
next = heap[0]->next;
cur = cur->next;
if(next == NULL){
//删除节点的方法,
heap[0]= heap.back();
heap.pop_back();
}
else{
heap[0] = next;  //
}
swift_down(heap,0);
}
return dummy.next;
}

void swap(ListNode *l1, ListNode *l2)
{
ListNode tmp = *l1;
*l1 = *l2;
*l2 = tmp;
}

void build_heap(vector<ListNode*> &heap){
int mid = heap.size() / 2 - 1;
for(int i = mid; i >= 0; i--)
swift_down(heap,i);
}
void swift_down(vector<ListNode*> &heap,int i){
int l = 2 * i + 1;
int r = l + 1;
int min = i;
int len = heap.size();

if(l < len && heap[l]->val < heap[i]->val)  min = l;
if(r < len && heap[r]->val < heap[min]->val)  min = r;
if(min != i)
{
swap(heap[min],heap[i]);
swift_down(heap,min);
}
}

/*  vector 实现的简单点
ListNode * pop_heap(vector<ListNode*> &heap)
{
if(heap.size() == 0) return NULL;
ListNode *ret  = head[0];
head[0] = heap[heap.size() - 1];  //最后节点赋值给第一个节点
heap.pop_back();   // 删除第一个节点
// heap.back() ;   //读取最后一个节点
swift_down(heap,0);
}
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  堆排序