Recursive Linear Search - algorithm

The code shown below works fine. It prints the position of the element found inside the if clause and exits. Whenever the element is not found, the function runs to max and returns 0 to calling function to indicate no elements has been found.
However, I was pondering about returning the position of the element found, to the calling function rather than printing it. Since returning the position would just return to earlier instance of the function and not to the calling function, I am struck. How to achieve this ?
#include <stdio.h>
#include <stdlib.h>
int RLinearSearch(int A[],int n,int key)
{
if(n<1)
return 0;
else
{
RLinearSearch(A,n-1,key);
if(A[n-1]==key)
{
printf("found %d at %d",key,n);
exit(0);
}
}
return 0;
}
int main(void)
{
int A[5]={23,41,22,15,32}; // Array Of 5 Elements
int pos,n=5;
pos=RLinearSearch(A,n,23);
if(pos==0)
printf("Not found");
return 0;
}

Since returning the position would just return to earlier instance of the function and not to the calling function, I am struck.
You can solve this problem by returning the result of recursive invocation from the recursive call itself:
int RLinearSearch(int A[], int n, int key) {
if(n<0) { // Base case - not found
return -1;
}
if(A[n]==key) { // Base case - found
return n;
}
// Recursive case
return RLinearSearch(A, n-1, key);
}
Since this implementation treats n as the index of the current element, the caller should pass 4, not 5, in your example.
Demo 1.
Note: you can further simplify the code by joining the base cases together:
int RLinearSearch(int A[], int n, int key) {
return (n<0 || A[n]==key) ? n : RLinearSearch(A, n-1, key);
}
Demo 2.

start with your problem: linear search returning the index of where the key is found the function has three perameters, the array, the starting index of search n and the search key k.
so you have:
int RLinearSearch(int[] A, int n, int k)
{
if (n=>A.length()) return (-1);//base case(k not found in A)
else if (A[n]==k) return n; //found case
else return RLinearSearch(A, n+1, key); //continue case(keep looking through array)
}
int main(void){
int A[5]={23,41,22,15,32}; // Array Of 5 Elements
int pos,n=0;
pos=RLinearSearch(A,n,23);
if (pos == -1) printf("Not Found");
return 0;
}
you could also change it so that you just returned n-1 and you would have the right index.

You could use tail recursion :
int LSearch(int a[],int n,int key,int i)
{
if(n==0) return -1;
if(a[0]==key) return i;
LSearch(a+1,n-1,key,++i);
}
while calling use the function call:
LSeacrh(a,n,key,0);

public static int recursiveLinearSearch(int[] data, int index, int key){
if(index==data.length)
return -1;
if(data[index]==key)
return index;
return recursiveLinearSearch(data, index+1, key);
}

Related

binary search (recursive) to check is if a certain value is found in a sorted array- modification

I studied that a recursive algorithm which checks if a certain value (key) is exists in a sorted given array, looks so:
int bin_search_rec(int key, int *a, int n)
{
if (n==0)
return 0;
if (key=a[n/2])
return key;
if (key<a[n/2])
return bin_search_rec(key,a,n/2);
else
return bin_search_rec(key,a+n/2 +1,n-n/2 -1 );
}
I also studied that this algorithm above can be modified - in order not only to check if a certain value exists in the array but also return the index of this value if it does exist - that way:
int bin_search_rec(int key, int *a, int n)
{
int pos;
if (n==0)
return -1;
if (key=a[n/2])
return key;
if (key<a[n/2])
return bin_search_rec(key,a,n/2);
else
pos= bin_search_rec(key,a+n/2 +1,n-n/2 -1 );
if (pos==-1)
return -1;
else
return pos+ n/2 +1;
}
I dont understand why in this modification we need to use the variable pos in order to find the index of the key.
Why is it wrong to just modify the algorithm that way instead:
int bin_search_rec(int key, int *a, int n)
{
if (n==0)
return -1;
if (key=a[n/2])
return n/2;
if (key<a[n/2])
return bin_search_rec(key,a,n/2);
else
return bin_search_rec(key,a+n/2 +1,n-n/2 -1 );
}

Function to insert an integer into a circular linked _list in ascending order

I am writing a function to insert an integer into a circular linked _list in ascending order whose elements are sorted in ascending order (smallest to largest).
The input to the function insertSortedList is a pointer start to some node in the circular list and an integer n between 0 and 100. Return a pointer to the newly inserted node.
The structure to follow for a node of the circular linked list is-
Struct CNode;
Typedef struct CNode cnode;
Struct CNode
{
Int value;
Cnode* next;
};
Cnode* insertSortedList (cnode* start,int n)
{
//WRITE YOUR CODE HERE
}
//FUNCTION SIGNATURE ENDS
Test Case 1:
Input:
[3->4->6->1->2->^],5
Expected Return Value:
[5->6->1->2->3->4->^]
Test Case 2:
Input:
[1->2->3->4->5->^],0
Expected Return Value:
[0->1->2->3->4->5->^]
Here's my code:
Cnode* insertSortedList (cnode* start,int n)
{
int count=1,i,count1=0;
Cnode* temp=start;
Cnode* temp1=start;
Cnode* temp2=start;
Cnode* newHead=NULL;
while(temp!=NULL)
{
temp=temp->next;
count ++;
}
int arr[count];
while(temp2!=NULL)
{
for(j=0;j<count;j++)
{
arr[j]=temp->data;
temp2=temp2->next;
}
}
while(n>=temp2->value)
{
temp2=temp2->next;
}
newHead=temp2;
for(i=0;i<count;i++)
{
Cnode* newNode=new Cnode();
newNode->data=arr[i];
newNode->next=NULL;
}
}
You said it's a circular linked-list but you are checking for temp != null. It should be temp→next != start.
Its not so complicated at all. Given a pointer to any element in a circular linked list, whose elements are already in ascending order, we just need to find the location of the new element, which can be done in a few lines. Simple Java code -
CNode prev = start;
CNode next = start.next;
while(true){
if(prev.value <= n && n <= next.value) break;
prev=next; next=next.next;
}
CNode node = new CNode();
node.value = n;
prev.next=node; node.next=next;
return node;

Sort odd and even numbers separatedly and move all odd numbers in front

For example, if the input array is
832461905
The output is
1357902468
I think this can be done in two steps
1) sort data
012345678
2) move odd numbers in front of even numbers by preserving order
To do so, we can have two pointers
Initially one points to the beginning and the other points to the end
Move the head util even numbers are found
The move the tail until odd numbers are found
Swap data at the pointers
Do the above until the two pointers meet
My question is if we can solve the problem by using one step rather than two
All you need is a little comp-function for sorting:
bool comp(int x, int y)
{
if (x % 2 == y % 2) return x < y;
return x % 2 > y % 2;
}
...
sort(your_array.begin(), your_array.end(), comp);
Yes, it can be done in one step.
Write your own comparison function, and use std::sort in C++:
sort(data.begin(),data.end(),comp);
bool comp(int x,int y)
{
if (x%2==0)
{
if(y%2==0)
{
return x<y; // if both are even
}
else
{
return false; // if only x is even
}
}
else
{
if(y%2==0)
{
return true;
}
else
{
return x<y;
}
}
}
Under the <algorithm> library in C++ you can use sort to order the numbers and then stable_partition to separate by odd and even.
Like so:
auto arr = std::valarray<int>{8,3,2,4,6,1,9,0,5};
std::sort(std::begin(arr), std::end(arr));
std::stable_partition(std::begin(arr), std::end(arr), [](int a){ return a % 2; });
Resulting in a rather succinct solution.
I am considering you are familiar with C++. See my code snippet, and yes it can be done in a step:
#include <iostream>
#include <stdio.h>
#include <algorithm>
bool function(int a, int b) {
if(a%2 != b%2) { /* When one is even and another is odd */
if(a&1) {
return true;
} else {
return false;
}
} else { /* When both are either odd or even */
return (a<b);
}
}
int main() {
int input[10005]; /* Input array */
int n = -1, i;
/* Take the input */
while(scanf("%i", &input[++n]) != EOF);
/* Sort according to desire condition */
std::sort(input, input+n, function);
/* Time to print out the values */
for(i=0; i<n; i++) {
std::cout << input[i] << " ";
}
return 0;
}
Any confusion, comments most welcome.

Can insertion sort be post order?

public class insSort {
int i,j,key; //j=1
public void rec(int a[],int pos){
if(pos>a.length-1){
return;
}
key= a[pos];
i=pos-1;
while((i>=0)&&(a[i]>key)){//swapping
a[i+1]=a[i];
i--;
a[i+1]=key;
}
pos++;
rec(a,pos);//post order
}
can it be considered as insertion sort? or should it be in-order?
Is it a universal practice to use in-order for recursive algorithms?if so why is it so?
The example code in the question is a tail recursive version, which a compiler may optimize into a loop (no recursion). I converted the example code to C++ with some minor clean up. The initial call should be rec(1) (initial value of pos == 1).
class insSort
{
public:
int a[8];
void rec(int pos){
int i,value;
if(pos >= (sizeof(a)/sizeof(a[0])))
return;
value = a[pos]; // get value
i = pos-1;
while((i >= 0) && (a[i] > value)){ // shift up
a[i+1] = a[i];
i--;
}
a[i+1] = value; // insert value
pos++;
rec(pos);
}
};

Sum of depth of all nodes in binary tree (Path length)

I am trying to implement a function to calculate path length of a binary tree and i am not able to get the correct answer. Can you check what i am doing wrong? Here is my code below:
public int pathLength() {
int sum = 0;
int c = 1;
pathLength(root, sum);
return sum;
}
public int pathLength(Node n, int sum) {
if(n.isRoot())
sum+= 0;
if(n.left == null && n.right == null)
return;
c++;
if(n.left != null)
sum += c;
if (n.right != null)
sum+=c;
pathLength(n.left, sum);
pathLength(n.right, sum);
}
There are a lot of things wrong with this code. It wouldn't even compile because a) In the 2nd function c is never declared (it is local in the first) and b) the 2nd function never returns a value.
But the biggest issue is the way you declare the 2nd function. "sum" is passed by value. That basically means a new copy of "sum" is created each time you call the function and is discarded when the function ends.
What you want to do is pass by reference. When doing this, the actual sum variable, not a copy, is passed to the function. So your code might look like this:
public void pathLength(Node n, int& sum) {
//if(n.isRoot()) <- not sure what this is for
// sum+= 0;
sum += 1; // Increment for this node
//if(n.left == null && n.right == null)
// return; // This conditional is not needed with next 2 if statements
//c++; <- Don't know what c is for
// Recursively call for child nodes
if(n.left != null)
pathLength(n.left, sum);
if (n.right != null)
pathLength(n.right, sum);
}
Note that this counts all the nodes in the tree. I assume that's what you want. If you want to find the deepest node, that's different.
Is it because of you set the initial value of c as 1 instead of 0?
The children of root should be at level 2 with the depth 1.
Here is an easy approach
Time : O(n) while the space will be O(h) where h is the height of the binary tree:
int sum(BinaryTree *node, int count){
if(node == nullptr){
return 0;
}
return count + sum(node->left, count+1)+sum(node->right, count+1);
}
int nodeDepths(BinaryTree *root) {
int count=0;
int ans=0;
ans =sum(root, count);
return ans;
}

Resources