tags:

views:

298

answers:

4

I want to do a ternary search for integers in C ... I have tried it...but it's not working well for particular cases. Please help me to remove the bugs from the following program--

My attempt:

#include<stdio.h>
#include<conio.h>
void  tsearch(int *a,int i,int j,int k);
main() {
  int a[30],n,i,k;
        printf("\nEnter n:");
  scanf("%d",&n);
  printf("\nEnter nos in ascending order:");
  for(i=0;i<n;i++)
      scanf("%d",&a[i]);
  printf("Enter no to search:");
  scanf("%d",&k);
  tsearch(a,0,n-1,k);

  getch();
}

void tsearch(int *a,int i,int j,int k) {
  int m1,m2;
  m1=(i+j)/3;
  m2=2*(i+j)/3;
  if(k==a[m1])
   {
    printf("\nno found at %d",m1);
    return;
   }
  else  if(k==a[m2])
   {
    printf("\nno found at %d",m2);
    return;
   }
  if(k<a[m1])
    return(tsearch(a,i,m1-1,k));
  if(k>a[m2])
    return(tsearch(a,m2+1,j,k));
  else   
    return(tsearch(a,m1+1,m2-1,k));
}


It (only) terminates if the number to be searched is present in one of last 2-3 locations (of array). Where i have committed the mistake???

+4  A: 

The midpoint calculations are wrong. The way you have it, m1 and m2 are not between i and j.

try

 m1 = i + (j - i) * 1 / 3;
 m2 = i + (j - i) * 2 / 3;
UncleO
yess.....its working now...thanks a lot!!!
JAY G
Good point - but not the whole answer.
Jonathan Leffler
A: 
int a[30],n,i;
scanf("%d",&n);
for(i=0;i<n;i++)
    scanf("%d",&a[i]);

This is a typical buffer overflow issue. Allocate memory for a dynamically once you know what n is. uncleo solved your issue nicely. :)

Michael Foukarakis
ok...will avoid it next time...thanks.
JAY G
+4  A: 

@uncleo makes a good point - and provides a decent solution.

The bigger problem, though, is that if you search for a number that isn't in the array, there is nothing to stop the recursion - it continues until it crashes.

Also, the design of tsearch() is suspect; the code shown says it is a void function, yet you use return(tsearch(...)); several times (as well as a couple of plain return; statements). Surely, the function should return an int and the two plain return; statements should return m1 or m2? You also need to deal with the case where the range is degenerate (i >= j) which means the value is not present - maybe you can return -1 or something similar for that case.

Jonathan Leffler
ohh...absolutely right...i missed it...thnx!!
JAY G
+1  A: 
#include<stdio.h>

int  tsearch(int *a,int i,int j,int k);

int main() {
      int a[10]={1,2,3,4,5,6,7,8,9,10};
      int search;
      int k;
      printf("enter no to be searched :");
      scanf("%d",&k);
      search=tsearch(a,0,9,k);
      printf("\n%d",search);
      return 0;
}

int tsearch(int *data, int left, int right, int value){
    int i;
    int first,second;
    if(left>right)
       return -1;

    i= (right - left)/3;
    if(i==0) i++;

    first = i  + left -1;
    second = i*2 + left - 1;

    if(data[first]==value)
       return first;
    else
    if(data[first]>value)
         return tsearch(data, left, first-1, value);
    else
     {
        if(data[second]==value)
          return second;
        else
        if(data[second]>value)
           return tsearch(data, first+1,second-1, value);
        else
           return tsearch(data, second+1,right, value);
     }
}
adatapost
Also, stylistically, why do you have the 'big else' clause instead of just continuing with `else if (data[second] == value) ...'? Plus you haven't made your mind up about whether there should be a space after 'if' in 'if (...)'; please decide that the answer is "yes, there should be a space there".
Jonathan Leffler
It works as fixed. It also works with 'if (left >= right) return -1;'.
Jonathan Leffler