编程艺术第三章 找最小的K个数

来源:互联网 发布:c语言多线程函数 编辑:程序博客网 时间:2024/05/17 04:54

原题及解答出处http://blog.csdn.net/v_JULY_v/article/details/6370650

快速排序确定枢轴量的方法,确定了第K个枢轴量,那么继续递归之前的数组区间,就可以得到一个有序的K个数

推荐 http://www.cnblogs.com/morewindows/archive/2011/08/13/2137415.html 介绍的挖坑填数的解释

如果要选择一个特定的数作为枢轴量,只要将这个数与第一个数进行交换,那么这个算法仍然适用!

<pre name="code" class="cpp">// FindK.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include "stdio.h"#define K 3       //前4个最小的数int array[7] = {8,10,2,4,3,6,10};void swap(int &a, int &b){int tmp = a;a = b;b = tmp;}/*void partion(int left, int right){if (left < right){int mid = (left+right)/2;int pivot = array[mid];int i = left;int j = right;while(i < j){while(array[i] < pivot)       //当A[i] = A[j]时会出现死循环i++;while(array[j] > pivot)       j--;if (i < j)  //i > j说明越过了枢轴量,不用进行交换了swap(array[i], array[j]);}partion(left, i-1);if (i == K-1)return;partion(i+1, right);}}void partion(int left, int right){if (left <= right){int pivot = array[(left+right) / 2];int i = left;int j = right;while(i < j){while(array[i] < pivot)i++;      while(array[j] > pivot)j--;       if (i < j)  //i > j说明越过了枢轴量,不用进行交换了swap(array[i], array[j]);if(array[i] ==array[j]) //完全是为了避免死循环j--;} partion(left, i-1);//if (i == K-1)//return;partion(i+1, right);}}*/void partion(int left, int right)   //填坑补数法!!{if (left <= right){int pivot = array[left];//将第一个数存至局部枢轴量中,这样第一个数就可以空出来int i = left;int j = right;while(i != j){while(i < j && array[j] > pivot)j--;       if (i < j){array[i] = array[j];    //用j填i的坑,j是新坑i++;}while(i < j && array[i] < pivot)i++;      if (i < j){array[j] = array[i];    //用i填j的坑,i是新坑j--;}} array[i] = pivot;  //填i的坑if (i == K-1)return;partion(left, i-1);   //i的位置才是枢轴量后的位置partion(i+1, right);}}int main(int argc, char* argv[]){partion(0, 6);printf("%d", array[K-1]);return 0;}


方法二:堆排序,出堆K次即可,其中挖坑填数法再次出现,并且要注意下降的时候,选择的是子节点中的最小值进行交换。这一点要牢记

// FindK.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include "stdio.h"#define K 3       //前4个最小的数int array[8] = {0,8,10,2,3,3,6,10};void swap(int &a, int &b){int tmp = a;a = b;b = tmp;}void SiftDown(int low, int high){int i = low;int j = 2*i;int tmp = array[i];while(j <= high){if (j < high && array[j] > array[j+1]) //选择子孩子中最小的节点j++;if (tmp > array[j]){//swap(array[i], array[j]);  array[i] = array[j];      //利用好i这个坑,可以再每次循环中减少两次赋值操作,这样j成为新坑i = j;  //因为i = j,所以最后填坑的时候要填array[i]j = i * 2;}elsebreak;}array[i] = tmp;}void HeapSort(int n){int i;for (i = n/2; i >= 1; i--)SiftDown(i, n);for (i = n; i > n - K; i--){printf("%d", array[1]);swap(array[1], array[i]);SiftDown(1, i-1);}}int main(int argc, char* argv[]){HeapSort(7);return 0;}




0 0
原创粉丝点击