算法导论代码 第9章 中位数和顺序统计学
2011-12-30 15:48
399 查看
第9章 中位数和顺序统计学
9.1 最小值和最大值
#include <stdio.h> #include <stdlib.h> #include <time.h> #include <string.h> int minimum(int A[], int n) { int min = A[0]; for (int i = 1; i < n; i++) { if (min > A[i]) { min = A[i]; } } return min; } void min_and_max(int A[], int n, int *min, int *max) { int i; if (n % 2 == 1) { *min = A[0]; *max = A[0]; i = 1; } else { if (A[0] > A[1]) { *max = A[0]; *min = A[1]; } else { *max = A[1]; *min = A[0]; } i = 2; } for (; i < n; i += 2) { if (A[i] > A[i + 1]) { if (A[i] > *max) { *max = A[i]; } if (A[i + 1] < *min) { *min = A[i + 1]; } } else { if (A[i + 1] > *max) { *max = A[i + 1]; } if (A[i] < *min) { *min = A[i]; } } } } void print_array(int a[], int n) { for (int i = 0; i < n; i++) { printf("%d ", a[i]); } printf("\n"); } int main() { srand((unsigned)time(NULL)); int a[10]; for (int i = 0; i < 10; i++) { a[i] = rand() % 100; } print_array(a,10); printf("最小元素是:%d\n",minimum(a,10)); int min; int max; min_and_max(a,10,&min,&max); printf("最小和最大元素是:%d,%d\n",min,max); }
9.2 以期望线性时间做选择
#include <stdio.h> #include <stdlib.h> #include <time.h> #include <string.h> void swap(void *a, void *b, size_t elem_size) { if(a==NULL||b==NULL||a==b) return; char temp[elem_size]; /*变长数组 */ memcpy(temp, a, elem_size); memcpy(a, b, elem_size); memcpy(b, temp, elem_size); } int partition(void *base, size_t elem_size, int p, int r, int (*comp) (const void *, const void *)) { char *cbase = base; void *key = &cbase[r * elem_size]; int i = p - 1; for (int j = p; j < r; j++) { if (comp(&cbase[j * elem_size], key) <= 0) { ++i; swap(&cbase[i * elem_size], &cbase[j * elem_size], elem_size); } } swap(&cbase[(i + 1) * elem_size], key, elem_size); return i + 1; } int randomized_partition(void *base, size_t elem_size, int p, int r, int (*comp) (const void *, const void *)) { char *cbase = base; int i = rand() % (r - p + 1) + p; swap(&cbase[r * elem_size], &cbase[i * elem_size], elem_size); return partition(base, elem_size, p, r, comp); } void *randomized_select(void *base, size_t elem_size, int p, int r, int i, int (*comp) (const void *, const void *)) { char *cbase = base; if (p == r) return &cbase[p * elem_size]; int q = randomized_partition(base, elem_size, p, r, comp); int k = q - p + 1; if (i == k) { return &cbase[q * elem_size]; } else if (i < k) { return randomized_select(base, elem_size, p, q - 1, i, comp); } else { return randomized_select(base, elem_size, q + 1, r, i - k, comp); } } void print_array(int a[], int length) { for (int i = 0; i < length; i++) { printf("%d ", a[i]); } printf("\n"); } int cmp_int(const void *p1, const void *p2) { const int *pa = p1; const int *pb = p2; if (*pa < *pb) return -1; if (*pa == *pb) return 0; return 1; } void randomize_quick_sort(void *base, size_t elem_size, int p, int r, int (*comp) (const void *, const void *)) { if (p < r) { int q = randomized_partition(base, elem_size, p, r, comp); randomize_quick_sort(base, elem_size, p, q - 1, comp); randomize_quick_sort(base, elem_size, q + 1, r, comp); } } int main() { srand((unsigned)time(NULL)); int a[10]; for (int i = 0; i < 10; i++) { a[i] = rand() % 100; } printf("原数组:\n"); print_array(a, 10); int order = 3; int *select_value = randomized_select(a, sizeof(int), 0, 9, order, cmp_int); randomize_quick_sort(a, sizeof(int),0,9, cmp_int); printf("第%d小的元素是:%d\n", order, *select_value); printf("跟排序后的相应位置的值比较:%s\n", *select_value == a[order - 1] ? "相等" : "不相等"); return 0; }
9.3 最坏情况线性时间的选择
#include <stdio.h> #include <stdlib.h> #include <time.h> #include <string.h> void insertion_sort(void *base, size_t elem_size, size_t n, int (*comp) (const void *, const void *)) { char *cbase = base; char key[elem_size]; for (size_t i = 1; i < n; i++) { memcpy(key, &cbase[i * elem_size], elem_size); /*把base[i]插入到排好序的base[0..i-1]中 */ int j = i - 1; while (j >= 0 && comp(&cbase[j * elem_size], key) > 0) { memcpy(&cbase[(j + 1) * elem_size], &cbase[j * elem_size], elem_size); j--; } memcpy(&cbase[(j + 1) * elem_size], key, elem_size); } } void swap(void *a, void *b, size_t elem_size) { if (a == NULL || b == NULL || a == b) return; char temp[elem_size]; /*变长数组 */ memcpy(temp, a, elem_size); memcpy(a, b, elem_size); memcpy(b, temp, elem_size); } int partition(void *base, size_t elem_size, int p, int r, void *pivot, int (*comp) (const void *, const void *)) { char *cbase = base; void *key = pivot; int i = p - 1; int pivot_pos = p; /*主元的位置 */ for (int j = p; j < r; j++) { if (comp(&cbase[j * elem_size], key) == 0) pivot_pos = j; /*记录主元的位置 */ if (comp(&cbase[j * elem_size], key) <= 0) { ++i; swap(&cbase[i * elem_size], &cbase[j * elem_size], elem_size); } } swap(&cbase[(i + 1) * elem_size], &cbase[pivot_pos * elem_size], elem_size); return i + 1; } void *select(void *base, size_t elem_size, int p, int r, int order, int (*comp) (const void *, const void *)) { char *cbase = base; if (p == r) return &cbase[p * elem_size]; int n = r - p + 1; int array_count = n % 5 == 0 ? n / 5 : n / 5 + 1; char array[elem_size * array_count]; for (int i = 0; i < array_count; i++) { int begin = p + i * 5; int end = begin + 4 < r ? begin + 4 : r; insertion_sort(&cbase[begin * elem_size], elem_size, end - begin + 1, comp); int middle=begin+(end-begin)/2; memcpy(&array[i * elem_size], &cbase[middle * elem_size], elem_size); } void *x = select(array, elem_size, 0, array_count - 1, (array_count + 1) / 2, comp); /*用求得的划分的元素x来划分数组A,保证对数组的划分是好的划分 */ int q = partition(base, elem_size, p, r, x, comp); int k = q - p + 1; if (order == k) { return &cbase[q * elem_size]; } else if (order < k) { return select(base, elem_size, p, q - 1, order, comp); } else { return select(base, elem_size, q + 1, r, order - k, comp); } } void print_array(int a[], int length) { for (int i = 0; i < length; i++) { printf("%d ", a[i]); } printf("\n"); } int cmp_int(const void *p1, const void *p2) { const int *pa = p1; const int *pb = p2; if (*pa < *pb) return -1; if (*pa == *pb) return 0; return 1; } int main() { srand((unsigned)time(NULL)); int a[10]; for (int i = 0; i < 10; i++) { a[i] = rand() % 100; } printf("原数组:\n"); print_array(a, 10); int order = 3; int *select_value = select(a, sizeof(int), 0, 9, order, cmp_int); insertion_sort(a, sizeof(int), 10, cmp_int); printf("第%d小的元素是:%d\n", order, *select_value); printf("跟排序后的相应位置的值比较:%s\n", *select_value == a[order - 1] ? "相等" : "不相等"); return 0; }
相关文章推荐
- 算法导论学习笔记——第9章 中位数和顺序统计学
- 算法导论 第9章 中位数和顺序统计学(线性时间选择算法)
- 算法导论(第9章-中位数和顺序统计学)最大值和最小值
- 《算法导论》读书笔记之第9章 中位数和顺序统计学
- 算法导论学习笔记-第9章 中位数和顺序统计学
- 《算法导论》读书笔记之第9章 中位数和顺序统计学
- 《算法导论》读书笔记之第9章 中位数和顺序统计学
- 《算法导论》读书笔记之第9章 中位数和顺序统计学 最坏情况是线性时间的选择算法
- 算法导论第9章 中位数和顺序统计学
- 算法导论 第9章 中位数和顺序统计学(线性时间选择算法)
- 《算法导论》第9章 顺序统计学 (1)最小值和最大值
- 《算法导论》第9章 顺序统计学 (1)最小值和最大值
- 《算法导论》第9章 顺序统计学 (1)最小值和最大值
- 《算法导论的Java实现》 10 中位数和顺序统计学
- 算法导论——lec 09 中位数和顺序统计学
- 算法导论-------------中位数和顺序统计学
- 《算法导论》— Chapter 9 中位数和顺序统计学
- 《算法导论》第9章 顺序统计学 (2)随机选择
- 《算法导论》— Chapter 9 中位数和顺序统计学
- 算法导论 第9章 排序和顺序统计学算法导论