Bubble sort using recursion in C# - c#

I've wrote this simple piece of code. And I have a slight problem with it.
int [] x = [50,70,10,12,129];
sort(x, 0,1);
sort(x, 1,2);
sort(x, 2,3);
sort(x, 3,4);
for(int i = 0; i < 5; i++)
Console.WriteLine(x[i]);
static int [] sort(int [] x, int i, int j)
{
if(j ==x.length)
return x;
else if(x[i]>x[j])
{
int temp = x[i];
x[i] = x[j];
x[j] = temp;
return sort(x, i, j+1);
}
else
return sort(x, i, j+1);
}
I feel that calling sort 4 time isn't the best soultion. I need a way to handle this using sort() also. I also ask you for your advice, suggestion, or tip.
Thanks

Firstly, your sort is restricted to ints, however you can use the IComparable<T> interface to extend it to any comparable type. Alternatively you could have another parameter for a Comparer<T> to allow the user to define how to compare items in the input.
A recursive bubble sort would probably look something like this: (NOTE: not tested...)
public static T[] BubbleSort(T[] input) where T : IComparable<T>
{
return BubbleSort(input, 0, 0);
}
public static T[] BubbleSort(T[] input, int passStartIndex, int currentIndex) where T : IComparable<T>
{
if(passStartIndex == input.Length - 1) return input;
if(currentIndex == input.Length - 1) return BubbleSort(input, passStartIndex+1, passStartIndex+1);
//compare items at current index and current index + 1 and swap if required
int nextIndex = currentIndex + 1;
if(input[currentIndex].CompareTo(input[nextIndex]) > 0)
{
T temp = input[nextIndex];
input[nextIndex] = input[currentIndex];
input[currentIndex] = temp;
}
return BubbleSort(input, passStartIndex, currentIndex + 1);
}
However, an iterative solution would probably be more efficient and easier to understand...

A simple bubblesort shouldn't need recursion. You could do something like this, just passing in the array to sort:
public int[] Sort(int[] sortArray)
{
for (int i = 0; i < sortArray.Length - 1; i++)
{
for (int j = sortArray.Length - 1; j > i; j--)
{
if (sortArray[j] < sortArray[j - 1])
{
int x = sortArray[j];
sortArray[j] = sortArray[j - 1];
sortArray[j - 1] = x;
}
}
}
return sortArray;
}

Nothing wrong with wanting to learn - couple of obvious things.
Firstly you're already aware that there's a length property for the array - so you could use that to create a loop that gets rid of the multiple calls to sort at the start and makes the length of the array a non problem.
Secondly you might want to think about the way the sort works - how about this: you're attempting to bubble a value up to its correct place in the list (or down if you prefer!) - so for a list of n items, remove the first, sort the remaining n - 1 items (that's the recursive bit) then bubble the first item into place.
Been decades since I thought about this, fun!

another one with only 2 params :p yeah :
static void Sort(IList<int> data)
{
Sort(data, 0);
}
static void Sort(IList<int> data, int startIndex)
{
if (startIndex >= data.Count) return;
//find the index of the min value
int minIndex = startIndex;
for (int i = startIndex; i < data.Count; i++)
if (data[i] < data[minIndex])
minIndex = i;
//exchange the values
if (minIndex != startIndex)
{
var temp = data[startIndex];
data[startIndex] = data[minIndex];
data[minIndex] = temp;
}
//recurring to the next
Sort(data, startIndex + 1);
}
Note : This is completly useless in real life because
- its extremely slow
- its recursion iteration is linear meaning that when you have more than 1k items, it will stackoverflow

Related

Where is my mistake in solution of HackerRank - "Pairs" problem (rated medium)?

Given an array of integers and a target value, determine the number of pairs of array elements that have a difference equal to the target value.
Here is the link to the problem:
https://www.hackerrank.com/challenges/pairs/problem
My algorithm is supposed to do the following:
Sort the array
compare 2 neighbour numbers (i, i+1):
if difference between them is equal to given number k, increment
result
if the difference is less than given number, then compare i+1
with 0,...,i-1 elements to try to find possible pair among those.
if the difference is grater than given number k, then increment i and do the same for the next pair.
I think the algorithm is correct & I cannot find mistake in the implementation. My code passes main test cases & passes 5/18 additional test cases. Please help me find my mistake.
Here's my code:
public static int pairs(int k, List<int> arr)
{
arr.Sort();
var result = 0;
for (var i = 0; i < arr.Count - 1; ++i){
var diff = arr[i + 1] - arr[i];
if (diff > k) continue;
else if (diff == k) ++result;
else {
result = CompareWithPreviousValues(arr, k, i + 1, result);
}
}
return result;
}
private static int CompareWithPreviousValues(List<int> arr, int k, int indexOfElementToCompare, int result) {
var j = 2;
for (var i = indexOfElementToCompare; i - j >= 0; --i){
var diff = arr[i] - arr[i - j];
if (diff < k) ++j;
else if (diff == k){
++result;
return result;
}
else return result;
}
return result;
}
before posting the question, I went through the code once again and found the mistake I made.. But since there's no discussion on this problem in stackoverflow and it maybe interesting for some folks to find mistake in code, I decided to post it anyway. And I've spend time on filling in the question :D
So the mistake.. Of course it's a small one, but an unpleasing one.
DISCLAMER For those of you, who would like to find the mistake, I recommend not reading further below as there's the fixed code :D
The mistake is in the for loop of "CompareWithPreviousValues" method.
After each iteration, for some reason i was decreased. I probably wrote that i mechanically, as most loops are working with "i"s.
So here is the right version of the method:
private static int CompareWithPreviousValues(List<int> arr, int k, int n, int result) {
var j = 2;
for (var i = n; i - j >= 0; ++j){
var diff = arr[i] - arr[i - j];
if (diff < k) continue;
else if (diff == k){
++result;
return result;
}
else return result;
}
return result;
}

Quick Sort Implementation with large numbers [duplicate]

I learnt about quick sort and how it can be implemented in both Recursive and Iterative method.
In Iterative method:
Push the range (0...n) into the stack
Partition the given array with a pivot
Pop the top element.
Push the partitions (index range) onto a stack if the range has more than one element
Do the above 3 steps, till the stack is empty
And the recursive version is the normal one defined in wiki.
I learnt that recursive algorithms are always slower than their iterative counterpart.
So, Which method is preferred in terms of time complexity (memory is not a concern)?
Which one is fast enough to use in Programming contest?
Is c++ STL sort() using a recursive approach?
In terms of (asymptotic) time complexity - they are both the same.
"Recursive is slower then iterative" - the rational behind this statement is because of the overhead of the recursive stack (saving and restoring the environment between calls).
However -these are constant number of ops, while not changing the number of "iterations".
Both recursive and iterative quicksort are O(nlogn) average case and O(n^2) worst case.
EDIT:
just for the fun of it I ran a benchmark with the (java) code attached to the post , and then I ran wilcoxon statistic test, to check what is the probability that the running times are indeed distinct
The results may be conclusive (P_VALUE=2.6e-34, https://en.wikipedia.org/wiki/P-value. Remember that the P_VALUE is P(T >= t | H) where T is the test statistic and H is the null hypothesis). But the answer is not what you expected.
The average of the iterative solution was 408.86 ms while of recursive was 236.81 ms
(Note - I used Integer and not int as argument to recursiveQsort() - otherwise the recursive would have achieved much better, because it doesn't have to box a lot of integers, which is also time consuming - I did it because the iterative solution has no choice but doing so.
Thus - your assumption is not true, the recursive solution is faster (for my machine and java for the very least) than the iterative one with P_VALUE=2.6e-34.
public static void recursiveQsort(int[] arr,Integer start, Integer end) {
if (end - start < 2) return; //stop clause
int p = start + ((end-start)/2);
p = partition(arr,p,start,end);
recursiveQsort(arr, start, p);
recursiveQsort(arr, p+1, end);
}
public static void iterativeQsort(int[] arr) {
Stack<Integer> stack = new Stack<Integer>();
stack.push(0);
stack.push(arr.length);
while (!stack.isEmpty()) {
int end = stack.pop();
int start = stack.pop();
if (end - start < 2) continue;
int p = start + ((end-start)/2);
p = partition(arr,p,start,end);
stack.push(p+1);
stack.push(end);
stack.push(start);
stack.push(p);
}
}
private static int partition(int[] arr, int p, int start, int end) {
int l = start;
int h = end - 2;
int piv = arr[p];
swap(arr,p,end-1);
while (l < h) {
if (arr[l] < piv) {
l++;
} else if (arr[h] >= piv) {
h--;
} else {
swap(arr,l,h);
}
}
int idx = h;
if (arr[h] < piv) idx++;
swap(arr,end-1,idx);
return idx;
}
private static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
public static void main(String... args) throws Exception {
Random r = new Random(1);
int SIZE = 1000000;
int N = 100;
int[] arr = new int[SIZE];
int[] millisRecursive = new int[N];
int[] millisIterative = new int[N];
for (int t = 0; t < N; t++) {
for (int i = 0; i < SIZE; i++) {
arr[i] = r.nextInt(SIZE);
}
int[] tempArr = Arrays.copyOf(arr, arr.length);
long start = System.currentTimeMillis();
iterativeQsort(tempArr);
millisIterative[t] = (int)(System.currentTimeMillis()-start);
tempArr = Arrays.copyOf(arr, arr.length);
start = System.currentTimeMillis();
recursvieQsort(tempArr,0,arr.length);
millisRecursive[t] = (int)(System.currentTimeMillis()-start);
}
int sum = 0;
for (int x : millisRecursive) {
System.out.println(x);
sum += x;
}
System.out.println("end of recursive. AVG = " + ((double)sum)/millisRecursive.length);
sum = 0;
for (int x : millisIterative) {
System.out.println(x);
sum += x;
}
System.out.println("end of iterative. AVG = " + ((double)sum)/millisIterative.length);
}
Recursion is NOT always slower than iteration. Quicksort is perfect example of it. The only way to do this in iterate way is create stack structure. So in other way do the same that the compiler do if we use recursion, and propably you will do this worse than compiler. Also there will be more jumps if you don't use recursion (to pop and push values to stack).
That's the solution i came up with in Javascript. I think it works.
const myArr = [33, 103, 3, 726, 200, 984, 198, 764, 9]
document.write('initial order :', JSON.stringify(myArr), '<br><br>')
qs_iter(myArr)
document.write('_Final order :', JSON.stringify(myArr))
function qs_iter(items) {
if (!items || items.length <= 1) {
return items
}
var stack = []
var low = 0
var high = items.length - 1
stack.push([low, high])
while (stack.length) {
var range = stack.pop()
low = range[0]
high = range[1]
if (low < high) {
var pivot = Math.floor((low + high) / 2)
stack.push([low, pivot])
stack.push([pivot + 1, high])
while (low < high) {
while (low < pivot && items[low] <= items[pivot]) low++
while (high > pivot && items[high] > items[pivot]) high--
if (low < high) {
var tmp = items[low]
items[low] = items[high]
items[high] = tmp
}
}
}
}
return items
}
Let me know if you found a mistake :)
Mister Jojo UPDATE :
this code just mixes values that can in rare cases lead to a sort, in other words never.
For those who have a doubt, I put it in snippet.

Union of two arrays

Given two arrays
int arr1[n]
int arr2[m]
where n > m
Need to write a union of two arrays into one.
For example, if the input arrays are:
int arr1[] = {1, 3, 4, 5, 7}
int arr2[] = {2, 3, 5, 6}
Then program should create new array Union as {1, 2, 3, 4, 5, 6, 7}
Implementation can be in C# or Java.
In order to solve it first of all need to to sort the arrays using Merge Sort
and then do the union
I looked in the net but did not find the elegant way . Every code that I looked
was full of IF's.
Please advice what is the most quick and elegant way to do it
You are correct that merging the two lists as is done in Merge Sort is the most efficient thing to do. This assumes that the two lists are already sorted, as in your example. Here is an example of how to implement merge:
function merge(left,right)
var list result
while length(left) > 0 or length(right) > 0
if length(left) > 0 and length(right) > 0
if first(left) ≤ first(right)
append first(left) to result
left = rest(left)
else
append first(right) to result
right = rest(right)
else if length(left) > 0
append first(left) to result
left = rest(left)
else if length(right) > 0
append first(right) to result
right = rest(right)
end while
return result
From here, simply do not include repeats in the final output.
If its an elegant MergeSort you are looking then nothing is more elegant than a recursive function :-)
Here it is :
This is a divide and conquer strategy. We basically divide the array into smaller arrays , sort the smaller arrays and merge them back.
public static void mergesort(int a[],int left, int right){
/*
* Time : O(n log n)
* Space : O(n)
*/
int b[] = new int[right -left+1];
domergesort(a,left,right,b);
}
public static void domergesort(int a[],int left,int right, int b[]){
if(left < right){
int mid = (left+right)/2;
domergesort(a,left,mid,b);
domergesort(a,mid+1,right,b);
merge(a,left,mid,a,mid+1,right,b);
for(int k=left;k<=right;k++)
a[k] = b[k-left];
}
}
Not many ifs too ..
Source : My Blog (http://cloudingitup.blogspot.com/p/reading-guide-arrays.html)
To merge them together as a Union :
public static void merge( int a[], int al, int ar, int b[], int bl, int br, int c[]){
// al : a's left index ar : a's right index c: merged array
int i= al;
int j = bl;
int k=0;
int prev = c[0];
while ( i<= ar && j <= br){
if (a[i] <= b[j])
if (prev != a[i]) // Too keep the union distinct
c[k++] = a[i++];
else
i++;
else
if (prev != b[j]) // Too keep the union distinct
c[k++] = b[j++];
else
j++;
prev = c[k-1];
}
while (i <= ar)
{
if (prev != a[i])
c[k++] = a[i++];
else
i++;
prev = c[k-1];
}
while (j <= br)
{
if (prev != b[j])
c[k++] = b[j++];
else
j++;
prev = c[k-1];
}
}
A driver code to illustrate the code :
int arr1[] = {1,1, 3, 4,4,4,5, 7};
int arr2[] = {2, 3, 5, 6,6,8};
int c[] = new int[8];
merge(arr1,0,7,arr2,0,5,c);
for(int i=0;i<8;i++)
System.out.print(c[i]);
Output: 12345678
public static void printUnion(int ar1[],int ar2[]) {
int m = ar1.length;
int n = ar2.length;
int i=0,j=0;
while(i<m && j<n) {
if( ar1[i] <ar2[j]) {
System.out.println(ar1[i]);
i++;
}else if(ar1[i] > ar2[j]) {
System.out.println(ar2[j]);
j++;
}else {
System.out.println(ar1[i]);
i++;
j++;
}
}
while(i < m)
System.out.println(ar1[i++]);
while(j < n)
System.out.println(ar2[j++]);
}
Same code will work for intersection with minimal changes....
In interviews, they usually want to see you solve the problem, rather than using library calls (e.g. arr1.union(arr2) probably wouldn't cut it.)
This is off the top of my head, but something like this should work, and I think is O(n^2). It assumes both arrays are sorted.
union.rb
arr1 = [0,2,4,9,11,12,13]
arr2 = [3,4,7,9,10,11]
def union(n, m)
if n.last > m.last
arr1 = n; arr2 = m
else
arr1 = m; arr2 = n
end
union_array = []
j = 0
arr1.each do |x|
while j < arr2.length && arr2[j] < x
if arr2[j] < x
union_array << arr2[j] unless arr2[j] == union_array.last
j += 1
end
end
union_array << x
end
union_array
end
puts union(arr1, arr2)
this method should work fairly well, and it will decide which array is bigger so there doesn't need to necessarily be a defined order.
Java:
public static <T> T[] combine(T[] a1, T[] a2)
{
return combine(a1, a2, a1.length + a2.length);
}
public static <T> T[] combine(T[] a1, T[] a2, int maxlength)
{
T[] front = null;
T[] back = null;
if(a1.length >= a2.length)
{
front = a1;
back = a2;
}
else
{
front = a2;
back = a1;
}
int len = front.length + back.length;
if(len > maxlength)
{
len = maxlength;
}
int n = 0;
T[] result = Arrays.copyOf(front, len);
int c = 0;
for(int i = 0;i < front.length;i++)
{
if(i < front.length && c < result.length)
{
result[c] = front[i];
c++;
}
if(i < back.length && c < result.length)
{
result[c] = back[i];
c++;
}
}
return result;
}
this is obviously not the most efficient method, but it does completely work. It also includes a capping, if you want to merge them, but only get the first, let's way 5 items, then you can add a parameter of 5 to the method.
You can actually get rid of a lot of waste, there's a lot of messy stuff in here, I'm away from my IDE so it's off my head, I may have stuff that's not needed.

Find the first occurrence/starting index of the sub-array in C#

Given two arrays as parameters (x and y) and find the starting index where the first occurrence of y in x. I am wondering what the simplest or the fastest implementation would be.
Example:
when x = {1,2,4,2,3,4,5,6}
y = {2,3}
result
starting index should be 3
Update: Since my code is wrong I removed it from the question.
Simplest to write?
return (from i in Enumerable.Range(0, 1 + x.Length - y.Length)
where x.Skip(i).Take(y.Length).SequenceEqual(y)
select (int?)i).FirstOrDefault().GetValueOrDefault(-1);
Not quite as efficient, of course... a bit more like it:
private static bool IsSubArrayEqual(int[] x, int[] y, int start) {
for (int i = 0; i < y.Length; i++) {
if (x[start++] != y[i]) return false;
}
return true;
}
public static int StartingIndex(this int[] x, int[] y) {
int max = 1 + x.Length - y.Length;
for(int i = 0 ; i < max ; i++) {
if(IsSubArrayEqual(x,y,i)) return i;
}
return -1;
}
Here is a simple (yet fairly efficient) implementation that finds all occurances of the array, not just the first one:
static class ArrayExtensions {
public static IEnumerable<int> StartingIndex(this int[] x, int[] y) {
IEnumerable<int> index = Enumerable.Range(0, x.Length - y.Length + 1);
for (int i = 0; i < y.Length; i++) {
index = index.Where(n => x[n + i] == y[i]).ToArray();
}
return index;
}
}
Example:
int[] x = { 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4 };
int[] y = { 2, 3 };
foreach (int i in x.StartingIndex(y)) {
Console.WriteLine(i);
}
Output:
1
5
9
The method first loops through the x array to find all occurances of the first item in the y array, and place the index of those in the index array. Then it goes on to reduce the matches by checking which of those also match the second item in the y array. When all items in the y array is checked, the index array contains only the full matches.
Edit:
An alternative implementation would be to remove the ToArray call from the statement in the loop, making it just:
index = index.Where(n => x[n + i] == y[i]);
This would totally change how the method works. Instead of looping through the items level by level, it would return an enumerator with nested expressions, deferring the search to the time when the enumerator was iterated. That means that you could get only the first match if you wanted:
int index = x.StartingIndex(y).First();
This would not find all matches and then return the first, it would just search until the first was found and then return it.
The simplest way is probably this:
public static class ArrayExtensions
{
private static bool isMatch(int[] x, int[] y, int index)
{
for (int j = 0; j < y.Length; ++j)
if (x[j + index] != y[j]) return false;
return true;
}
public static int IndexOf(this int[] x, int[] y)
{
for (int i = 0; i < x.Length - y.Length + 1; ++i)
if (isMatch(x, y, i)) return i;
return -1;
}
}
But it's definitely not the fastest way.
This is based off of Mark Gravell's answer but I made it generic and added some simple bounds checking to keep exceptions from being thrown
private static bool IsSubArrayEqual<T>(T[] source, T[] compare, int start) where T:IEquatable<T>
{
if (compare.Length > source.Length - start)
{
//If the compare string is shorter than the test area it is not a match.
return false;
}
for (int i = 0; i < compare.Length; i++)
{
if (source[start++].Equals(compare[i]) == false) return false;
}
return true;
}
Could be improved further by implementing Boyer-Moore but for short patterns it works fine.
"Simplest" and "fastest" are opposites in this case, and besides, in order to describe fast algorithms we need to know lots of things about how the source array and the search array are related to each other.
This is essentially the same problem as finding a substring inside a string. Suppose you are looking for "fox" in "the quick brown fox jumps over the lazy dog". The naive string matching algorithm is extremely good in this case. If you are searching for "bananananananananananananananana" inside a million-character string that is of the form "banananananabanananabananabananabanananananbananana..." then the naive substring matching algorithm is terrible -- far faster results can be obtained by using more complex and sophisticated string matching algorithms. Basically, the naive algorithm is O(nm) where n and m are the lengths of the source and search strings. There are O(n+m) algorithms but they are far more complex.
Can you tell us more about the data you're searching? How big is it, how redundant is it, how long are the search arrays, and what is the likelihood of a bad match?
I find something along the following lines more intuitive, but that may be a matter of taste.
public static class ArrayExtensions
{
public static int StartingIndex(this int[] x, int[] y)
{
var xIndex = 0;
while(xIndex < x.length)
{
var found = xIndex;
var yIndex = 0;
while(yIndex < y.length && xIndex < x.length && x[xIndex] == y[yIndex])
{
xIndex++;
yIndex++;
}
if(yIndex == y.length-1)
{
return found;
}
xIndex = found + 1;
}
return -1;
}
}
This code also addresses an issue I believe your implementation may have in cases like x = {3, 3, 7}, y = {3, 7}. I think what would happen with your code is that it matches the first number, then resets itself on the second, but starts matching again on the third, rather than stepping back to the index just after where it started matching. May be missing something, but it's definitely something to consider and should be easily fixable in your code.
//this is the best in C#
//bool contains(array,subarray)
// when find (subarray[0])
// while subarray[next] IS OK
// subarray.end then Return True
public static bool ContainSubArray<T>(T[] findIn, out int found_index,
params T[]toFind)
{
found_index = -1;
if (toFind.Length < findIn.Length)
{
int index = 0;
Func<int, bool> NextOk = (i) =>
{
if(index < findIn.Length-1)
return findIn[++index].Equals(toFind[i]);
return false;
};
//----------
int n=0;
for (; index < findIn.Length; index++)
{
if (findIn[index].Equals(toFind[0]))
{
found_index=index;n=1;
while (n < toFind.Length && NextOk(n))
n++;
}
if (n == toFind.Length)
{
return true;
}
}
}
return false;
}
using System;
using System.Linq;
public class Test
{
public static void Main()
{
int[] x = {1,2,4,2,3,4,5,6};
int[] y = {2,3};
int? index = null;
for(int i=0; i<x.Length; ++i)
{
if (y.SequenceEqual(x.Skip(i).Take(y.Length)))
{
index = i;
break;
}
}
Console.WriteLine($"{index}");
}
}
Output
3

A logical error with my code

I wrote this code and its always showing the same results why?
The code is a searching method.
using System;
using System.Collections.Generic;
using System.Text;
namespace CArraySe
{
class Program
{
class CArray
{
private int[] arr;
private int upper;
private int numElements;
private int compCount;
public CArray(int size)
{
arr = new int[size];
upper = size - 1;
numElements = 0;
compCount = 0;
}
public void Insert(int item)
{
arr[numElements] = item;
numElements++;
}
public void DisplayElements()
{
for (int i = 0; i <= upper; i++)
{
Console.Write(arr[i]);
if (i == upper)
{
Console.WriteLine();
continue;
}
Console.Write(", ");
}
}
public void Clear()
{
for (int i = 0; i <= upper; i++)
arr[i] = 0;
numElements = 0;
}
public bool SeqSearch(CArray n, int sValue)
{
for (int index = 0; index < n.upper; index++)
{
if (arr[index] == sValue)
return true;
}
compCount++;
return false;
}
public int binSearch(CArray n, int value)
{
int upperBound, lowerBound, mid;
upperBound = n.upper; lowerBound = 0;
while (lowerBound <= upperBound)
{
mid = (upperBound + lowerBound) / 2;
if (arr[mid] == value)
return mid;
else if (value < arr[mid]) upperBound = mid - 1;
else lowerBound = mid + 1;
}
compCount++;
return -1;
}
static void Main(string[] args)
{
CArray nums = new CArray(10);
Random rnd = new Random(100);
for (int i = 0; i < 10; i++)
nums.Insert((int)(rnd.NextDouble() * 100));
Console.WriteLine();
Console.Write("The Binary Search Result is: ");
Console.WriteLine(nums.binSearch(nums, 500));
Console.WriteLine(nums.compCount);
nums.Clear();
for (int i = 0; i < 10; i++)
nums.Insert((int)(rnd.NextDouble() * 100));
Console.Write("The Sequential Search result is: ");
Console.WriteLine(nums.SeqSearch(nums, 500));
Console.WriteLine(nums.compCount);
}
}
}
}
Its always showing the same result even if I changed the number I'm looking for.
The output is:
The Binary Search Result is: -1
1
The Sequential Search result is: False
2
Press any key to continue . . .
I think your value being searched for (500) is not being found. Try outputting the nums array and verifying that what you are looking for is in the array.
Plus, one search returns an int and the other returns a bool. Is there a specific reason for that?
Edit: Also, Binary Search only works with sorted lists.
Your method binSearch returns "-1" when the number isn't found. Since you're populating your array with random values, the odds are very good that the number you search for won't be found. So you're always getting "-1".
To test your binSearch method, you should populate the array with known values, then search for some value that is guaranteed to be in the array.
The first answer is correct. Also, even though you are using a random number, each run of the program will produce the same sequence of random numbers. You should seed it with a different number each time you run the program if you want to test the code well.
As the others have already mentioned, in the general case, there's no guarantee that the number you're searching for is in the list of randomly generated numbers. In the specific case that you posted, the number will never appear in the list because you're generating random numbers in the 0-100 range, then trying to find 500.
Running what you provided does not add a value above 100. If you change your add to this:
for (int i = 0; i < 9; i++)
nums.Insert((int)(rnd.NextDouble() * 100));
nums.Insert(500);
The binSearch returns 9, but the SeqSearch return false because your looping search is index < n.upper and you need to do index <= n.upper to check all values. Additionally, as noted above, the binSearch only works in this case because 500 is larger than all the numbers in the array and has been placed at the last index. The binary search will only work by luck if the list its searching is not sorted. Therefore changing to:
nums.Insert(500);
for (int i = 0; i < 9; i++)
nums.Insert((int)(rnd.NextDouble() * 100));
Will return -1; and true for the SeqSearch.
Although this probably doesn't answer your question directly, here are some observations which makes your code hard to understand and debug:
You need either one of numElements or upper, not both. In Clear(), you are setting only numElements to 0 whereas you are using upper in your loops everywhere?
Binary search works only with sorted arrays
If SeqSearch and BinSearch are receiving an instance of the array, shouldn't they be static methods instead of instance methods?

Categories