intrandPartition(int A[],int low, int high){ int p = (int)(1.0 * rand() / RAND_MAX * (high - low) + low); swap(A[low], A[P]); //将此随机数指定的数字交换到序列头 temp = A[low]; while (low < high){ while (A[high] >= temp && low < high) high--; A[low] = A[high]; while (A[low] <= temp && low < high) low++; A[high] = A[low]; } A[low] = temp; return low; }
intrandSelect(int A[], int low, int high, int K){ if (low == high) return A[low]; int p = randPartition(A, low, high); //划分后枢轴位置 int M = p - low + 1; if (K == M) return A[p]; elseif(K > M) return randSelect(A, p + 1, high, K - M); elsereturn randSelect(A, left, p - 1, K) }
更优做法是利用随机选择算法,先求出原集合中元素的第 n / 2 大,然后根据这个数将集合分为两部分。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
intrandSelect(int A[], int low, int high, int K); //找出序列第K大的数
intmain(){ int i; int n; int sum1, sum2; sum1 = sum2 = 0; scanf("%d", &n); int *A = (int *)calloc(sizeof(int), n); for (i = 0; i < n; i++) scanf("%d", &A[i]); randSelect(A, 0, n - 1, n / 2); for (i = 0; i < n / 2; i++) sum1 += A[i]; for ( ; i < n; i++) sum2 += A[i]; printf("%d", sum2 - sum1); }