Skip to content

Commit f3da506

Browse files
committed
完成第九章
1 parent 4a4dafe commit f3da506

File tree

6 files changed

+143
-15
lines changed

6 files changed

+143
-15
lines changed

chap07/quick_sort.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@
77
#include "../utils.h"
88
#include <stdlib.h>
99

10-
static int partition(int nums[], int begin, int end);
11-
static int randomized_partition(int nums[], int begin, int end);
12-
1310
int partition(int nums[], int begin, int end) {
1411
int small_top = begin;
1512
int key = nums[end-1];

chap07/quick_sort.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#ifndef QUICK_SORT_H
22
#define QUICK_SORT_H
33

4+
int partition(int nums[], int begin, int end);
5+
int randomized_partition(int nums[], int begin, int end);
46
void randomized_quick_sort(int nums[], int begin, int end);
57
void quick_sort(int nums[], int begin, int end);
68

chap09/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# 第九章 中位数和顺序统计量

chap09/order_statistic.c

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
/**
2+
* order_statistic.c
3+
* 顺序统计量
4+
*/
5+
6+
#include "order_statistic.h"
7+
#include "../chap02/insertion_sort.h"
8+
#include "../chap07/quick_sort.h"
9+
#include "../utils.h"
10+
#include <stdlib.h>
11+
12+
int minimum(int nums[], int len) {
13+
int min = nums[0];
14+
for (int i = 1; i < len; i++) {
15+
if (nums[i] < min) {
16+
min = nums[i];
17+
}
18+
}
19+
return min;
20+
}
21+
22+
int maximum(int nums[], int len) {
23+
int max = nums[0];
24+
for (int i = 1; i < len; i++) {
25+
if (nums[i] > max) {
26+
max = nums[i];
27+
}
28+
}
29+
return max;
30+
}
31+
32+
/**
33+
* 返回第i小的元素。最小的是第0小
34+
* 平均O(n)
35+
*/
36+
int randomized_select(int nums[], int begin, int end, int i) {
37+
int len = end - begin;
38+
if (len == 1) {
39+
return nums[begin];
40+
}
41+
int q = randomized_partition(nums, begin, end);
42+
int left_len = q - begin;
43+
if (i == left_len) {
44+
return nums[q];
45+
} else if (i < left_len) {
46+
return randomized_select(nums, begin, q, i);
47+
} else {
48+
return randomized_select(nums, q+1, end, i-left_len-1);
49+
}
50+
}
51+
/**
52+
* 将数组5个一组进行分组,找出每组的中位数,返回这些中位数的中位数的下标
53+
*/
54+
int median_of_medians(int nums[], int begin, int end) {
55+
int len = end - begin;
56+
int parts_count = len / 5;
57+
int last_part_len = len % 5;
58+
int part[5] = {0};
59+
if (last_part_len > 0) {
60+
parts_count++;
61+
}
62+
int *medians = malloc(parts_count * sizeof(int));
63+
for (int i = 0; i < parts_count; i++) {
64+
for (int j = 0; j < 5; j++) {
65+
part[j] = nums[i*5+j];
66+
}
67+
int part_len = 5;
68+
if (i > len / 5) {
69+
part_len = last_part_len;
70+
}
71+
insertion_sort(part, part_len);
72+
medians[i] = part[part_len/2];
73+
}
74+
int mm = linear_select(medians, 0, parts_count, parts_count/2);
75+
free(medians);
76+
return mm;
77+
}
78+
79+
/**
80+
* 以pivoit作为主元对数组进行partition。返回partition之后主元后的位置
81+
*/
82+
int specified_partition(int nums[], int begin, int end, int pivot) {
83+
int pivot_index = begin;
84+
for (; pivot_index < end; pivot_index++) {
85+
if (nums[pivot_index] == pivot) {
86+
break;
87+
}
88+
}
89+
swap(nums, end-1, pivot_index);
90+
return partition(nums, begin, end);
91+
}
92+
93+
/**
94+
* 最差O(n), 假设数组的数都是互异的
95+
*/
96+
int linear_select(int nums[], int begin, int end, int i) {
97+
int len = end - begin;
98+
if (len == 1) {
99+
return nums[begin];
100+
}
101+
// index of median_of_medians
102+
int imm = median_of_medians(nums, begin, end);
103+
int q = specified_partition(nums, begin, end, imm);
104+
int left_len = q - begin;
105+
if (i == left_len) {
106+
return nums[q];
107+
} else if (i < left_len) {
108+
return linear_select(nums, begin, q, i);
109+
} else {
110+
return linear_select(nums, q+1, end, i-left_len-1);
111+
}
112+
113+
}

chap09/order_statistic.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#ifndef ORDER_STATISTIC_H
2+
#define ORDER_STATISTIC_H
3+
4+
int minimum(int nums[], int len);
5+
int maximum(int nums[], int len);
6+
int linear_select(int nums[], int begin, int end, int r);
7+
int randomized_select(int nums[], int begin, int end, int r);
8+
9+
#endif

main.c

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
#include "chap07/quick_sort.h"
77
#include "chap08/counting_sort.h"
88
#include "chap08/radix_sort.h"
9+
#include "chap09/order_statistic.h"
10+
#include "chap15/cut_rod.h"
911
#include <stdio.h>
1012
#include <stdlib.h>
1113
#include <time.h>
@@ -14,19 +16,23 @@ int main() {
1416
srand(time(NULL));
1517
//int nums[] = {13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7};
1618
//int nums[10] = {1, 0, 4, 3, 7, 6, 5, 2, 9, 8};
17-
//int nums[100] = {
18-
// 71, 57, 79, 0, 60, 56, 89, 92, 87, 18, 43, 53, 86, 26, 15, 51, 73,
19-
// 65, 41, 42, 25, 62, 49, 28, 70, 78, 5, 85, 22, 69, 6, 93, 37, 4, 40,
20-
// 38, 77, 64, 76, 63, 94, 33, 21, 29, 35, 11, 12, 97, 48, 7, 17, 91,
21-
// 99, 8, 44, 24, 39, 83, 3, 52, 90, 95, 2, 10, 58, 88, 27, 14, 75,
22-
// 98, 66, 9, 68, 67, 55, 50, 16, 45, 59, 20, 54, 72, 32, 19, 84, 47,
23-
// 1, 80, 13, 36, 34, 96, 81, 31, 46, 30, 61, 23, 74, 82
24-
//};
25-
int nums[] = {49, 26, 64, 97, 59, 62, 76, 12, 76, 20, 5, 66, 60, 0, 28, 59, 9, 43, 5, 44, 27, 80, 80, 27, 10, 10, 14, 86, 7, 37, 39, 12, 27, 40, 46, 96, 93, 38, 11, 27, 56, 6, 75, 85, 12, 50, 49, 75, 63, 12, 11, 71, 28, 38, 0, 53, 96, 2, 99, 58, 85, 81, 88, 60, 73, 15, 86, 72, 63, 58, 47, 28, 59, 96, 62, 86, 73, 92, 50, 46, 60, 2, 23, 8, 42, 5, 11, 63, 60, 14, 50, 72, 28, 48, 82, 17, 15, 22, 68, 29};
26-
print_array(nums, 100);
27-
radix_sort(nums, 100);
19+
int nums[100] = {
20+
71, 57, 79, 0, 60, 56, 89, 92, 87, 18, 43, 53, 86, 26, 15, 51, 73,
21+
65, 41, 42, 25, 62, 49, 28, 70, 78, 5, 85, 22, 69, 6, 93, 37, 4, 40,
22+
38, 77, 64, 76, 63, 94, 33, 21, 29, 35, 11, 12, 97, 48, 7, 17, 91,
23+
99, 8, 44, 24, 39, 83, 3, 52, 90, 95, 2, 10, 58, 88, 27, 14, 75,
24+
98, 66, 9, 68, 67, 55, 50, 16, 45, 59, 20, 54, 72, 32, 19, 84, 47,
25+
1, 80, 13, 36, 34, 96, 81, 31, 46, 30, 61, 23, 74, 82
26+
};
27+
// int nums[] = {49, 26, 64, 97, 59, 62, 76, 12, 76, 20, 5, 66, 60, 0, 28, 59, 9, 43, 5, 44, 27, 80, 80, 27, 10, 10, 14, 86, 7, 37, 39, 12, 27, 40, 46, 96, 93, 38, 11, 27, 56, 6, 75, 85, 12, 50, 49, 75, 63, 12, 11, 71, 28, 38, 0, 53, 96, 2, 99, 58, 85, 81, 88, 60, 73, 15, 86, 72, 63, 58, 47, 28, 59, 96, 62, 86, 73, 92, 50, 46, 60, 2, 23, 8, 42, 5, 11, 63, 60, 14, 50, 72, 28, 48, 82, 17, 15, 22, 68, 29};
28+
int price_table[] = {0,1,5,8,9,10,17,17,20,24,30};
29+
//print_array(nums, 100);
30+
//int s = linear_select(nums, 0, 100, 10);
31+
//radix_sort(nums, 100);
2832
// subarr sa = maximum_subarray(nums, 0, 4);
29-
print_array(nums, 100);
33+
//print_array(nums, 100);
34+
int s = memoized_cut_rod(price_table, 10);
35+
printf("%d\n", s);
3036
//printf("left: %d, right: %d, sum: %d\n", sa.left, sa.right, sa.sum);
3137
return 0;
3238
}

0 commit comments

Comments
 (0)