1

So in the programming course I'm taking we learned about recursion. I got an assignment to write recursive function that gets sorted array and a number and return the index of that number in the array if existed.

I didn't quite understand yet the subject of recursion so I need a little help with my code. I think i'm at the right direction but again, I'm a little struggling with the subject so I thought I could find guidance and help here.

this is the code I have at the moment:

private static int arrayIndexValue(int[] arr, int ind)
{
    if (ind > arr.Length/2)
    {
        return arrayIndexValue(arr.Length/2, ind)
    }
    else if (ind < arr.Length/2)
    {
        return arrayIndexValue(arr.Length/2)
    }
}

basically what i wanted to write here is something like this:

if the number the user inserts is smaller then the middle of the array, continue with the function but with the array cut in half (Binary search)

same if the number is bigger (i suggested to use my function with something like the binary search but as you can see i dont quite know how to apply it to my code)

8
  • So you want us to write the code for finding index? Umm.. that's not happening unless you show what have you tried Commented Apr 27, 2017 at 14:19
  • 1
    First off when you write a recursive funtion you have to have one or more base cases that return immediately then you break down the problem into pieces that will led to the base cases and then combine those results to return the result. Commented Apr 27, 2017 at 14:20
  • 5
    @Rahul Pretty sure they did show what they tried, which of course didn't work. Commented Apr 27, 2017 at 14:22
  • @Rhaul I dont want you to solve my homework at all. how did you get that from my question? what i want is someone help me understand a little better the subject of recursion so i could try and do my homework with some kind of understanding of the subject. Second, i did show you what i have. the code i posted here is what i have so far (it's not much because i dont understand the subject yet) Commented Apr 27, 2017 at 14:25
  • 1
    Look at the Wiki article : en.wikipedia.org/wiki/Binary_search_tree Commented Apr 27, 2017 at 14:35

4 Answers 4

2

Recursion works by breaking the entire problem into smaller parts. If you are at the smallest part (meaning that your array has only one value) then you would have your solution. This would also be your first case that you have to handle.

if (arr.Length == 1) return arr[0];

Now you can start to break down the problem. Binary left or right decision. As you already wrote you want to check weather the number is left or right from the middle of your array. So in your condition you need to access the element in the array using the [ ] operator:

if (ind > arr[arr.Length / 2]) // check if larger than the middle element

To extract a part of the array you need a second array in which you can copy the content that you want. Since you intend to pass only half of the current array into the recursive call you also need only half of the size.

int [] temp = new int[arr.Length / 2];

Now you can copy the part that you desire (first or second) depending on your condition and keep searching with a recursive call.

To copy the Array you can use the Arra.Copy method. You can pass the start and length to this method and it will copy the left or the right part into the int [] temp array. Here is an example of how to copy the right part:

Array.Copy(arr, arr.Length / 2, temp, 0, arr.Length / 2);

In the end you will need to fire your recursive call. This call will expect the new array and still the same number to look for. So since you copied either the left or right half of the previous array, now you pass the new short array to the recursive call:

return arrayIndexValue(temp, ind);

And there you have it

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

Comments

1

i got an assignment to write recursive function that gets sorted array and a number and return the index of that number in the array if existed.

In your method you check indexes, not values - you should compare values of elements, not indexes.

To write recursive function to find element you should pass array, element to find, start index and end index. Start index and end index will be used for finding in part of array.

Your method will be something like this:

private static int GetIndex(int[] arr, int element, int startIndex, int endIndex)
{
    if (startIndex > endIndex)
    {
        return -1; //not found
    }

    var middleIndex = (startIndex + endIndex) / 2;

    if (element == arr[middleIndex])
    {
        return middleIndex;
    }

    if (element < arr[middleIndex])
    {
        return GetIndex(arr, element, startIndex, middleIndex - 1);
    }
    else
    {
        return GetIndex(arr, element, middleIndex + 1, endIndex);
    }
}

and to get some index:

static void Main(String[] args)
{
    var arr = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

    var element = 5;
    var index = GetIndex(arr, element , 0, arr.Length - 1);
}

7 Comments

ok it's looks just like the definition of Binary search. but i got to write this kind of function with only a sorted array and a number. could this be done with only those two parameters?
@Dolev, you should somehow know the part of array which you should search for element in so, you need 4 parameters.
ok, i tried to do this exercise with only two parameters so i guess that's why i was struggling with it. i'll try to do it as all of you suggested with couple more parameters
@MongZhu oh sorry, jumped to conclusion to fast :P. thanks again for the help! i will follow your advice and figure out the solution for this problam!
@Dolev When you have figured out one solution, I will post the entire code, so that you can compare. :)
|
1

So the problem you have right now is that you haven't broken your problem into repeating steps. It actually should be very similar flow to a loop without all the variables. I want to do something a little simpler first.

void int find(int[] values, int at, int value) {
    if (values.Length >= at || at < 0) {
        return -1;
    } else if (values[at] == value) {
        return at;
    }
    return find(values, at+1, value);
}

This function just moves a index up one every time via recursion, but we can also do something very similar with a loop.

void int find(int[] values, int at, int value) {
    while (values.Length < at && at >= 0) {
        if (values[at] == value) {
            return at;
        }
        at = at + 1;
    }
    return -1;
}

The whole reason we usually talk about recursion is that it is usually used so that you have no "mutating" state. The variables and there values are the same for every value. You can break this, but it is usually considered beneficial. A quick stab at your problem produces something like

void int find(int[] sortedValues, int start, int end, int value) {
    var midIndex = (start + end) / 2;
    var mid = sortedValues[midIndex];
    if (start == end) {
        return mid == value ? midIndex : -1;
    } else if (mid > value) {
        return find(sortedValues, mid, end, value);
    } else if (mid < value) {
        return find(sortedValues, start, mid, value);
    } else {
        return midIndex;
    }
}

However, this isn't perfect. It has known issues like edge cases that would cause a crash. It should definitely be cleaned up a little. If you want to really want to dip your toe into recursion, try a purely functional language where you cannot mutate, like Haskell, Elm, or maybe something a little impure like F#, Clojure, or Scala. Anyway have fun.

Comments

0

Recursive Binary search using C# 12 in .NET 8.

I'm using Range operator introduced in C# 8 here. And using NUnit 3 for testing.

public static int BinarySearcher(int[] sortedItems, int item)
{
    // Base case
    if (sortedItems.Length == 0) return -1;
    
    var midIndex = sortedItems.Length / 2;
    var guess = sortedItems[midIndex];

    if (guess == item) return midIndex;
    
    // Recursive cases
    // 1. Throw away the right half and search again
    if (guess > item)
    {
        var leftHalf = sortedItems[..midIndex]; // Upper index is not included, so it has elements from start to midIndex - 1
        return BinarySearcher(leftHalf, item);
    }
    
    // 2. Throw away the left half and search again
    var rightHalf = sortedItems[(midIndex + 1)..];
    var result = BinarySearcher(rightHalf, item);
    // The returned index should be offset by midIndex + 1 for right half search
    return result == -1 ? -1 : midIndex + 1 + result;
}

And test it like:

using NUnit.Framework;

public class DivideAndConquerTests
{
    [Test]
    public void BinarySearcher_Finds_Item_Using_DAndC()
    {
        // Arrange
        int[] myList = [1, 3, 5, 7, 9];
        var myListItem = myList[3];
        // Act
        var searchedItemIndex = BinarySearcher(myList, myListItem);
        // Assert
        Assert.That(searchedItemIndex, Is.EqualTo(3));
    }

    [Test]
    public void BinarySearcher_Doesnt_Find_Item_Using_DAndC()
    {
        // Arrange
        int[] myList = [1, 3, 5, 7, 9];
        // Act
        var searchedItemIndex = BinarySearcher(myList, 10);
        // Assert
        Assert.That(searchedItemIndex, Is.EqualTo(-1));
    }
}

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.