Find the smallest and second smallest elements in an array

Hi, how to find the smallest and second smallest elements in an array and the corresponding index number?

Hello
Post your current sketch, well formated, with comments and in code tags <"/"> to see how we can help.

Sort the array

1 Like

or if you don't want to go brute force,

  • find the smallest with one iteration
  • then iterate again and find the smallest that is not at the index you found for the first search (mind the edge case where the first entry is the minimum)

This is the Project Guidance board not Programming Questions, OP doesn't have to have done any code so far. Seems to me more like they're asking for advice on strategy.

To sort some numbers isn´t a project.

That was going to be my suggestion too, but then it struck me that "the corresponding index value" would be them wanting the original position not the sorted one, and that would get lost in the sort. J-M-L's idea is what I was then going to suggest.

something like this (typed here, untested)

byte data[] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9};
const byte cnt = sizeof data / sizeof data[0];

void setup() {
  Serial.begin(115200); Serial.println();

  byte i1 = 0;

  for (byte i = 1; i < cnt; i++)
    if (data[i] < data[i1]) i1 = i;

  Serial.print(F("Smallest : ")); Serial.print(data[i1]);
  Serial.print(F(" at index ")); Serial.println(i1);

  byte i2 = (i1 == 0) ? 1 : 0;
  for (byte i = 0; i < cnt; i++)
    if ((data[i] < data[i2]) && (i != i1)) i2 = i;

  Serial.print(F("Second smallest : ")); Serial.print(data[i2]);
  Serial.print(F(" at index ")); Serial.println(i2);

}

void loop() {}

By any project management definition of project it very probably is a project. Maybe a very small one, sure and sorry if it's beneath you, but if it almost certainly fits the PMI's definition:

any temporary endeavor with a definite beginning and end

Rather than iterate twice, just keep the two lowest:

  byte i1 = data[0] >= data[1]; // Index of smaller value
  byte i2 = data[0] < data[1];  // Index of larger (or equal) value

  for (byte i = 2; i < cnt; i++)
    if (data[i] <= data[i1]) 
    {
      i2 = i1;
      i1 = i;
    }
1 Like

Is this a school assignment?

hum... you don't know which data at index 0 or 1 is the smallest, so a bit of extra initialization work is required probably

What if there are more than one element that have the smallest and/or next smallest values?

Hence:

  byte i1 = data[0] >= data[1]; // Index of smaller value
  byte i2 = data[0] < data[1];  // Index of larger (or equal) value

If data[0] >= data[1], set i1 to 1 (true), else 0 (false)
If data[0] < data[1], set i2 to 1 (true), else 0 (false)

(In my first try I set i1 and i2 to 0 and 1, checked the data, and swapped the values if necessary.)

sorry, for some reason I did not see that.

Then you have changed the specification of the problem to be solved

There aren't. If there were the OP would have said "corresponding index numbers" instead of "corresponding index number".

What would you like to happen if there were multiple instances of both the lowest and second-lowest values? Which two indexes would you return, if you can only return two.

Okay. I see that now. Thanks for the corrections!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.