Skip to content

Commit 491fa9a

Browse files
committed
修复顺序统计量最坏线性算法的bug
1 parent a2a9bca commit 491fa9a

File tree

4 files changed

+22
-12
lines changed

4 files changed

+22
-12
lines changed

chap09/order_statistic.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "../chap07/quick_sort.h"
99
#include "../utils.h"
1010
#include <stdlib.h>
11+
#include <stdio.h>
1112

1213
int minimum(int nums[], int len) {
1314
int min = nums[0];
@@ -49,7 +50,7 @@ int randomized_select(int nums[], int begin, int end, int i) {
4950
}
5051
}
5152
/**
52-
* 将数组5个一组进行分组,找出每组的中位数,返回这些中位数的中位数的下标
53+
* 将数组5个一组进行分组,找出每组的中位数,返回这些中位数的中位数
5354
*/
5455
int median_of_medians(int nums[], int begin, int end) {
5556
int len = end - begin;
@@ -58,24 +59,27 @@ int median_of_medians(int nums[], int begin, int end) {
5859
int part[5] = {0};
5960
if (last_part_len > 0) {
6061
parts_count++;
62+
} else {
63+
last_part_len = 5;
6164
}
62-
int *medians = malloc(parts_count * sizeof(int));
65+
// int *medians = malloc(parts_count * sizeof(int));
66+
int medians[parts_count];
6367
for (int i = 0; i < parts_count; i++) {
64-
for (int j = 0; j < 5; j++) {
65-
part[j] = nums[i*5+j];
66-
}
6768
int part_len = 5;
6869
if (i == parts_count-1) {
6970
part_len = last_part_len;
7071
}
72+
for (int j = 0; j < part_len; j++) {
73+
part[j] = nums[begin+i*5+j];
74+
}
7175
// 这里可以直接使用插入排序确定每组的中位数
7276
// 树上就是这样做而且证明这样整个算法还是最坏线性
7377
// 我的理解是因为每组的大小是常数
7478
insertion_sort(part, part_len);
7579
medians[i] = part[(part_len-1)/2];
7680
}
77-
int mm = medians[(parts_count-1)/2];
78-
free(medians);
81+
int mm = linear_select(medians, 0, parts_count, (parts_count-1)/2);
82+
// free(medians);
7983
return mm;
8084
}
8185

@@ -103,6 +107,7 @@ int linear_select(int nums[], int begin, int end, int i) {
103107
}
104108
// median_of_medians
105109
int mm = median_of_medians(nums, begin, end);
110+
106111
int q = specified_partition(nums, begin, end, mm);
107112
int left_len = q - begin;
108113
if (i == left_len) {

chap09/test_order_statistic.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,17 @@ static void test_order_statistic() {
88
int len = 100;
99
int nums[len];
1010
for (int i = 0; i < len; i++) {
11-
nums[i] = i;;
11+
nums[i] = i;
1212
}
1313
shuffle(nums, len);
1414
CU_ASSERT(maximum(nums, len) == len-1);
1515
CU_ASSERT(minimum(nums, len) == 0);
16-
for (int i = 1; i < len; i++) {
17-
CU_ASSERT(randomized_select(nums, 0, len, i) == i);
18-
//CU_ASSERT(linear_select(nums, 0, len, i) == i);
16+
printf("\n");
17+
for (int i = 0; i < 10; i++) {
18+
// CU_ASSERT(randomized_select(nums, 0, len, i) == i);
19+
int rst = linear_select(nums, 0, len, i);
20+
// printf("expect: %d, actually: %d\n", i, rst);
21+
CU_ASSERT_EQUAL(rst, i);
1922
}
2023
}
2124

test_main

80 Bytes
Binary file not shown.

utils.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ void print_array(int nums[], int len) {
1515
} else {
1616
printf("%d", nums[i]);
1717
}
18-
if (i !=0 && i%10 == 0) printf("\n");
18+
if (((i + 1) % 5 == 0) && (i != len - 1)) {
19+
printf("\n");
20+
}
1921
}
2022
printf("]\n");
2123
}

0 commit comments

Comments
 (0)