-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfindmink.c
More file actions
126 lines (118 loc) · 3.11 KB
/
findmink.c
File metadata and controls
126 lines (118 loc) · 3.11 KB
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/*
* =========================================================
* Filename: findmink.c
* Description: 基于快排的两种寻找pivot元素位置的方法
* 来实现寻找数列中最小的k个数字
*
* =========================================================
*/
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#define SWAP(a,b) do{int temp;temp=a;a=b;b=temp;}while(0)
typedef struct interval{
int left;
int right;
}Interval;
int findp_v1(int a[] , int left , int right);
Interval *findp_v2(int a[] , int left , int right);
int findmink(int a[],int left,int right,int k);
void print(int a[],int start,int end);
int main(){
long seed;
seed=time(NULL);
srand(seed);
int *a , n , k ,kth;
while(scanf("%d%d",&n ,&k) == 2){
a = malloc(sizeof(int) * n);
for(int i = 0; i < n ; ++i)
scanf("%d",a + i);
findmink(a , 0 , n-1 , k);
print(a , 0 ,k- 1);
free(a);
}
}
int findmink(int a[],int left,int right,int k){
// int p=k-1;
// Interval *inter;
// inter = findp_v2(a , left ,right);
// if(p >= inter->left && p <= inter->right)
// return k;
// else if(p < inter->left)
// return findmink(a , left ,inter->left -1 ,k);
// else
// return findmink(a , inter->right +1 ,right,k);
int p = findp_v1(a , left ,right);
if( p < k-1)
return findmink(a , p+1 , right , k);
else if(p > k-1)
return findmink(a , left , p-1 ,k);
else
return k;
}
int findp_v1(int a[] , int left , int right){ // left <= pivot <= right
//从[left , right]随机选出pivot元素
int random=rand()%(right-left+1)+left;
SWAP(a[left],a[random]);
int pivot=a[left];
int l = left + 1;
int r = right;
while(l < r){// l == r 时跳出循环
while(a[l] <= pivot && l < r)
++l;
while(a[r] >= pivot && l < r)
--r;
if(l < r)
SWAP(a[l] , a[r]);
}
if(a[l] >= pivot){
SWAP(a[l-1] , a[left]);
return l-1;
}
else{
SWAP(a[l] , a[left]);
return l;
}
}
/*
以[0,n-1]为例解释各个参数的含义
[1,l]<p l指向最后一个小于p的数
(r,n]>p r+1指向第一个大于p的数
(l,i)=p
[i,r] 未处理的数
*/
Interval *findp_v2(int a[] , int left , int right){
int random = rand() % (right - left + 1) + left;
SWAP(a[left] , a[random]);
int pivot = a[left];
int l=left,r=right;
int i;
for(i=left+1;i<=r;i++){
if(a[i]<pivot){
l++;
SWAP(a[l],a[i]);
}
else if(a[i]>pivot){
while(a[r]>pivot && r>=i)// important!!!
r--;
if(r>=i){
SWAP(a[r],a[i]);
r--;
if(a[i]<pivot){
l++;
SWAP(a[l],a[i]);
}
}
}
}
SWAP(a[left],a[l]);
Interval *inter = malloc(sizeof(Interval));
inter->left = l;
inter->right = r;
return inter;
}
void print(int a[],int start,int end){
int i;
for(i=start;i<=end;i++)
printf("%d%s",a[i],(i==end)?"\n":" ");
}