Seeking the array k-th smallest number of the array required minimum number of k-th

Seeking the array k-th minimum number

I. Description of the problem

Given an array, the data array of the disorder, to find out the k-th smallest number in an array, for example arrays x, x = {3,2,1,4,5,6}, it first the minimum number of 2 2.


Second, problem-solving ideas

This algorithm is similar to the idea with the fast row, first select a number in the array as a hub centre, centre than small numbers, larger numbers than centre centre to the front and into the rear centre. If at this time was exactly Center position k, the Center for the k-th smallest number; Center at this time, if the previous position k, the k-th smallest number of certain behind centre, recursively find the right thereof; if at this position Center, the k-th smallest number of certain behind Center, recursively find the ratio of k to its left.


Note: position = Center value +1 subscript, as index of the first element of the array is zero.


From the above description, we can see that this algorithm uses a method of solving the reduction treatment. Less government's thinking and the partition is very similar, the same scale in one operation, reducing the problem, just divide and conquer to each sub-problem solving later, to merge solution to each sub-problem to get the problem, and rule reduction method, but do not merge sub-problem solution, the solution of the problem child, is a direct solution of the original problem. Take, for example, as fast row and binary search algorithm, the former is divide and conquer, which is cut rule. Because fast row until all the sub-arrays are exactly the sort, the original array was orderly, and binary search but do not have it every execute a search, discards half of the array, rather than merging sub-problem solution. But there are also many books to them the property of the divide and conquer.


Third, code implementation

Considering the universal code, using the template function, if not read a template function, you only need to ignore template <typename T>, and the T can be seen as a type. code show as below:


  
  
  1. // return start function array k-th smallest elements, attention will destroy the original array
  2. template< typename T>
  3. T FindTheKMin(T *x, int x_size, int k);
  4. // Find the array to achieve the K-th smallest element performance function
  5. template< typename T>
  6. T TheKMin(T *x, int left, int right, int k);
  7. template < typename T>
  8. T FindTheKMin(T *x, int x_size, int k)
  9. {
  10. // determines whether the value of k is too large, i.e. exceeds the size of the array
  11. // If the element 0 is returned, mainly to prevent invalid recursion
  12. if(x_size < k)
  13. return x[ 0];
  14. return TheKMin(x, 0, x_size -1, k);
  15. }
  16. template < typename T>
  17. T TheKMin(T *x, int left, int right, int k)
  18. {
  19. // get the last element of the array as a hub
  20. T centre = x[right];
  21. int i = left;
  22. int j = right - 1;
  23. while( true)
  24. {
  25. // back front scan, to find a value smaller than the first hub,
  26. // before reaching the end of the array, will the end of the cycle, because the last value centre
  27. while(x[i] < centre)
  28. ++i;
  29. // scan from back to front, this time to check the index against the array bounds
  30. while(j >= left && x[j] > centre)
  31. --j;
  32. // If the trip is not completed exchange, the exchange
  33. if(i < j)
  34. Swap(x[i], x[j]);
  35. else
  36. break;
  37. }
  38. // the hub in the right place
  39. Swap(x[i], x[right]);
  40. // If at this time was exactly centre position k, the k-th smallest centre number
  41. if(i+ 1 == k)
  42. return x[i];
  43. else if(i+ 1 < k)
  44. {
  45. // If at this time centre position than before k, recursively looking at its right
  46. TheKMin(x, i+ 1, right, k);
  47. }
  48. else
  49. {
  50. // If this time centre position than k, recursively looking to its left
  51. TheKMin(x, left, i -1, k);
  52. }
  53. }

Code Description:

In the above code, we should pay attention to the final if-else TheKMin function, this algorithm is different from fast row, when the hub is not to find the elements, it will only select sub-arrays continue to look in one direction, rather than fast row that will continue in the direction of the two sub-arrays. From the above point of view of the code, in which the speed should use the same strategy on fast row selected hub, the time complexity is O (N).


Meanwhile, when the K value is unreasonable, we can only return element 0, this is a little unreasonable, but I do not know what kind of return to a proper value, because it is generic.


In fact, there are two defective code, first, that when looking, destroyed the original data array (exchange position); the second is, when the copy type T and construction costs of large, multi directly secondary swap two elements, could bring considerable.


Another implementation

Next, look at another implementation, the same idea and the strategy algorithm, but uses a tracking array Track, to exchange information for tracking data using the first method, using the array element tracking array instead of the original exchange switching elements, solves two problems mentioned above. Its implementation is as follows:


  
  
  1. // returns an array of the smallest elements of the subject under startup function, does not destroy the original array
  2. template< typename T>
  3. int IndexOfKMin(const T *x, int x_size, int k);
  4. // Find the array to achieve the K-th subject of minimum performance function yuan
  5. template < typename T>
  6. int TheKMin(const T *x, int *track, int left, int right, int k);
  7. template < typename T>
  8. int IndexOfKMin(const T *x, int x_size, int k)
  9. {
  10. // determines whether the value of k is too large, i.e. exceeds the size of the array
  11. // If the superscript -1 is returned, mainly to prevent invalid recursion
  12. if(x_size < k)
  13. return -1;
  14. // Create a tracking array, which reads subscript original elements in the array,
  15. // exchanging recording element (i.e., instead of switching element)
  16. // in order to track the data in the array for the next access to standard elements, a method for accessing the same order of
  17. int *track = new int[x_size];
  18. for ( int I = 0 ; I <x_size; I ++) // initialize tracking array, which is the value corresponding to the value of the subscript
  19. track[i] = i;
  20. int i = TheKMin(x, track, 0, x_size -1, k);
  21. delete []track;
  22. return i;
  23. }
  24. template< typename T>
  25. int TheKMin(const T *x, int *track, int left, int right, int k)
  26. {
  27. // get the last element of the array as a hub
  28. T centre = x[track[right]];
  29. int i = left;
  30. int j = right - 1;
  31. while( true)
  32. {
  33. // back front scan, to find a value smaller than the first hub,
  34. // before reaching the end of the array, will the end of the cycle, because the last value centre
  35. // note data at this time is not the index i, but the track [i]
  36. while(x[track[i]] < centre)
  37. ++i;
  38. // After scanning forward from the index to be checked, to prevent cross-border array
  39. while(j >= left && x[track[j]] > centre)
  40. --j;
  41. // If the trip is not completed exchange, the exchange of note, is the value of the exchange tracking array
  42. if(i < j)
  43. Swap(track[i], track[j]);
  44. else
  45. break;
  46. }
  47. // the hub in the right place
  48. Swap(track[i], track[right]);
  49. // If at this time was exactly centre position k, the k-th smallest centre number,
  50. // returns to its index in the real array, i.e. track [i]
  51. if(i+ 1 == k)
  52. return track[i];
  53. else if(i+ 1 < k)
  54. {
  55. // If at this time centre position than before k, recursively looking at its right
  56. TheKMin(x, track, i+ 1, right, k);
  57. }
  58. else
  59. {
  60. // If this time centre position than k, recursively looking to its left
  61. TheKMin(x, track, left, i -1, k);
  62. }
  63. }

Code Description:

From the above code, we can see that this function returns the array element of the k-th smallest index, it is unreasonable when k, -1 can be represented by the error, while it uses a track array, the contents of track array, the substance is an index of the original data in the array, the exchange elements using the tracking arrays instead of exchange of the original array elements, because the data type of the tracking array is int, so its switching speed is quite fast , so as to solve the two problems mentioned above.


From the above code, we can also see that the time complexity of implementation is the same as the previous, but also for O (N), but the implementation has brought a certain amount of space overhead, it opens up a original equal to the number of array elements one-dimensional array, for tracking the exchange of information elements in the original array.

As for the practice, what kind of algorithm to be used, depending on the needs of the user!


Published 25 original articles · won praise 5 · Views 330

Guess you like

Origin blog.csdn.net/weixin_44602007/article/details/105057043