1

Im currently trying to make a binary insert program, it reads a random number and inserts it in a sorted list, but every time I execute the program it just returns a list full of 0's I had this problem too when creating a normal insertion one. Even before sorting the list is full of 0's (aka no elements are ever assigned for some reason)

Here's the code:

program BinaryInsert;

function binaryfind(head, tail : integer; e : integer; vector: array of integer) : integer;  //uses binary search to find the right placement for e (element) inside the vector
var
    mid : integer;
begin
    mid := (head + tail) div 2;  //keep in mind that div returns the value rounded down
    if head <> tail then
    begin
       if vector[mid] >= e then  //>= garantees that this sorting method is stable
         binaryfind(mid+1, tail, e, vector)
       else
         binaryfind(head, mid, e, vector);
    end
    else
    begin
       if e >= vector[mid] then
         binaryfind := mid + 1  //it should take the place in front of mid (again >= garantees stability)
       else
         binaryfind := mid;  //it should take the place before mid
    end;
end;

procedure swap(e1, e2: integer);
var
    aux : integer;
begin
    aux := e1;
    e1 := e2;
    e2 := aux;
end;

procedure binaryinsert(e : integer; vector : array of integer);  //actual sorting happens here
var
    i, placement, l : integer;
begin
    l := Length(vector);
    placement := binaryfind(0, l-1, e, vector);
    vector[l] := e;
    for i := (l-1) downto (placement + 1) do
       swap(vector[i], vector[i-1]);  //reorganizes the array until the new element is at the correct placement
end;

procedure randomsorted(vector : array of integer);  //creates a sorted array with n random numbers
var
  i : integer;
begin
    for i := 0 to Length(vector)-1 do
       binaryinsert(random(9999), vector);
end;

var
  vector : array of integer ;
  e : integer;
begin
  SetLength(vector, 5);
  randomsorted(vector);
  for e in vector do
    writeln(e);
  readln(e);
end.

I was trying to get a list of sorted random integers

3
  • First of all, I don't get what your binaryfind needed for when you then still iterate over all all elements from the end to its final position ... Second: check what your binaryfind returns. Most certainly it doesn't return what you expect it to return, because 1) you don't use the result of your recursive call. I'd expect something like tmp := binaryfind(...) (but I admit my pascal is a bit rusty, so it might work diffent than other languages) 2) binary search won't work on an array like 1 5 0 0 0, because it's not sorted. It always return 32585 for me Commented Feb 9, 2024 at 15:52
  • And as for all such basic algorithms: Lean how to use a debugger. Try to understand your algorithm and what it should return in specific situations. Then use a debugger and strep through your program and you will see, when your program starts to differ from the expected results ... stackoverflow.com/questions/25385173/… Commented Feb 9, 2024 at 15:55
  • 2
    Note that swap effectively does nothing as written. You need to pass e1 and e2 as var. E.g. procedure swap(var e1, e2: integer); Commented Feb 10, 2024 at 0:43

2 Answers 2

2

Some observations: the call to random(9999); without a previous call to Randomize() always returns 0 as the first value in my test. For a true (semi)random series you should call Randomize() at beginning of the program.

However, during development, it might be useful to feed selected constant values, just to verify that the sorting works as it should.

Pay attention to the difference between Value and Variable parameters. You are passing vector in two places as a value parameter, but you want to retain the changes you do to the array, ergo, you should pass vector as a variable parameter.

Finally it seems binaryinsert() and binaryfind() need some attention. You are assigning new values to vector[l], which is past the end of the array. There might be other problems too.

Sign up to request clarification or add additional context in comments.

5 Comments

yeah the code still doesn't work so clearly there are other problems, but thanks for bringing those things to my attention, my teacher suddenly asked us to use pascal so many things just escaped me as I tried to learn it asap.
Thanks for feedback. I noticed that in binaryinsert you are swapping items unconditionally in the for -loop. Probably you should swap only if verctor[i] > vector[i-1]. If you have further problems, post a new question with current code, and I will have a look. Also note the comment by @Chris.
I see what he's trying to do. He's trying to add the new value to the vector at the end, and then shift it down to its proper place.
@James OP already said so in the first sentence: ...it reads a random number and inserts it in a sorted list...
@Tom Yeah, I was responding to your comment about him swapping unconditionally. If his binaryfind function worked the way he wanted it to (which it doesn't), then the list would already be sorted, and he'd have already done all the comparisons in that function, so he wouldn't have to compare again; he could just trust that binaryfind found the right spot to insert. He's just shifting the whole tail over one, to make a hole for his new entry.
1

Some thoughts on your binaryfind function:

Passing vector in by value instead of by reference will work in this function, since you only ever read it, but it's inefficient, since it makes a complete copy of the array. For a five element array, it's probably OK, but if you change that to a million elements, it'll probably get a little slower, and might overflow the stack.

The bigger issue, I think, is that vector is never initialized. I don't know what your processor does, but in ISO Standard Pascal, when a block is activated, all its contained variables are totally-undefined. It's an error to use an undefined variable in an expression. binaryfind does this a lot. Even an actual value parameter is an expression, so it happens on the function call too.

Your algorithm seems to assume initial zeroes in the array. If your processor isn't throwing uninitialized variable errors at you, then your array is probably initially full of random garbage (e.g. whatever's in the stack frame when the function is called). Even if you change vector to a var parameter everywhere, the definition of the global vector in the statement-part of the program-block will still be uninitialized. This will probably produce unexpected results, including things like negative integers in your final list.

Your algorithm is sorting from high to low. If this is what you want, then you should change >= to <= in the expression of the top-level else clause on line 17, so it matches the one on line 10 in the top-level if clause.

binaryfind is a function, and the standard says it must be a factor in an expression. You can't call it in a stand-alone statement, like a procedure. If you add binaryfind := before the two calls on lines 14 and 16, it will probably do what you intended. The function is being called recursively, and you need to pass the final value back up through all the nested calls.

Hope this helps. :)

EDIT: Seems like freepascal's setlength zeroes a dynamic array when expanding the size, so you might be alright on that point.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.