isSorted, what is wrong?

closed account (jvqpDjzh)
What is wrong with this function that tries to control if the array passed as first parameter is sorted?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//this function verifies if an integer array is sorted in a range
//returns false if low and high are not in the range: [0-length[ and low >= high 
//returns false if numbers[i] > numbers[i+1]: if the actual number is higher than the next one
//otherwise returns true
bool isSorted( const int* numbers, const int length, const int low, const int high )
{
	if ( low >= 0 && high < length && low < high ) {
		//if the range is composed by just 2 numbers
		if ( high - low == 1 ) {
			if ( numbers[low] > numbers[high] )
				return false;	
		} else {
			for ( int i = low; i< high - 1; i++ )//EDIT: ERRROOOOORRRR!!!!
				if ( numbers[i] > numbers[i + 1] )
					return false;
		}
	} else
		return false;
	
        return true;
}
Last edited on
What is wrong? Is it crashes? Is it not working? if so, give an example on data it fails to provide correct example.

Only mistake I see, on line 13 it should be i < high, because there high is a valid index and it should be checked.
closed account (jvqpDjzh)
Thank you!
Last edited on
closed account (jvqpDjzh)
So I don't need the if for the case where the range has just 2 numbers:
1
2
3
4
5
6
7
8
9
10
bool isSorted( const int* numbers, const int length, const int low, const int high )
{
	if ( low >= 0 && high < length && low < high ) {
		for ( int i = low; i< high; i++ ) 
			if ( numbers[i] > numbers[i + 1] ) 
				return false;
	} else 
		return false;
	return true;
}
Last edited on
You do not need to actually pass so many parameters.
It is enough to pass pointer to the first and to the last (or one-past-the-last to be concise with standard library) element.

After you write implementation for that, look into std::is_sorted function: http://www.cplusplus.com/reference/algorithm/is_sorted/
closed account (jvqpDjzh)
Something like this, but this one doesn't control if the pointers are pointing to the elements of the array:
1
2
3
4
5
6
7
8
9
10
11
bool isSorted( int* first, const int* one_past_the_last)

{
	while( first != one_past_the_last ){
		if(*first > *(one_past_the_last-1))

			return false;
		first++;
	}
	return true;
}
Last edited on
Your code checking only current and last valid elements. You should do something similar to:
1
2
3
4
5
6
7
8
9
10
bool isSorted( const int* first, const int* last)
{
    if (first == last) 
        return true;
    while (++first != last) {
            if (*first > *(first - 1))
                return false;
    }
    return true;
}

doesn't control if the pointers are pointing to the elements of the array
And it should not. Your prevous code does not check if array pointer indeed points to the array and if length is valid either.

And after implementing two-pointers variety of isSorted you might be surprised to know that there is standard function is_sorted which works not only on arrays, but on basically anything which supports iterators (raw pointers can be seen as raw arrays iterators)
Last edited on
closed account (jvqpDjzh)
Yes, silly I am, I have to think more when writing!
closed account (jvqpDjzh)
line 6 is:
1
2
3
4
5
6
7
8
bool isSorted( int* first, const int* one_past_the_last)
{
	while( ++first != one_past_the_last ){
		if(*first < *(first-1))//not ">"
			return false;
	}
	return true;
}
Oh yes, sorry.
Please note that your code is going to loop infinitely if first == one_past_the_last. It can happen when range is calculated by different functions (empty range is still a range and, therefore, valid). So replace != on line 3 with < (I left early return when translating from forward iterator based to pointer based function)

And first parameter should be const int* too.

const int* x; // or int const * x means that x is a mutable pointer to constant element, i.e. you can change pointer itself, but not the value it points to:
1
2
x += 1;//legal
*x = 1;//illegal 


int* const x; means that x is constant pointer to mutable element. You cannot make pointer poiint to another variable, but you can change value it points to:
1
2
x += 1;//illegal
*x = 1;//legal 


And finally const int* const x; // or int const * const x means that x is a constant pointer to constant element. You cannot change anything. Only read value it points to.
Last edited on
Is it legal to check a range of one element? It seems to me that a collection of 1 is always sorted. Currently your code says that it is always unsorted.
Is it legal to check a range of one element?
Yes it is.
It seems to me that a collection of 1 is always sorted
Yes it is. As is collection of 0 elements
Currently your code says that it is always unsorted.
Nope, while( ++first != one_past_the_last ) (or more correctly while( ++first < one_past_the_last )) will evaluate to false right away, making function to return true.
closed account (jvqpDjzh)
Yes, of course, you right!

Yes, about the pointers, I already known that, but sometimes I still get confused (but not so much by now).

Anyway, thank you! You helped much!
From OP
1
2
3
for ( int i = low; i< high - 1; i++ )//EDIT: ERRROOOOORRRR!!!!
				if ( numbers[i] > numbers[i + 1] )
					return false;

Should probably be
1
2
3
for ( int i = 0; i< length - 1; i++ )//EDIT: ERRROOOOORRRR!!!!
				if ( numbers[i] > numbers[i + 1] )
					return false;
He does check if numbers in range [low, high] are sorted with check if low and high indices are in array (in range [0, length])
Last edited on
closed account (jvqpDjzh)
@naraku9333 (1951)
What do you mean? The correct function verifies if a range of an array is sorted [low-high], not from 0, the first element of the array.
Last edited on
Topic archived. No new replies allowed.