寻找大富翁---HeapSort

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include <stdio.h>
#include <stdio.h>
void HeapAdjust(int H[],int s,int m);
void HeapSort(int H[],int length);
int main(){
    int n,m;
    int total[100000] = {0};
   
    while(scanf("%d %d",&n,&m)){
        if(n == 0 && m == 0){
            break;
        }
   
        for(int i = 0;i < n;i++){
            scanf("%d",&total[i]);
        }
 
        HeapSort(total,n);
 
        for(int i = n;i > n-m;i--){
            if( i != n-m+1)
            printf("%d ",total[i]);
            else
                printf("%d\n",total[i]);
    }
         
    }
    return0;
}
void HeapAdjust(int H[],int s,int m){
    int temp = H[s];//堆顶元素暂存
 
    //沿key较大的孩子结点向下筛选,直到叶子结点
    for(int j = 2*s;j <=m;j*=2){
        if(j <m && H[j]<H[j+1]){
            ++j;
        }
        //交换
        if(temp < H[j]){
            H[s] = H[j];
            s = j;
        }
        else{
            break;
        }
    }
 
    H[s] = temp;//temp应插入位置s上
}
 
void HeapSort(int H[],int length){
    //构建大根堆
    for(int i = length;i > 0;--i){
        HeapAdjust(H,i,length);
    }
 
    for(inti = length;i > 1;--i){
        inttemp;
        //与堆顶元素交换
        temp = H[i];
        H[i] = H[1];
        H[1] = temp;
 
        HeapAdjust(H,1,i-1);//将H【1,i-1】重新调整为大根堆
    }
}

/**************************************************************
     Problem: 1034
     User: qiujiaxin93
     Language: C
     Result: Accepted
     Time:30 ms
     Memory:1228 kb
****************************************************************/
写这篇文章的原因是这道题目整整纠结了我两天。这是九度的一道题目,
其实就是一个简单的排序问题,但是难点在有time limited,
所以用最简单的冒泡无法ac通过。后来换了快速排序,自己写的,
结果依然没有ac通过,还是卡在time limited上面,我是按照传统的
快排写的,并不是那种优化后的快排。
测试用例中 可能包含最坏的情况:
即将第一个数选定为key值,那么假如用例中恰好key值后面所有的数恰好均是比它小的数,
那么这个效率就非常低,可能是导致仍然无法
通过time limited的原因。
下面是快排失败的代码:
#include <stdio.h>
#include <stdlib.h>
void QuickSort(int R[],int start,int end);
int main(){
    int n,m;
    int total[100000];
  
    while(scanf("%d %d",&n,&m)){
        if(n == 0 && m == 0){
            break;
        }
  
        for(inti = 0;i < n;i++){
            scanf("%d",&total[i]);
        }
  
        QuickSort(total,0,n-1);
  
         if(m <= n)
                {
                        for(int i = 0; i < m; i++)
                        {
                                if(i != m -1)
                                        printf("%d ",total[i]);
                                else
                                        printf("%d\n",total[i]);
                        }
                }else
                {
                        for(int i = 0; i < n; i++)
                        {
                                if(i != n - 1)
                                        printf("%d ",total[i]);
                                else
                                        printf("%d\n",total[i]);
                        }
                }
        }
    return0;
}
     
void QuickSort(int R[],int start,intend){
        int i = start,j = end;
        int key;
 
        if(start < end){
            key = R[start];//以key作为基准元素进行划分
 
            while(i != j){
                //从后往前找小于key的
                while(i < j && R[j] < key){
                    j--;
                }
                R[i] = R[j];
                //从前往后找大于key的
                while(i < j && R[i] > key){
                    i++;
                }
                R[j] = R[i];
            }
 
            R[i] = key;//归为基准元素
            QuickSort(R,start,i-1);
            QuickSort(R,i+1,end);
    }
}


后来迫不得已才去复习了堆排序,一个是基本忘记得差不多了,
另一个是以前的学习也只是停留在伪代码上,没有解决过什么实际问题。
这一次好好写了一遍HeapSort,还是有收获的,堆排序用于在较多的数据中寻找极值,
效率最高。代码已经贴在上面了,学习学习。


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值