堆排序

堆排序

提供几种堆排序,各种方法,包括堆的各种基本操作;

 

 

 //堆排 1(侧重于删除顶元素及读入元素建堆)

#include<iostream>
#include<vector> 
#include<algorithm>
using namespace std;
int heap[1000];
int heap_size=0;
void put(int d)                 //heap[1]为堆顶  建堆
{
    int now, next;
    heap[++heap_size] = d;
    now = heap_size;
    while(now > 1)
    {
        next = now >> 1;
        if(heap[now] >= heap[next]) break;
        swap(heap[now], heap[next]);
        now = next;
    }
}
/*void put(int d)
{
    heap[++heap_size] = d;
    //push_heap(heap + 1, heap + heap_size + 1);            //大根堆
    push_heap(heap + 1, heap + heap_size + 1, greater<int>()); //小根堆
}*/
int get()                //heap[1]为堆顶   删除顶元素及确定新堆
{
    int now=1, next, res= heap[1];
    heap[1] = heap[heap_size--];
    while(now * 2 <= heap_size)
    {
        next = now * 2;
        if (next < heap_size && heap[next + 1] < heap[next]) next++;
        if (heap[now] <= heap[next]) break;
        swap(heap[now], heap[next]);
        now = next;
    }
    return res;
}
int main()
{
    int i=0;
    while(cin>>heap[++i]){
        put(heap[i]);
    }
    for(int j=1;j<i;++j){
        cout<<heap[1]<<" ";get();
    } 
    return 0;
}

 

//堆排2

 1 #include <iostream>
 2 #include <cstdio>
 3 using namespace std;
 4 int heap_size, n;
 5 int heap[100001];
 6 void swap(int &a, int &b)
 7 {
 8     int t = a;a = b;b = t;
 9 }
10 
11 void put(int d)
12 {
13     int now, next;
14     heap[++heap_size] = d;
15     now = heap_size;
16     while(now > 1)
17     {
18         next = now >> 1;
19         if(heap[now] >= heap[next])return;
20         swap(heap[now], heap[next]);
21         now = next;
22     }
23 }
24 int get()
25 {
26     int now, next, res;
27     res = heap[1];
28     heap[1] = heap[heap_size--];
29     now = 1;
30     while(now * 2 <= heap_size)
31     {
32         next = now * 2;
33         if(next < heap_size && heap[next + 1] < heap[next])next++;
34         if(heap[now] <= heap[next])return res;
35         swap(heap[now], heap[next]);
36         now = next;
37     }
38     return res;
39 }
40 
41 void work()
42 {
43     int i, x, y, ans = 0;
44     cin >> n;
45     for(i = 1 ; i <= n ; i++)
46     {
47         cin >> x;
48         put(x);
49     }
50     for(i = 1 ; i < n ; i++) cout << get() << ' ';
51     cout << get() << endl;
52 }
53 
54 int main()
55 {
56     //freopen("heapsort.in", "r", stdin);
57     //freopen("heapsort.out", "w", stdout);
58     work();
59     return 0;
60 }

 

 

//堆排3

 1 #include<iostream>
 2 using namespace std;
 3 int d[1000];
 4 int n,i,total,tmp;
 5 void down(int i)
 6 {
 7     int t,j;
 8     while(i<=total/2)
 9         {
10             j=2*i;
11             if((j<total)&&(d[j+1]<d[j])) j=j+1;
12             if(d[i]>d[j]) 
13                {
14                    t=d[i]; d[i]=d[j]; d[j]=t;
15                    i=j;
16                }
17             else break;
18         }
19     
20 }
21 int main()
22 {
23     cin>>n;
24     for (i=1;i<=n;i++) cin>>d[i];
25     total=n;
26     for(i=n/2;i>=1;i--) down(i);
27     for(i=1;i<=n;i++)
28         {
29             tmp=d[1];d[1]=d[total];d[total]=tmp;
30             total=total-1;
31             down(1);
32         }
33     for(i=n;i>=1;i--) cout<<d[i]<<" ";
34 }

 

//堆排4(利用heap函数,调用头文件(#include<algorithm>))

 1 #include<iostream>
 2 #include<algorithm>
 3 using namespace std;
 4 
 5 int heap[100010];
 6 
 7 bool cmp(int a,int b){ return a > b; }  //小根堆 
 8 
 9 int main()
10 {
11     int k;
12     cin>>k;
13     for(int i=0;i<k;++i)
14     {
15         cin>>heap[i];
16     }
17     make_heap(heap,heap+k,cmp);
18     for(int i= 0;i<k;i++) 
19     {
20         cout<<heap[0]<<" ";
21         //pop_heap(heap,heap+(k-i));  //pop删除后,自动建堆但是默认堆是大根堆 ,与make_heap相同 
22         pop_heap(heap,heap+(k-i),cmp);
23     }
24     
25     return 0;
26 }
27 
28 //pop测试 
29 /*for(int i=0;i<k;i++)
30         cout<<heap[i]<<" ";
31         cout<<endl;
32     pop_heap(heap,heap+k);
33     for(int i=0;i<k;i++)
34         cout<<heap[i]<<" ";*/

 

//参考(heap函数)

 1 /* 介绍algorithm头文件中根的相关函数 
 2     make_heap(首位置, 尾位置+1, 可选的cmp函数); -> 构造堆 
 3     push_heap(首位置, 尾位置+1, 可选的cmp函数); -> 添加元素到堆中 
 4     pop_heap(首位置, 尾位置+1, 可选的cmp函数);  -> 从堆中移出元素 
 5     sort_heap(首位置, 尾位置+1, 可选的cmp函数); -> 整个堆进行排序 
 6 */
 7 
 8 #include<algorithm>
 9 #include<cstdio>
10 using namespace std;
11 
12 bool inc_cmp(int a,int b){ return a > b; }
13 // 可以理解为:左a右b,当a>b的时候,双方交换位置,
14 // 所以上式这个cmp意为从小到大(排序)。 
15 
16 bool des_cmp(int a, int b){ return a < b; }
17 
18 int num[10]={3, 1, 2, 5, 6, 4};
19 
20 int main()
21 {    
22     make_heap(num, num+6);//构造一个堆,默认是大根堆。 
23                             // 上式等价于make_heap(&num[0], &num[6]);可以看到,区间是[0, 7),
24                             // 即参数中的末尾是真真实末尾的后一个位置。
25                             // 可以修改为make_heap(num, num+6, inc_cmp); 此时为小根堆。 
26                             
27                             // 插入一个元素到先前创建的堆中,插进来的数将调整到合适的位置。 
28     num[6] = 5;
29     push_heap(num, num+7);
30     
31                             // pop_heap将堆顶数据移动到末尾位置,然后将剩余数据重新构造堆。
32                             // 其中一个易于理解的例子就是,不断将大根堆堆顶移到末尾,
33                             // 以此模拟从小到大排序。 
34                             
35                             /* ---------- */ 
36     printf("before: "); 
37     for(int i = 0; i < 7; i++)
38         printf("%d ", num[i]);
39     printf("\n");
40     
41     for(int i = 7; i >= 1; i--) // 共7个数,交换到最后第二个数为止。 
42     {
43         pop_heap(num, num+i);
44     }
45     
46     printf("after : "); 
47     for(int i = 0; i < 7; i++)
48         printf("%d ", num[i]);
49     printf("\n");
50     /* ---------- */ 
51     
52     //sort_heap,堆排序,因为前面都pop_heap掉了,所以得重新make_heap
53     make_heap(num, num + 6); 
54     sort_heap(num, num+6, des_cmp);
55     for(int i = 0; i < 7; i++)
56         printf("%d ", num[i]);
57     printf("\n");
58     return 0;
59 }
posted @ 2017-03-31 16:20  MJT12044  阅读(192)  评论(0编辑  收藏  举报