There are many different cases in which sorting an array can be useful. Algorithms (such as searching to see if a number exists in an array) can often be made simpler and/or more efficient when the input data is sorted. Furthermore, sorting is often useful for human readability, such as when printing a list of names in alphabetical order.
Sorting is generally performed by repeatedly comparing pairs of array elements, and swapping them if they meet some criteria. The order in which these elements are compared differs depending on which sorting algorithm is used, and the criteria depends on how the list will be sorted (ascending or descending order). To swap two elements, we can use the swap() function from the C++ standard library. Swap is defined in the algorithm header, and lives in the std namespace.
#include <algorithm> // for swap
#include <iostream>
int main()
{
using namespace std;
int x = 2;
int y = 4;
cout << "Before swap: x = " << x << ", y = " << y << endl;
swap(x, y); // swap also lives in std namespace
cout << "After swap: x = " << x << ", y = " << y << endl;
}
This program prints:
Before swap: x = 2, y = 4 After swap: x = 4, y = 2
Note that after the swap, the values of x and y have been interchanged!
Selection sort
There are many ways to sort an array. Selection sort is probably the easiest sort to understand, which makes it a good candidate for teaching even though it is one of the slower sorts.
Selection sort performs the following steps:
1) Starting at index 0, search the entire array to find the smallest value
2) Swap the smallest value found with the value at index 0
3) Repeat steps 1 & 2 starting from the next index
In other words, we’re going to find the smallest element in the array, and put it in the first position. Then we’re going to find the next smallest element, and put it in the second position. This process will be repeated until we run out of elements.
Here is an example of this algorithm working on 5 elements. Let’s start with a sample array:
{ 30, 50, 20, 10, 40 }
First, we find the smallest element, starting from index 0:
{ 30, 50, 20, 10, 40 }
We then swap this with the element at index 0:
{ 10, 50, 20, 30, 40 }
Now that the first element is sorted, we can ignore it. Consequently, we find the smallest element, starting from index 1:
{ 10, 50, 20, 30, 40 }
And swap it with the element in index 1:
{ 10, 20, 50, 30, 40 }
Find the smallest element starting at index 2:
{ 10, 20, 50, 30, 40 }
And swap it with the element in index 2:
{ 10, 20, 30, 50, 40 }
Find the smallest element starting at index 3:
{ 10, 20, 30, 50, 40 }
And swap it with the element in index 3:
{ 10, 20, 30, 40, 50 }
Finally, find the smallest element starting at index 4:
{ 10, 20, 30, 40, 50 }
And swap it with the element in index 4 (which doesn’t do anything):
{ 10, 20, 30, 40, 50 }
Done!
{ 10, 20, 30, 40, 50 }
Here’s how this algorithm is implemented in C++:
const int nSize = 5;
int anArray[nSize] = { 30, 50, 20, 10, 40 };
// Step through each element of the array
for (int nStartIndex = 0; nStartIndex < nSize; nStartIndex++)
{
// nSmallestIndex is the index of the smallest element
// we've encountered so far.
int nSmallestIndex = nStartIndex;
// Search through every element starting at nStartIndex+1
for (int nCurrentIndex = nStartIndex + 1; nCurrentIndex < nSize; nCurrentIndex++)
{
// If the current element is smaller than our previously found smallest
if (anArray[nCurrentIndex] < anArray[nSmallestIndex])
// Store the index in nSmallestIndex
nSmallestIndex = nCurrentIndex;
}
// Swap our start element with our smallest element
swap(anArray[nStartIndex], anArray[nSmallestIndex]);
}
The most confusing part of this algorithm is the nested loop. The outside loop (nStartIndex) steps through each element one by one. The inner loop (nCurrentIndex) finds the smallest element in the array starting from nStartIndex and sets the variable nSmallestIndex to point to it. The smallest index is then swapped with the start index. Then the outer loop (nStartIndex) advances one element, and the process is repeated.
Quiz
1) Selection sort the following array: { 30, 60, 20, 50, 40, 10 }. Show the array after each swap that takes place.
2) Rewrite the selection sort code above to sort in descending order (largest numbers first). Although this may seem complex, it is actually surprisingly simple.
Quiz solutions
6.5 — Multidimensional Arrays
|
Index
|
6.3 — Arrays and loops
|
6.5 — Multidimensional Arrays
Index
6.3 — Arrays and loops
I am having trouble (a lot) understanding classes; which from what I’ve read so far is crucial to understanding OOP… Any advice?? This tutorial is sweet by the way… Good job…
Jeff, I will be covering classes very shortly, as soon as I wrap up the section on functions. Outside of waiting for those tutorials, my advice (outside of actually purchasing a book) would be to search for “c++ classes” on Google and read everything you can. If you have any specific questions, feel free to post them in my forum and I will do my best to answer them.
hi,,,hope you mind,how can i sort a two dimensional array with series of characters through the use of selection sort method…??
Roseann, I’m not sure what it even means to sort a 2d array. Do you sort each row? Each column? The whole array and then list the results in rows? In columns? Without further information, the problem just doesn’t make sense.
Then what’s the faster and difficult to understand sort?
Will my small mind be able to understand that?
There are a large number of faster sorting algorithms. Two of the more popular faster sorts are quicksort and mergesort. However, sorting algorithms are really the topic for a data structures/algorithms class or tutorial (since they can be implemented in any language), not a C one. :)
See wikipedia for more information.
I didn’t compile this, so I could be wrong, but on line 5, shouldn’t the for loop expression be:
would that be a one off error?
The code was written to follow the 5-element example that proceeds it. You will note the last step in the example is redundant because it will always swap the last element with itself. Similarly, the last iteration of the outer loop will always cause the last element to be swapped with itself!
This doesn’t affect the correctness of the algorithm, it’s just non-optimal. As you note, changing the loop to
nStartIndex < (nSize - 1)removes this non-optimality.Generally when we talk about "off by one" errors, we're talking about errors that make the algorithm perform incorrectly because the loop executes one too many or too few times. In this case, the algorithm is correct, it just has a redundant step that can be removed by changing that loop condition.
ah, very clear. thanks
hi!!!!!oh please give me some points or idea on how to program the “bubble
sort” which will show all the passes and of course the sorted list inputed by
the user using c looping and array.pls..pls..pls…
tnx
Bubble sort works somewhat similarly to insertion sort. However, it uses a different array access pattern. Bubble sort works by comparing adjacent pairs of elements and swapping them if they are not in the correct order. Thus, it “bubbles” the largest or smallest element to the end of the array. Basically, the algorithm looks like this:
There’s a pretty good description of this algorithm, along with an example, on wikipedia.
Alex, you’re right about the inner nest being confusing! Again, for clarity on my part, I have converted this using while statments. The only part that is still a bit foggy is the incrementing statement in the nested loop. What keeps
in the nested loop from incrementing that loop before the incrementing statement at the bottom of the program
executes and causes the outer to increment? Or is the inner loop incrementing and cycling thru all of the index numbers before the outer loop begins its second loop?
btw: why dont the plus signs show up in the posted code?
int main() { using namespace std; const int nSize = 5; int anArray[nSize] = { 30, 50, 20, 10, 40 }; int nStartIndex = 0; while(nStartIndex < nSize) { int nSmallestIndex = nStartIndex; int nCurrentIndex = nStartIndex plus 1; while(nCurrentIndex < nSize) { if(anArray[nCurrentIndex] < anArray[nSmallestIndex]) nSmallestIndex = nCurrentIndex; nCurrentIndex; } swap(anArray[nStartIndex], anArray[nSmallestIndex]); cout << anArray[nStartIndex] << endl; nStartIndex; } return 0; }The inner loops runs through all it’s iterations before the outer loop is allowed to execute again.
It looks like plus symbols work for the initial response, but if you edit your posts, the AJAX editor seems to be stripping them out.
[ edit: I upgraded to a new version of the AJAX editor and it seems to fix that particular issue. -Alex ]
In the sort example/problem, it would seem that the output statement should read:
But this yields a funky output. The only thing that yields the output below
10
20
30
40
50
Press any key to conitiue…
is this output statement:
Can you elaborate on this a little more? Thanks.
anArray refers to the array itself, and the array variable is really just a pointer. So when you do this:
You're printing out the address held in anArray pointer (which as you say "yields funky output")
When you really want is to print the value of the ELEMENTS of anArray. To do that, you need to index the array using the [] operator -- in this case, the index is the value of nStartIndex.
Generally speaking, it's a better idea to sort your array and THEN re-loop through it to print out the sorted result. You could do this by adding the following lines:
for (int nIndex=0; nIndex < nSize; nIndex++) cout << anArray[nIndex] << endl;By the way, the issue with the disappearing + symbols should be fixed now.
C++ is definitely harder than MATLAB, but better in some ways.
The first quiz uses { 30, 60, 20, 40, 50, 10 }, but the answer appears to be using {30 60 20 50 40 10}.
Great tutorial btw
Yeah. It’s done sorting by the 3rd iteration of the outer loop, not the 4th like the answer shows.
attach the loop statement from the last lesson to the end of the for statement and see this program work through the sorting. Thought it was kinda neat how it works.
Who ever wrote this post thank you. The book i’m using gave me a horrible example for sorting. Great job who ever put this up.
I’m using Selection Sort as a function. Can I get the function to return the sorted array, or do I have to use it to change a global variable?
I think the best answer to your question is to pass your input array to the selection sort function by reference, which we cover in chapter 7.3.
how can you sort using characters with there lastname?and the inputted students are 10
how to do this program:
Write a program that will read N integers from keyboard input into an array. The size of the array N will be entered on the keyboard. The program will tabulate the output as shown below: tje first column should show list of distinct array elements sorted in ascending order, while the second column should show the number of occurrences of each element.
Sample input: 9 15 7 9 3 7 3 3 7 6 3 20
Expected output: N count
3 4
6 1
7 3
9 2
15 1
20 1
How to do that program?
puckundo@yahoo.com
hi alex, just want to clarify about the following: isnt it in the ff line, nStartIndex is already increased by 1? or will it be increased on its second loop? for (int nStartIndex = 0; nStartIndex < nSize; nStartIndex++) Because if its already increased by 1, then we dont need a variable to hold the value of the smallest number stored in the array.. please check and comment on my code: int anSort[]= { 30, 50, 20, 10, 40 }; for(int xxx=0;xxx<5;xxx++) for (int jjj = xxx;jjj<5;jjj++)//xxx is already incremented if anSort[jjj]< anSort[xxx] swap(anSort[xxx],anSort[jjj]);im just lost completely here, i ran through the code the first time, everything when fine, smallest to largest. then to switch it to largest to smallest i did exactly what the solution showed (before looking at it) and well… see for yourself
#include <stdafx.h> #include <iostream> #include <algorithm> int main() { using namespace std; const int nMaxArray = 6; int anArray[nMaxArray] = { 30, 60, 20, 50, 40, 10 }; for (int nStartingIn = 0 ; nStartingIn < 6 ; nStartingIn++) { int nSmallestIn = nStartingIn; for (int nCurrentIn = nStartingIn + 1 ; nCurrentIn < 6 ; nCurrentIn++) { if(anArray[nCurrentIn] > anArray[nSmallestIn]) nSmallestIn = nCurrentIn; swap(anArray[nSmallestIn],anArray[nStartingIn]); } for (int nCount = 0; nCount < 6 ; nCount++) { if (nCount < 6) cout << anArray[nCount] << " "; } cout << endl; } return 0; }#include <stdafx.h> #include <iostream> #include <algorithm> int main() { using namespace std; const int nMaxArray = 6; int anArray[nMaxArray] = { 30, 60, 20, 50, 40, 10 }; for (int nStartingIn = 0 ; nStartingIn < 6 ; nStartingIn++) { int nSmallestIn = nStartingIn; for (int nCurrentIn = nStartingIn + 1 ; nCurrentIn < 6 ; nCurrentIn++) { if(anArray[nCurrentIn] > anArray[nSmallestIn]) nSmallestIn = nCurrentIn; // swap(anArray[nSmallestIn],anArray[nStartingIn]); OLD LOCATION } swap(anArray[nSmallestIn],anArray[nStartingIn]); // NEW LOCATION for (int nCount = 0; nCount < 6 ; nCount++) { if (nCount < 6) cout << anArray[nCount] << " "; } cout << endl; } return 0; }You wait until you have found the smallest, THEN swap(). I commented out the old swap function, then located it outside the internal for loop.
*sigh* this padawan has much to learn yet still. Thanks alot for the help :)
Two questions, when the outerloop runs the first time nCurrentIndex is set to 1. If the nested loop runs all of its iterations before the outerloop can run again, then nCurrentIndex would get keep getting incremented by 1 until (nCurrentIndex < nSize) wasnt true. So does it then proceed to the swap() command?
Second, if thats true, then on the second round of the outerloop, does the nested loop reiterate (int nCurrentIndex = nStartIndex + 1)? I thought that ‘for loops’ only use the initializing statement once??? I have the program working, i am just not understanding how exactly it is working.
nevermind now i understand perfectly, just had to write out what was happening on paper so my brain could fathom it.
After following your lessons (Awesome, by the way) I always enjoy the quiz’s however I’ve been having some difficulty with this one. I tried the first question without out-right copying what you did but repeatedly got the same results. I compared yours against mine and changed my variable names to make the differences more obvious. I couldn’t see where I’d gone wrong. I opened a new project and copied your code (and added #include etc.) Yours worked fine.
My code reads:
#include "stdafx.h" #include <iostream> #include <algorithm> int main() { using namespace std; const int nSize = 6; int nStartIndex = 0; int anArray[nSize] = { 30, 60, 20, 50, 40, 10 }; //Display initial order for (int iii = 0; iii < 6; iii++) cout << anArray[iii] << ", "; cout << endl; for (int nStartIndex = 0; nStartIndex < nSize; nStartIndex++); { int nSmallestIndex = nStartIndex; for (int nCurrentIndex = nStartIndex + 1; nCurrentIndex < nSize; nCurrentIndex++) { if (anArray[nCurrentIndex] < anArray[nSmallestIndex]) nSmallestIndex = nCurrentIndex; } swap(anArray[nStartIndex], anArray[nSmallestIndex]); } for (int iii = 0; iii < 6; iii++) cout << anArray[iii] << ", "; cout << endl; return 0; }My other issue is that, whilst yours works straight off, mine refuses to compile unless nStartIndex is declared earlier whilst you don’t. Any ideas why that might be?
give me example of array (sorting/bubble)…
That is because you put ; after the for statement.
This is a usual mistake that begginers do.
Thanks! Man, that’s had me stumped for weeks!
hi haw are you i have a question when using insertion sort,bubble sort,selection sort,accept 10 students and then if the user inter 10 names without ascending order and then the user enter 1the output is insertion sort and inter 2 output is bubble like this how work this one pleas help me thanks good by
hi haw are you i have a question when using insertion,bubble,and selection sort.How can write a c++ program that accept 8-names and sort the names by using the above three sorting.Just forward your idea as soon as possible.Thanks for your contribution!!
how come there is no code for the solution to the first question? i cant seem to figure out how to output each completed array when the first element is swaped..
never mind, i got my code to work. the problem wasnt with my output part of the function, i wrote: nCurrentIndex = nSmallestIndex, instead of the other way around.
hello, i was wondering how swap works since you’re passing an argument by value, not reference, or am i missing something? just wondering, that’s all. great tutorials by the way
I am definitely new to programming, but so far I’m understanding everything reasonably well. I do have one question though. If you are re-initializing “nSmallestIndex” to a value of “nStartIndex” each time, why do you use “nSmallestIndex” in this part of your loop?
If the purpose of “nSmallestIndex” is just to temporarily hold the smallest index whilst you search the rest, wouldn’t it make more sense just to use “nStartIndex” and not bother giving “nSmallestIndex” a value of anything when it’s initialized, thus using “nSmallestIndex” Only as a temp holding place? I hope this is clear, I’m not a C++ pro like some of you. It just took me a while to understand it because of this seemingly unnecessary assignment. Please let me know if there is a good reason for doing so. Thanks -Zach
Disregard that. I figured it out. Upon further examination I realized that if you don’t continually check against your hold value, the last value that evaluated as “true” gets swapped, in this case 40. Had it been checking against nSmallestIndex, which gets incrementally smaller with each check, the loop would be checking 40 < 10 rather than 40 < 50. For the record, this is a hard concept to grab when your asked to write one off the top of your head lol. I hope I get quicker with this stuff.
hi
i m new to c++
could any one explain to me that how is this for for loops work
1)for (int nStartIndex = 0; nStartIndex < nSize; nStartIndex++)
2)for(int nCurrentIndex = nStartIndex + 1; nCurrentIndex < nSize; nCurrentIndex++)
thank
#include
using namespace std;
int main()
{
const int nSize=5;
int anArray[nSize]={30, 50, 20, 10, 40};
//cout<<anArray[nSize]<<endl;
for(int Indexzero=0;Indexzero<nSize;Indexzero++)
{
int nSmallestIndex=Indexzero;
//cout<<anArray[nSmallestIndex];
for(int nCurrentIndex=Indexzero;nCurrentIndex<nSize;nCurrentIndex++)
{
if(anArray[nCurrentIndex]<anArray[nSmallestIndex])
nSmallestIndex=nCurrentIndex;
//cout<<anArray[nSmallestIndex];
}
swap(anArray[Indexzero],anArray[nSmallestIndex]);
cout<<anArray[Indexzero]<< " "<<anArray[nSmallestIndex]<<endl;
cout<<endl;
}
system("pause");
return 0;
}
could anyone explain to me, please
results obtain 10 30
20 50
30 50
40 50
50 50
in my second for loop, i leave for int nCurrentIndex=Indexzero instead of int nCurrentIndex=Indexzero+1, but i still get the results. why?
results obtain
10 30
20 50
30 50
40 50
50 50