编程艺术之数组2.1 求最小的k个数

来源:互联网 发布:plc编程入门梯形图说明 编辑:程序博客网 时间:2024/05/14 02:01
/*输入 n 个整数,输出其中最小的 k 个*/#include<stdio.h>int sort(int *a, int left, int right){int tmp = a[left];while(left < right){while (left<right && a[right] >= tmp)right--;a[left] = a[right];while (left<right && a[left] <=  tmp)left++;a[right] = a[left];}a[left] = tmp;return left;}void quick_sort(int *a,int left,int right){if (left >= right)return;int i = sort(a, left, right);quick_sort(a, left, i - 1);quick_sort(a, i + 1, right);}void swap(int *a, int *b){*a = *a^*b;*b = *a^*b;*a = *a^*b;}//三数中值分割法int median3(int *a, int left, int right){int center = (left + right) / 2;if (a[left] > a[center])swap(&a[left], &a[center]);if (a[left] > a[right])swap(&a[left], &a[right]);if (a[center] > a[right])swap(&a[center], &a[right]);swap(&a[center], &a[right - 1]);return a[right - 1];}void Qselect(int *a,int k, int left, int right){int privot = median3(a, left, right);int i = left, j = right - 1;while (i < j){while (i < j && a[++i] < a[privot]);while (i<j && a[--j]>a[privot]);if (i < j)swap(&a[i], &a[j]);}//换枢纽元, 已经对要排序的数据都与枢纽比较了一次//把中枢纽保存在适当的位置,因为i的数一定比枢纽大      //所以把这个数放在数组后面 swap(&i, &right - 1);if (k <= i)Qselect(a, k, left, i - 1);else if (k > i + 1)Qselect(a, k, i + 1, right);}int main(void){int a[5] = { 5, 3, 4, 2, 1 };int k = 3;//前3个数int i;//方法一:从小到大排序找出前k个数//quick_sort(a,0,4);/*方法二:用快速排序先进行一遍排序,分成三部分:①如果S1>k,则k个数在其里面  ②S1+1=k,则k个数是S1+中间数③S1+1<k,则k个数包含了S1和中间数和S2中k-S1-1个数*//*int S1;S1 = sort(a, 0, 4);quick_sort(a, 0, S1 - 1);if (S1+1>k){quick_sort(a, S1 + 1, k);}*//*方法三:同方法二,但枢纽元采用三数中值分割法*/Qselect(a,k,0, 4);for (i = 0; i < k; i++)printf("%d ", a[i]);printf("\n"); return 0;}

0 0
原创粉丝点击