Data structures all in one

466
Day-1 Return maximum occurring character in the input string March 20, 2009 Write an efficient C function to return maximum occurring character in the input string e.g., if input string is “test string” then function should return ‘t’. Algorithm: Input string = “test” 1: Construct character count array from the input string. count['e'] = 1 count['s'] = 1 count['t'] = 2 2: Return the index of maximum value in count array (returns ‘t’). Implementation: #include <stdio.h> #include <stdlib.h> #define NO_OF_CHARS 256 int *getCharCountArray(char *); char getIndexOfMax(int *, int); /* Returns the maximum occurring character in the input string */

description

Data structures all in one

Transcript of Data structures all in one

Page 1: Data structures all in one

Day-1Return maximum occurring character in the input stringMarch 20, 2009

Write an efficient C function to return maximum occurring character in the input string e.g., if input string is “test string” then function should return ‘t’.

Algorithm:

Input string = “test”1: Construct character count array from the input string. count['e'] = 1 count['s'] = 1 count['t'] = 2

2: Return the index of maximum value in count array (returns ‘t’).

Implementation:

#include <stdio.h>#include <stdlib.h>#define NO_OF_CHARS 256

int *getCharCountArray(char *);char getIndexOfMax(int *, int);

/* Returns the maximum occurring character in the input string */char getMaxOccuringChar(char *str){  int *count = getCharCountArray(str);  return getIndexOfMax(count, NO_OF_CHARS);}

/* Returns an array of size 256 containg count   of characters in the passed char array */int *getCharCountArray(char *str){  int *count = (int *)calloc(NO_OF_CHARS, sizeof(int));  int i;

Page 2: Data structures all in one

  for (i = 0; *(str+i);  i++)    count[*(str+i)]++;

  return count;}

char getIndexOfMax(int ar[], int ar_size){  int i;  int max_index = 0;

  for(i = 1; i < ar_size; i++)    if(ar[i] > ar[max_index])      max_index = i;

  /* free memory allocated to count */  free(ar);  ar = NULL;

  return max_index;}

int main(){  char str[] = "sample string";  printf("%c", getMaxOccuringChar(str));

  getchar();  return 0;}

Time Complexity: O(n)

Notes:If more than one character have the same and maximum count then function returns only the first character in alphabetical order. For example if input string is “test sample” then function will return only ‘e’.

How will you print numbers from 1 to 100 without using loop?March 22, 2009

Here is a solution that prints numbers using recursion.

Other alternatives for loop statements are recursion and goto statement, but use of goto is not suggestible as a general programming practice as goto statement changes the normal program execution sequence and makes it difficult to undestand and maintain.

#include <stdio.h>

Page 3: Data structures all in one

/* Prints numbers from 1 to n */void printNos(unsigned int n){  if(n > 0)  {    printNos(n-1);    printf("%d ",  n);  }  return;}

/* Driver program to test printNos */int main(){  printNos(100);  getchar();  return 0;}

Time Complexity: O(n)

Now try writing a program that does the same but without any if construct.

How can we sum the digits of a given number in single statement?March 22, 2009

Below are the solutions to get sum of the digits.

1. Iterative:The function has three lines instead of one line but it calculates sum in line. It can be made one line function if we pass pointer to sum.

# include<stdio.h>int main(){  int n = 687;  printf(" %d ", getSum(n));

  getchar();  return 0;}

/* Function to get sum of digits */int getSum(int n){    int sum;    /*Single line that calculates sum*/    for(sum=0; n > 0; sum+=n%10,n/=10);    return sum;}

Page 4: Data structures all in one

2. RecursiveThanks to ayesha for providing the below recursive solution.

int sumDigits(int no){  return no == 0 ? 0 : no%10 + sumDigits(no/10) ;}

int main(void){  printf("%d", sumDigits(1352));  getchar();  return 0;}

Write a C program to calculate pow(x,n)March 22, 2009

Below solution divides the problem into subproblems of size y/2 and call the subproblems recursively.

#include<stdio.h>

/* Function to calculate x raised to the power y */int power(int x, unsigned int y){    if( y == 0)        return 1;    else if (y%2 == 0)        return power(x, y/2)*power(x, y/2);    else        return x*power(x, y/2)*power(x, y/2);

}

/* Program to test function power */int main(){    int x = 2;    unsigned int y = 3;

    printf("%d", power(x, y));    getchar();    return 0;}

Time Complexity: O(n)Space Complexity: O(1)Algorithmic Paradigm: Divide and conquer.

Page 5: Data structures all in one

Above function can be optimized to O(logn) by calculating power(x, y/2) only once and storing it.

/* Function to calculate x raised to the power y in O(logn)*/int power(int x, unsigned int y){    int temp;    if( y == 0)        return 1;    temp = power(x, y/2);    if (y%2 == 0)        return temp*temp;    else        return x*temp*temp;}

Time Complexity of optimized solution: O(logn)Let us extend the pow function to work for negative y and float x.

/* Extended version of power function that can work for float x and negative y*/#include<stdio.h>

float power(float x, int y){    float temp;    if( y == 0)       return 1;    temp = power(x, y/2);    if (y%2 == 0)        return temp*temp;    else    {        if(y > 0)            return x*temp*temp;        else            return (temp*temp)/x;    }}

/* Program to test function power */int main(){    float x = 2;    int y = -3;    printf("%f", power(x, y));    getchar();    return 0;}

Remove all duplicates from the input string.March 22, 2009

Below are the different methods to remove duplicates in a string.

METHOD 1 (Use Sorting)

Page 6: Data structures all in one

Algorithm:

1) Sort the elements. 2) Now in a loop, remove duplicates by comparing the current character with previous character. 3) Remove extra characters at the end of the resultant string.

Example:

Input string: geeksforgeeks1) Sort the characters eeeefggkkosss2) Remove duplicates efgkosgkkosss3) Remove extra characters efgkos

Note that, this method doesn’t keep the original order of the input string. For example, if we are to remove duplicates for geeksforgeeks and keep the order of characters same, then output should be geksfor, but above function returns efgkos. We can modify this method by storing the original order. METHOD 2 keeps the order same.

Implementation:

# include <stdio.h># include <stdlib.h>

/* Function to remove duplicates in a sorted array */char *removeDupsSorted(char *str);

/* Utitlity function to sort array A[] */void quickSort(char A[], int si, int ei);

/* Function removes duplicate characters from the string   This function work in-place and fills null characters   in the extra space left */char *removeDups(char *str){  int len = strlen(str);

Page 7: Data structures all in one

  quickSort(str, 0, len-1);  return removeDupsSorted(str);}

/* Function to remove duplicates in a sorted array */char *removeDupsSorted(char *str){  int res_ind = 1, ip_ind = 1;

  /* In place removal of duplicate characters*/  while(*(str + ip_ind))  {    if(*(str + ip_ind) != *(str + ip_ind - 1))    {      *(str + res_ind) = *(str + ip_ind);      res_ind++;    }    ip_ind++;  }

  /* After above step string is stringiittg.     Removing extra iittg after string*/  *(str + res_ind) = '\0';

  return str;}

/* Driver program to test removeDups */int main(){  char str[] = "eeeefggkkosss";  printf("%s", removeDups(str));  getchar();  return 0;}

/* FOLLOWING FUNCTIONS ARE ONLY FOR SORTING    PURPOSE */void exchange(char *a, char *b){  char temp;  temp = *a;  *a   = *b;  *b   = temp;}

int partition(char A[], int si, int ei){  char x = A[ei];  int i = (si - 1);  int j;

  for (j = si; j <= ei - 1; j++)  {    if(A[j] <= x)    {      i++;      exchange(&A[i], &A[j]);    }  }

Page 8: Data structures all in one

  exchange (&A[i + 1], &A[ei]);  return (i + 1);}

/* Implementation of Quick SortA[] --> Array to be sortedsi  --> Starting indexei  --> Ending index*/void quickSort(char A[], int si, int ei){  int pi;    /* Partitioning index */  if(si < ei)  {    pi = partition(A, si, ei);    quickSort(A, si, pi - 1);    quickSort(A, pi + 1, ei);  }}

Time Complexity: O(nlogn) If we use some nlogn sorting algorithm instead of quicksort.

METHOD 2 (Use Hashing )

Algorithm:

1: Initialize: str = "test string" /* input string */ ip_ind = 0 /* index to keep track of location of next character in input string */ res_ind = 0 /* index to keep track of location of next character in the resultant string */ bin_hash[0..255] = {0,0, ….} /* Binary hash to see if character is already processed or not */2: Do following for each character *(str + ip_ind) in input string:

Page 9: Data structures all in one

(a) if bin_hash is not set for *(str + ip_ind) then // if program sees the character *(str + ip_ind) first time (i) Set bin_hash for *(str + ip_ind) (ii) Move *(str + ip_ind) to the resultant string. This is done in-place. (iii) res_ind++ (b) ip_ind++ /* String obtained after this step is "te sringng" */3: Remove extra characters at the end of the resultant string. /* String obtained after this step is "te sring" */

Implementation:

# include <stdio.h># include <stdlib.h># define NO_OF_CHARS 256# define bool int

/* Function removes duplicate characters from the string   This function work in-place and fills null characters   in the extra space left */char *removeDups(char *str){  bool bin_hash[NO_OF_CHARS] = {0};  int ip_ind = 0, res_ind = 0;  char temp;

  /* In place removal of duplicate characters*/  while(*(str + ip_ind))  {    temp = *(str + ip_ind);    if(bin_hash[temp] == 0)    {        bin_hash[temp] = 1;        *(str + res_ind) = *(str + ip_ind);        res_ind++;    }    ip_ind++;  }

  /* After above step string is stringiittg.

Page 10: Data structures all in one

     Removing extra iittg after string*/  *(str+res_ind) = '\0';

  return str;}

/* Driver program to test removeDups */int main(){    char str[] = "geeksforgeeks";    printf("%s", removeDups(str));    getchar();    return 0;}

Time Complexity: O(n)

NOTES:* It is assumed that number of possible characters in input string are 256. NO_OF_CHARS should be changed accordingly.* calloc is used instead of malloc for memory allocations of counting array (count) to initialize allocated memory to ‘\0′. malloc() followed by memset() could also be used.* Above algorithm also works for an integer array inputs if range of the integers in array is given. Example problem is to find maximum occurring number in an input array given that the input array contain integers only between 1000 to 1100

Remove all duplicates from the input string.March 22, 2009

Below are the different methods to remove duplicates in a string.

METHOD 1 (Use Sorting)

Algorithm:

1) Sort the elements. 2) Now in a loop, remove duplicates by comparing the current character with previous character. 3) Remove extra characters at the end of the resultant string.

Page 11: Data structures all in one

Example:

Input string: geeksforgeeks1) Sort the characters eeeefggkkosss2) Remove duplicates efgkosgkkosss3) Remove extra characters efgkos

Note that, this method doesn’t keep the original order of the input string. For example, if we are to remove duplicates for geeksforgeeks and keep the order of characters same, then output should be geksfor, but above function returns efgkos. We can modify this method by storing the original order. METHOD 2 keeps the order same.

Implementation:

# include <stdio.h># include <stdlib.h>

/* Function to remove duplicates in a sorted array */char *removeDupsSorted(char *str);

/* Utitlity function to sort array A[] */void quickSort(char A[], int si, int ei);

/* Function removes duplicate characters from the string   This function work in-place and fills null characters   in the extra space left */char *removeDups(char *str){  int len = strlen(str);  quickSort(str, 0, len-1);  return removeDupsSorted(str);}

/* Function to remove duplicates in a sorted array */char *removeDupsSorted(char *str){  int res_ind = 1, ip_ind = 1;

  /* In place removal of duplicate characters*/  while(*(str + ip_ind))  {    if(*(str + ip_ind) != *(str + ip_ind - 1))    {      *(str + res_ind) = *(str + ip_ind);

Page 12: Data structures all in one

      res_ind++;    }    ip_ind++;  }

  /* After above step string is stringiittg.     Removing extra iittg after string*/  *(str + res_ind) = '\0';

  return str;}

/* Driver program to test removeDups */int main(){  char str[] = "eeeefggkkosss";  printf("%s", removeDups(str));  getchar();  return 0;}

/* FOLLOWING FUNCTIONS ARE ONLY FOR SORTING    PURPOSE */void exchange(char *a, char *b){  char temp;  temp = *a;  *a   = *b;  *b   = temp;}

int partition(char A[], int si, int ei){  char x = A[ei];  int i = (si - 1);  int j;

  for (j = si; j <= ei - 1; j++)  {    if(A[j] <= x)    {      i++;      exchange(&A[i], &A[j]);    }  }  exchange (&A[i + 1], &A[ei]);  return (i + 1);}

/* Implementation of Quick SortA[] --> Array to be sortedsi  --> Starting indexei  --> Ending index*/void quickSort(char A[], int si, int ei){  int pi;    /* Partitioning index */  if(si < ei)  {    pi = partition(A, si, ei);

Page 13: Data structures all in one

    quickSort(A, si, pi - 1);    quickSort(A, pi + 1, ei);  }}

Time Complexity: O(nlogn) If we use some nlogn sorting algorithm instead of quicksort.

METHOD 2 (Use Hashing )

Algorithm:

1: Initialize: str = "test string" /* input string */ ip_ind = 0 /* index to keep track of location of next character in input string */ res_ind = 0 /* index to keep track of location of next character in the resultant string */ bin_hash[0..255] = {0,0, ….} /* Binary hash to see if character is already processed or not */2: Do following for each character *(str + ip_ind) in input string: (a) if bin_hash is not set for *(str + ip_ind) then // if program sees the character *(str + ip_ind) first time (i) Set bin_hash for *(str + ip_ind) (ii) Move *(str + ip_ind) to the resultant string. This is done in-place.

Page 14: Data structures all in one

(iii) res_ind++ (b) ip_ind++ /* String obtained after this step is "te sringng" */3: Remove extra characters at the end of the resultant string. /* String obtained after this step is "te sring" */

Implementation:

# include <stdio.h># include <stdlib.h># define NO_OF_CHARS 256# define bool int

/* Function removes duplicate characters from the string   This function work in-place and fills null characters   in the extra space left */char *removeDups(char *str){  bool bin_hash[NO_OF_CHARS] = {0};  int ip_ind = 0, res_ind = 0;  char temp;

  /* In place removal of duplicate characters*/  while(*(str + ip_ind))  {    temp = *(str + ip_ind);    if(bin_hash[temp] == 0)    {        bin_hash[temp] = 1;        *(str + res_ind) = *(str + ip_ind);        res_ind++;    }    ip_ind++;  }

  /* After above step string is stringiittg.     Removing extra iittg after string*/  *(str+res_ind) = '\0';

  return str;}

/* Driver program to test removeDups */int main(){    char str[] = "geeksforgeeks";    printf("%s", removeDups(str));    getchar();    return 0;}

Page 15: Data structures all in one

Time Complexity: O(n)

NOTES:* It is assumed that number of possible characters in input string are 256. NO_OF_CHARS should be changed accordingly.* calloc is used instead of malloc for memory allocations of counting array (count) to initialize allocated memory to ‘\0′. malloc() followed by memset() could also be used.* Above algorithm also works for an integer array inputs if range of the integers in array is given. Example problem is to find maximum occurring number in an input array given that the input array contain integers only between 1000 to 1100

Write a function to get Nth node in a Linked ListMarch 26, 2009

Write a GetNth() function that takes a linked list and an integer index and returns the data value stored in the node at that index position.

Algorithm:

1. Initialize count = 02. Loop through the link list a. if count is equal to the passed index then return current node b. Increment count c. change current to point to next of the current.

Implementation:

#include <stdio.h>#include <stdlib.h>#include <assert.h>

/* Link list node */struct node{    int data;    struct node* next;};

Page 16: Data structures all in one

/* Given a reference (pointer to pointer) to the head    of a list and an int, push a new node on the front    of the list. */void push(struct node** head_ref, int new_data){    /* allocate node */    struct node* new_node =            (struct node*) malloc(sizeof(struct node));

    /* put in the data  */    new_node->data  = new_data;

    /* link the old list off the new node */    new_node->next = (*head_ref);

    /* move the head to point to the new node */    (*head_ref)    = new_node;}

/* Takes head pointer of the linked list and index    as arguments and return data at index*/int GetNth(struct node* head, int index){    struct node* current = head;    int count = 0; /* the index of the node we're currently                  looking at */    while (current != NULL)    {       if (count == index)          return(current->data);       count++;       current = current->next;    }

    /* if we get to this line, the caller was asking       for a non-existent element so we assert fail */    assert(0);}

/* Drier program to test above function*/int main(){    /* Start with the empty list */    struct node* head = NULL;

    /* Use push() to construct below list     1->12->1->4->1  */    push(&head, 1);    push(&head, 4);    push(&head, 1);    push(&head, 12);    push(&head, 1);

    /* Check the count function */    printf("Element at index 3 is %d", GetNth(head, 3));    getchar();}

Page 17: Data structures all in one

Time Complexity: O(n)

Given only a pointer to a node to be deleted in a singly linked list, how do you delete it?April 16, 2009

A simple solution is to traverse the linked list until you find the node you want to delete. But this solution requires pointer to the head node which contradicts the problem statement.

Fast solution is to copy the data from the next node to the node to be deleted and delete the next node. Something like following.

struct node *temp = node_ptr->next; node_ptr->data = temp->data; node_ptr->next = temp->next; free(temp);

Program:

#include<stdio.h>#include<assert.h>#include<stdlib.h>

/* Link list node */struct node{    int data;    struct node* next;};

/* Given a reference (pointer to pointer) to the head    of a list and an int, push a new node on the front    of the list. */void push(struct node** head_ref, int new_data){   /* allocate node */   struct node* new_node =             (struct node*) malloc(sizeof(struct node));

   /* put in the data  */   new_node->data  = new_data;

   /* link the old list off the new node */   new_node->next = (*head_ref);

   /* move the head to point to the new node */   (*head_ref)    = new_node;}

void printList(struct node *head)

Page 18: Data structures all in one

{   struct node *temp = head;   while(temp != NULL)   {      printf("%d  ", temp->data);      temp = temp->next;   }}

void deleteNode(struct node *node_ptr){   struct node *temp = node_ptr->next;   node_ptr->data    = temp->data;   node_ptr->next    = temp->next;   free(temp);}

/* Drier program to test above function*/int main(){    /* Start with the empty list */    struct node* head = NULL;

    /* Use push() to construct below list    1->12->1->4->1  */    push(&head, 1);    push(&head, 4);    push(&head, 1);    push(&head, 12);    push(&head, 1);

    printf("\n Before deleting \n");    printList(head);

    /* I m deleting the head itself.        You can check for more cases */    deleteNode(head);

    printf("\n After deleting \n");    printList(head);    getchar();    return 0;}

This solution doesn’t work if the node to be deleted is the last node of the list. To make this solution work we can mark the end node as a dummy node. But the programs/functions that are using this function should also be modified.

Remove characters from the first string which are present in the second stringMay 23, 2009

Page 19: Data structures all in one

Write an efficient C function that takes two strings as arguments and removes the characters from first string which are present in second string (mask string).

Algorithm: Let first input string be”test string” and the string which has characters to be removed from first string be “mask”1: Initialize:res_ind = 0 /* index to keep track of processing of each character in i/p string */ip_ind = 0 /* index to keep track of processing of each character in the resultant string */

2: Construct count array from mask_str. Count array would be:(We can use Boolean array here instead of int count array because we don’t need count, we need to know only if character is present in mask string)count['a'] = 1count['k'] = 1count['m'] = 1count['s'] = 1

3: Process each character of the input string and if count of that character is 0 then only add the character to the resultant string.str = “tet tringng” // ’s’ has been removed because ’s’ was present in mask_str but we we have got two extra characters “ng”ip_ind = 11res_ind = 9

4: Put a ‘\0′ at the end of the string?

Implementation:

#include <stdio.h>#include <stdlib.h>#define NO_OF_CHARS 256

/* Returns an array of size 256 containg count   of characters in the passed char array */int *getCharCountArray(char *str){   int *count = (int *)calloc(sizeof(int), NO_OF_CHARS);   int i;   for (i = 0; *(str+i);  i++)      count[*(str+i)]++;

Page 20: Data structures all in one

   return count;}

/* removeDirtyChars takes two string as arguments: Firststring (str)  is the one from where function removes dirtycharacters. Second  string is the string which contain alldirty characters which need to be removed  from first string */char *removeDirtyChars(char *str, char *mask_str){  int *count  = getCharCountArray(mask_str);  int ip_ind  = 0, res_ind = 0;  char temp;  while(*(str + ip_ind))  {    temp = *(str + ip_ind);    if(count[temp] == 0)    {      *(str + res_ind) = *(str + ip_ind);      res_ind++;    }    ip_ind++;  }

  /* After above step string is ngring.    Removing extra "iittg" after string*/  *(str+res_ind) = '\0';

  return str;}

/* Driver program to test getCharCountArray*/int main(){    char mask_str[]  = "mask";    char str[]         = "geeksforgeeks";    printf("%s", removeDirtyChars(str, mask_str));    getchar();    return 0;}

Time Complexity: O(m+n) Where m is the length of mask string and n is the length of the input string.

A Program to check if strings are rotations of each other or notMay 26, 2009

Given a string s1 and a string s2, write a snippet to say whether s2 is a rotation of s1 using only one call to strstr routine?(eg given s1 = ABCD and s2 = CDAB, return true, given s1 = ABCD, and s2 = ACBD , return false)

Page 21: Data structures all in one

Algorithm: areRotations(str1, str2)

1. Create a temp string and store concatenation of str1 to str1 in temp. temp = str1.str1 2. If str2 is a substring of temp then str1 and str2 are rotations of each other.

Example: str1 = "ABACD" str2 = "CDABA"

temp = str1.str1 = "ABACDABACD" Since str2 is a substring of temp, str1 and str2 are rotations of each other.

Implementation:

# include <stdio.h># include <string.h># include <stdlib.h>

/* Function checks if passed strings (str1 and str2)   are rotations of each other */int areRotations(char *str1, char *str2){  int size1   = strlen(str1);  int size2   = strlen(str2);  char *temp;  void *ptr;

  /* Check if sizes of two strings are same */  if(size1 != size2)     return 0;

  /* Create a temp string with value str1.str1 */  temp   = (char *)malloc(sizeof(char)*size1*2 + 1);  temp[0] = '\0';  strcat(temp, str1);  strcat(temp, str1);

  /* Now check if str2 is a substring of temp */  ptr = strstr(temp, str2);

Page 22: Data structures all in one

  /* strstr returns NULL if the second string is NOT a    substring of first string */  if(ptr != NULL)    return 1;  else    return 0;}

/* Driver program to test areRotations */int main(){    char *str1 = "ABCD";    char *str2 = "ABCDA";

    if(areRotations(str1, str2))       printf("Strings are rotations of each other");    else       printf("Strings are not rotations of each other");

    getchar();    return 0;}

Library Functions Used:strstr:strstr finds a sub-string within a string.Prototype: char * strstr(const char *s1, const char *s2);See http://www.lix.polytechnique.fr/Labo/Leo.Liberti/public/computing/prog/c/C/MAN/strstr.htm for more details

strcat:strncat concatenate two stringsPrototype: char *strcat(char *dest, const char *src);See http://www.lix.polytechnique.fr/Labo/Leo.Liberti/public/computing/prog/c/C/MAN/strcat.htm for more details

Time Complexity: Time complexity of this problem depends on the implementation of strstr function.If implementation of strstr is done using KMP matcher then complexity of the above program is (-)(n1 + n2) where n1 and n2 are lengths of strings. KMP matcher takes (-)(n) time to find a substrng in a string of length n where length of substring is assumed to be smaller than the string.

Output of the program | Dereference, Reference, Dereference, Reference….May 27, 2009

Page 23: Data structures all in one

Predict the output of below program

int main(){ char *ptr = "geeksforgeeks"; printf("%c\n", *&*&*ptr);

 getchar(); return 0;}

Output: g

Explanation: The operator * is used for dereferencing and the operator & is used to get the address. These operators cancel effect of each other when used one after another. We can apply them alternatively any no. of times. For example *ptr gives us g, &*ptr gives address of g, *&*ptr again g, &*&*ptr address of g, and finally *&*&*ptr gives ‘g’

Now try below

int main(){ char *ptr = "geeksforgeeks"; printf("%s\n", *&*&ptr);

 getchar(); return 0;}

Output of the Program | Use Macros Carefully!May 27, 2009

Predict the output of the below program

#define square(x) x*xint main(){  int x;  x = 36/square(6);  printf("%d",x);

  getchar();  return 0;}

Output: 36

Page 24: Data structures all in one

Explanation:Preprocessor replaces square(6) by 6*6 and the expression becomes x = 36/6*6 and value of x is calculated as 36. If we want correct behavior from macro square(x), we should declare it as

#define square(x) ((x)*(x)) /* Note that the expression(x*x) will also fail for square(6-2) */

Output of the Program | Pointer to a Constant or Constant Pointer?May 27, 2009

Predict the output of the below program.

int main(){    int x = 5;    int * const ptr = &x;    ++(*ptr);    printf("%d", x);

    getchar();    return 0;}

Output: 6

Explananation:See following declarations to know the difference between constant pointer and a pointer to a constant.

int * const ptr —> ptr is constant pointer. You can change the value at the location pointed by pointer p, but you can not change p to point to other location.

int const * ptr —> ptr is a pointer to a constant. You can change ptr to point other variable. But you cannot change the value pointed by ptr.

Therefore above program works well because we have a constant pointer and we are not changing ptr to point to any other location. We are only icrementing value pointed by ptr.

Try below program, you will get compiler error.

int main()

Page 25: Data structures all in one

{    int x = 5;    int const * ptr = &x;    ++(*ptr);    printf("%d", x);

    getchar();    return 0;}

Write a C program to print “Geeks for Geeks” without using a semicolonMay 28, 2009

Use printf statement inside the if condition

#include<stdio.h>int main(){      if( printf( "Geeks for Geeks" ) )      {    }}

One trivial extension of the above problem: Write a C program to print “;” without using a semicolon

#include<stdio.h>int main(){   if(printf("%c",59))   {   }}

Write a one line C function to round floating point numbersMay 28, 2009

Algorithm: roundNo(num)1. If num is positive then add 0.5.2. Else subtract 0.5.3. Type cast the result to int and return.

Example:num = 1.67, (int) num + 0.5 = (int)2.17 = 2num = -1.67, (int) num – 0.5 = -(int)2.17 = -2

Implementation:

/* Program for rounding floating point numbers */

Page 26: Data structures all in one

# include<stdio.h>

int roundNo(float num){    return num < 0 ? num - 0.5 : num + 0.5;}

int main(){    printf("%d", roundNo(-1.777));    getchar();    return 0;}

Output: -2

Time complexity: O(1)Space complexity: O(1)

Now try rounding for a given precision. i.e., if given precision is 2 then function should return 1.63 for 1.63322 and -1.63 for 1.6332.

Next Power of 2May 28, 2009

Write a function that, for a given no n, finds a number p which is greater than or equal to n and is a power of 2.

IP 5 OP 8

IP 17 OP 32

IP 32 OP 32

There are plenty of solutions for this. Let us take the example of 17 to explain some of them.

Method 1(Using Log of the number)

1. Calculate Position of set bit in p(next power of 2):

Page 27: Data structures all in one

pos = ceil(lgn) (ceiling of log n with base 2) 2. Now calculate p: p = pow(2, pos)

Example

Let us try for 17 pos = 5 p = 32

Method 2 (By getting the position of only set bit in result )

/* If n is a power of 2 then return n */ 1 If (n & !(n&(n-1))) then return n 2 Else keep right shifting n until it becomes zero and count no of shifts a. Initialize: count = 0 b. While n ! = 0 n = n>>1 count = count + 1

/* Now count has the position of set bit in result */ 3 Return (1 << count)

Example:

Let us try for 17 count = 5 p = 32 unsigned int nextPowerOf2(unsigned int n){  unsigned count = 0;

  /* First n in the below condition is for the case where n is 0*/  if (n & !(n&(n-1)))    return n;

  while( n != 0)  {

Page 28: Data structures all in one

    n  >>= 1;    count += 1;  }

  return 1<<count;}

/* Driver program to test above function */int main(){  unsigned int n = 0;  printf("%d", nextPowerOf2(n));

  getchar();  return 0;}

Method 3(Shift result one by one)Thanks to coderyogi for suggesting this method . This method is a variation of method 2 where instead of getting count, we shift the result one by one in a loop.

unsigned int nextPowerOf2(unsigned int n){    unsigned int p = 1;    if (n & !(n & (n - 1)))        return n;

    while (p < n) {        p <<= 1;    }    return p;}

/* Driver program to test above function */int main(){  unsigned int n = 5;  printf("%d", nextPowerOf2(n));

  getchar();  return 0;}

Time Complexity: O(lgn)

Method 4(Customized and Fast)

1. Subtract n by 1 n = n -1

Page 29: Data structures all in one

2. Set all bits after the leftmost set bit.

/* Below solution works only if integer is 32 bits */ n = n | (n >> 1); n = n | (n >> 2); n = n | (n >> 4); n = n | (n >> 8); n = n | (n >> 16); 3. Return n + 1

Example:

Steps 1 & 3 of above algorithm are to handle cases of power of 2 numbers e.g., 1, 2, 4, 8, 16,

Let us try for 17(10001) step 1 n = n - 1 = 16 (10000) step 2 n = n | n >> 1 n = 10000 | 01000 n = 11000 n = n | n >> 2 n = 11000 | 00110 n = 11110 n = n | n >> 4 n = 11110 | 00001 n = 11111 n = n | n >> 8 n = 11111 | 00000 n = 11111 n = n | n >> 16 n = 11110 | 00000 n = 11111

Page 30: Data structures all in one

step 3: Return n+1 We get n + 1 as 100000 (32)

Program:

# include <stdio.h>

/* Finds next power of two for n. If n itself   is a power of two then returns n*/

unsigned int nextPowerOf2(unsigned int n){    n--;    n |= n >> 1;    n |= n >> 2;    n |= n >> 4;    n |= n >> 8;    n |= n >> 16;    n++;    return n;}

/* Driver program to test above function */int main(){    unsigned int n = 5;    printf("%d", nextPowerOf2(n));

    getchar();    return 0;

}

Time Complexity: O(lgn)

References:http://en.wikipedia.org/wiki/Power_of_2

Given an array A[] and a number x, check for pair in A[] with sum as xMay 30, 2009

Write a C program that, given an array A[] of n numbers and another number x, determines whether or not there exist two elements in S whose sum is exactly x.

METHOD 1 (Use Sorting)

Algorithm:

Page 31: Data structures all in one

hasArrayTwoCandidates (A[], ar_size, sum)1) Sort the array in non-decreasing order.2) Initialize two index variables to find the candidate elements in the sorted array. (a) Initialize first to the leftmost index: l = 0 (b) Initialize second the rightmost index: r = ar_size-13) Loop while l < r. (a) If (A[l] + A[r] == sum) then return 1 (b) Else if( A[l] + A[r] < sum ) then l++ (c) Else r-- 4) No candidates in whole array - return 0

Time Complexity: Depends on what sorting algorithm we use. If we use Merge Sort or Heap Sort then (-)(nlogn) in worst case. If we use Quick Sort then O(n^2) in worst case.Auxiliary Space : Again, depends on sorting algorithm. For example auxiliary space is O(n) for merge sort and O(1) for Heap Sort.

Example:Let Array be {1, 4, 45, 6, 10, -8} and sum to find be 16

Sort the arrayA = {-8, 1, 4, 6, 10, 45}

Initialize l = 0, r = 5A[l] + A[r] ( -8 + 45) > 16 => decrement r. Now r = 10A[l] + A[r] ( -8 + 10) < 2 => increment l. Now l = 1A[l] + A[r] ( 1 + 10) < 16 => increment l. Now l = 2A[l] + A[r] ( 4 + 10) < 14 => increment l. Now l = 3A[l] + A[r] ( 6 + 10) == 16 => Found candidates (return 1)

Note: If there are more than one pair having the given sum then this algorithm reports only one. Can be easily extended for this though.

Page 32: Data structures all in one

Implementation:

# include <stdio.h># define bool int

void quickSort(int *, int, int);

bool hasArrayTwoCandidates(int A[], int arr_size, int sum){    int l, r;

    /* Sort the elements */    quickSort(A, 0, arr_size-1);

    /* Now look for the two candidates in the sorted       array*/    l = 0;    r = arr_size-1;    while(l < r)    {         if(A[l] + A[r] == sum)              return 1;         else if(A[l] + A[r] < sum)              l++;         else // A[i] + A[j] > sum              r--;    }    return 0;}

/* Driver program to test above function */int main(){    int A[] = {1, 4, 45, 6, 10, -8};    int n = 16;    int arr_size = 6;

    if( hasArrayTwoCandidates(A, arr_size, n))        printf("Array has two elements with sum 16");    else        printf("Array doesn't have two elements with sum 16 ");

    getchar();    return 0;}

/* FOLLOWING FUNCTIONS ARE ONLY FOR SORTING    PURPOSE */void exchange(int *a, int *b){    int temp;    temp = *a;    *a   = *b;    *b   = temp;}

int partition(int A[], int si, int ei){    int x = A[ei];

Page 33: Data structures all in one

    int i = (si - 1);    int j;

    for (j = si; j <= ei - 1; j++)    {        if(A[j] <= x)        {            i++;            exchange(&A[i], &A[j]);        }    }    exchange (&A[i + 1], &A[ei]);    return (i + 1);}

/* Implementation of Quick SortA[] --> Array to be sortedsi  --> Starting indexei  --> Ending index*/void quickSort(int A[], int si, int ei){    int pi;    /* Partitioning index */    if(si < ei)    {        pi = partition(A, si, ei);        quickSort(A, si, pi - 1);        quickSort(A, pi + 1, ei);    }}

METHOD 2 (Use Hash Map)Thanks to Bindu for suggesting this method and thanks to Shekhu for providing code.This method works in O(n) time if range of numbers is known.Let sum be the given sum and A[] be the array in which we need to find pair.

1) Initialize Binary Hash Map M[] = {0, 0, …}2) Do following for each element A[i] in A[] (a) If M[x - A[i]] is set then print the pair (A[i], x – A[i]) (b) Set M[A[i]]

Implementation:

#include <stdio.h>#define MAX 100000

Page 34: Data structures all in one

void printPairs(int arr[], int arr_size, int sum){  int i, temp;  bool binMap[MAX] = {0}; /*initialize hash map as 0*/

  for(i = 0; i < arr_size; i++)  {    temp = sum - arr[i];    if(temp >= 0 && binMap[temp] == 1)    {      printf("Pair with given sum %d is (%d, %d) \n", sum, arr[i], temp);    }    binMap[arr[i]] = 1;  }}

/* Driver program to test above function */int main(){    int A[] = {1, 4, 45, 6, 10, 8};    int n = 16;    int arr_size = 6;

    printPairs(A, arr_size, n);

    getchar();    return 0;}

Time Complexity: O(n)Auxiliary Space: O(R) where R is range of integers.

If range of numbers include negative numbers then also it works. All we have to do for negative numbers is to make everything positive by adding the absolute value of smallest negative integer to all numbers.

Majority ElementMay 30, 2009

Majority Element: A majority element in an array A[] of size n is an element that appears more than n/2 times (and hence there is at most one such element).

Write a function which takes an array and emits the majority element (if it exists), otherwise prints NONE as follows:

I/P : 3 3 4 2 4 4 2 4 4 O/P : 4

I/P : 3 3 4 2 4 4 2 4

Page 35: Data structures all in one

O/P : NONE

METHOD 1 (Basic)The basic solution is to have two loops and keep track of maximum count for all different elements. If maximum count becomes greater than n/2 then break the loops and return the element having maximum count. If maximum count doesn’t become more than n/2 then majority element doesn’t exist.

Time Complexity: O(n*n).Auxiliary Space : O(1).

METHOD 2 (Using Binary Search Tree)Thanks to Sachin Midha for suggesting this solution.

Node of the Binary Search Tree (used in this approach) will be as follows.

struct tree{  int element;  int count;}BST;

Insert elements in BST one by one and if an element is already present then increment the count of the node. At any stage, if count of a node becomes more than n/2 then return.The method works well for the cases where n/2+1 occurrences of the majority element is present in the starting of the array, for example {1, 1, 1, 1, 1, 2, 3, 4}.

Time Complexity: If a binary search tree is used then time complexity will be O(n^2). If a self-balancing-binary-search tree is used then O(nlogn)Auxiliary Space: O(n)

METHOD 3 (Using Moore’s Voting Algorithm)

Page 36: Data structures all in one

This is a two step process.1. Get an element occurring most of the time in the array. This phase will make sure that if there is a majority element then it will return that only.2. Check if the element obtained from above step is majority element.

1. Finding a Candidate:The algorithm for first phase that works in O(n) is known as Moore’s Voting Algorithm. Basic idea of the algorithm is if we cancel out each occurrence of an element e with all the other elements that are different from e then e will exist till end if it is a majority element.

findCandidate(a[], size)1. Initialize index and count of majority element maj_index = 0, count = 12. Loop for i = 1 to size – 1 (a)If a[maj_index] == a[i] count++ (b)Else count--; (c)If count == 0 maj_index = i; count = 13. Return a[maj_index]

Above algorithm loops through each element and maintains a count of a[maj_index], If next element is same then increments the count, if next element is not same then decrements the count, and if the count reaches 0 then changes the maj_index to the current element and sets count to 1.First Phase algorithm gives us a candidate element. In second phase we need to check if the candidate is really a majority element. Second phase is simple and can be easily done in O(n). We just need to check if count of the candidate element is greater than n/2.

Example:A[] = 2, 2, 3, 5, 2, 2, 6Initialize:

Page 37: Data structures all in one

maj_index = 0, count = 1 –> candidate ‘2?2, 2, 3, 5, 2, 2, 6

Same as a[maj_index] => count = 22, 2, 3, 5, 2, 2, 6

Different from a[maj_index] => count = 12, 2, 3, 5, 2, 2, 6

Different from a[maj_index] => count = 0Since count = 0, change candidate for majority element to 5 => maj_index = 3, count = 12, 2, 3, 5, 2, 2, 6

Different from a[maj_index] => count = 0Since count = 0, change candidate for majority element to 2 => maj_index = 42, 2, 3, 5, 2, 2, 6

Same as a[maj_index] => count = 22, 2, 3, 5, 2, 2, 6

Different from a[maj_index] => count = 1

Finally candidate for majority element is 2.

First step uses Moore’s Voting Algorithm to get a candidate for majority element.

2. Check if the element obtained in step 1 is majority

printMajority (a[], size)1. Find the candidate for majority2. If candidate is majority. i.e., appears more than n/2 times. Print the candidate3. Else Print "NONE"

Implementation of method 3:

Page 38: Data structures all in one

/* Program for finding out majority element in an array */# include<stdio.h># define bool int

int findCandidate(int *, int);bool isMajority(int *, int, int);

/* Function to print Majority Element */void printMajority(int a[], int size){  /* Find the candidate for Majority*/  int cand = findCandidate(a, size);

  /* Print the candidate if it is Majority*/  if(isMajority(a, size, cand))    printf(" %d ", cand);  else    printf("NO Majority Element");}

/* Function to find the candidate for Majority */int findCandidate(int a[], int size){    int maj_index = 0, count = 1;    int i;    for(i = 1; i < size; i++)    {        if(a[maj_index] == a[i])            count++;        else            count--;        if(count == 0)        {            maj_index = i;            count = 1;        }    }    return a[maj_index];}

/* Function to check if the candidate occurs more than n/2 times */bool isMajority(int a[], int size, int cand){    int i, count = 0;    for (i = 0; i < size; i++)      if(a[i] == cand)         count++;    if (count > size/2)       return 1;    else       return 0;}

/* Driver function to test above functions */int main(){    int a[] = {1, 3, 3, 1, 2};    printMajority(a, 5);    getchar();    return 0;}

Page 39: Data structures all in one

Time Complexity: O(n)Auxiliary Space : O(1)

Now give a try to below questionGiven an array of 2n elements of which n elements are same and the remaining n elements are all different. Write a C program to find out the value which is present n times in the array. There is no restriction on the elements in the array. They are random (In particular they not sequential).

Write an Efficient Method to Check if a Number is Multiple of 3May 30, 2009

The very first solution that comes to our mind is the one that we learned in school. If sum of digits in a number is multiple of 3 then number is multiple of 3 e.g., for 612 sum of digits is 9 so it’s a multiple of 3. But this solution is not efficient. You have to get all decimal digits one by one, add them and then check if sum is multiple of 3.

There is a pattern in binary representation of the number that can be used to find if number is a multiple of 3. If difference between count of odd set bits (Bits set at odd positions) and even set bits is multiple of 3 then is the number.

Example: 23 (00..10111)1) Get count of all set bits at odd positions (For 23 it’s 3).2) Get count of all set bits at even positions (For 23 it’s 1).3) If difference of above two counts is a multiple of 3 then number is also a multiple of 3.

(For 23 it’s 2 so 23 is not a multiple of 3)

Take some more examples like 21, 15, etc…

Algorithm: isMutlipleOf3(n)1) Make n positive if n is negative.2) If number is 0 then return 13) If number is 1 then return 04) Initialize: odd_count = 0, even_count = 0

Page 40: Data structures all in one

5) Loop while n != 0 a) If rightmost bit is set then increment odd count. b) Right-shift n by 1 bit c) If rightmost bit is set then increment even count. d) Right-shift n by 1 bit6) return isMutlipleOf3(odd_count - even_count)

Proof:Above can be proved by taking the example of 11 in decimal numbers. (In this context 11 in decimal numbers is same as 3 in binary numbers)If difference between sum of odd digits and even digits is multiple of 11 then decimal number is multiple of 11. Let’s see how.

Let’s take the example of 2 digit numbers in decimalAB = 11A -A + B = 11A + (B – A)So if (B – A) is a multiple of 11 then is AB.

Let us take 3 digit numbers.

ABC = 99A + A + 11B – B + C = (99A + 11B) + (A + C – B)So if (A + C – B) is a multiple of 11 then is (A+C-B)

Let us take 4 digit numbers now.ABCD = 1001A + D + 11C – C + 999B + B – A= (1001A – 999B + 11C) + (D + B – A -C )So, if (B + D – A – C) is a multiple of 11 then is ABCD.

This can be continued for all decimal numbers.Above concept can be proved for 3 in binary numbers in the same way.

Time Complexity: O(logn)

Program:

#include<stdio.h>

/* Fnction to check if n is a multiple of 3*/

Page 41: Data structures all in one

int isMultipleOf3(int n){    int odd_count = 0;    int even_count = 0;

    /* Make no positive if +n is multiple of 3       then is -n. We are doing this to avoid       stack overflow in recursion*/    if(n < 0)   n = -n;    if(n == 0) return 1;    if(n == 1) return 0;

    while(n)    {        /* If odd bit is set then           increment odd counter */        if(n & 1)           odd_count++;        n = n>>1;

        /* If even bit is set then           increment even counter */        if(n & 1)            even_count++;        n = n>>1;    }

     return isMultipleOf3(abs(odd_count - even_count));}

/* Program to test function isMultipleOf3 */int main(){    int num = 23;    if (isMultipleOf3(num))        printf("num is multiple of 3");    else        printf("num is not a multiple of 3");    getchar();    return 0;}

Write a C program to find the parity of an unsigned integerMay 30, 2009

Parity: Parity of a number refers to whether it contains an odd or even number of 1-bits. The number has “odd parity”, if it contains odd number of 1-bits and is “even parity” if it contains even number of 1-bits.Main idea of the below solution is – Loop while n is not 0 and in loop unset one of the set bits and invert parity.

Algorithm: getParity(n)1. Initialize parity = 0

Page 42: Data structures all in one

2. Loop while n != 0 a. Invert parity parity = !parity b. Unset rightmost set bit n = n & (n-1)3. return parity

Example: Initialize: n = 13 (1101) parity = 0

n = 13 & 12 = 12 (1100) parity = 1n = 12 & 11 = 8 (1000) parity = 0n = 8 & 7 = 0 (0000) parity = 1

Program:

# include <stdio.h># define  bool int

/* Function to get parity of number n. It returns 1   if n has odd parity, and returns 0 if n has even   parity */bool getParity(unsigned int n){    bool parity = 0;    while (n)    {        parity = !parity;        n      = n & (n - 1);    }    return parity;}

/* Driver program to test getParity() */int main(){    unsigned int n = 7;    printf("Parity of no %d = %s",  n,             (getParity(n)? "odd": "even"));

    getchar();    return 0;}

Above solution can be optimized by using lookup table. Please refer to Bit Twiddle Hacks[1st reference] for details.

Time Complexity: The time taken by above algorithm is proportional to the number of bits set. Worst case complexity is O(Logn).

Page 43: Data structures all in one

Uses: Parity is used in error detection and cryptography.

References:http://graphics.stanford.edu/~seander/bithacks.html#ParityNaive – last checked on 30 May 2009.

Write a C program to reverse digits of a numberMay 30, 2009

ITERATIVE WAYAlgorithm:

Input: num(1) Initialize rev_num = 0(2) Loop while num > 0 (a) Multiply rev_num by 10 and add remainder of num divide by 10 to rev_num rev_num = rev_num*10 + num%10; (b) Divide num by 10(3) Return rev_num

Example:num = 4562rev_num = 0

rev_num = rev_num *10 + num%10 = 2num = num/10 = 456

rev_num = rev_num *10 + num%10 = 20 + 6 = 26num = num/10 = 45

rev_num = rev_num *10 + num%10 = 260 + 5 = 265num = num/10 = 4

rev_num = rev_num *10 + num%10 = 265 + 4 = 2654num = num/10 = 0

Program:

#include <stdio.h>

Page 44: Data structures all in one

/* Iterative function to reverse digits of num*/int reversDigits(int num){    int rev_num = 0;    while(num > 0)    {        rev_num = rev_num*10 + num%10;        num = num/10;    }    return rev_num;}

/*Driver program to test reversDigits*/int main(){    int num = 4562;    printf("Reverse of no. is %d", reversDigits(num));

    getchar();    return 0;}

Time Complexity: O(Log(n)) where n is the input number.

RECURSIVE WAYThanks to Raj for adding this to the original post.

#include <stdio.h>;

/* Recursive function to reverse digits of num*/int reversDigits(int num){  static int rev_num = 0;  static int base_pos = 1;  if(num > 0)  {    reversDigits(num/10);    rev_num  += (num%10)*base_pos;    base_pos *= 10;  }  return rev_num;}

/*Driver program to test reversDigits*/int main(){    int num = 4562;    printf("Reverse of no. is %d", reversDigits(num));

    getchar();    return 0;}

Page 45: Data structures all in one

Time Complexity: O(Log(n)) where n is the input number

Note that above above program doesn’t consider leading zeroes. For example, for 100 program will print 1. If you want to print 001 then see this comment from Maheshwar.

Try extensions of above functions that should also work for floating point numbers.

Efficient way to multiply with 7May 30, 2009

We can multiply a number by 7 using bitwise operator. First left shift the number by 3 bits (you will get 8n) then subtract the original numberfrom the shifted number and return the difference (8n – n).

Program:

# include<stdio.h>

int multiplyBySeven(unsigned int n){    /* Note the inner bracket here. This is needed       because precedence of '-' operator is higher       than '<<' */    return ((n<<3) - n);}

/* Driver program to test above function */int main(){    unsigned int n = 4;    printf("%u", multiplyBySeven(n));

    getchar();    return 0;}

Time Complexity: O(1)Space Complexity: O(1)

Note: Works only for positive integers.Same concept can be used for fast multiplication by 9 or other numbers.

Page 46: Data structures all in one

Write one line C function to find whether a no is power of twoMay 30, 2009

1. A simple method for this is to simply take the log of the number on base 2 and if you get an integer then number is power of 2.

2. Another solution is to keep dividing the number by two, i.e, do n = n/2 iteratively. In any iteration, if n%2 becomes non-zero and n is not 1 then n is not a power of 2. If n becomes 1 then it is a power of 2.

#include<stdio.h>#define bool int

/* Function to check if x is power of 2*/bool isPowerOfTwo(int n){  if(n == 0)    return 0;  while(n != 1)  {    n = n/2;    if(n%2 != 0 && n != 1)      return 0;  }  return 1;}

/*Driver program to test above function*/int main(){  int test_no = 31;  if(isPowerOfTwo(test_no))    printf("%d is a power of 2", test_no);  else    printf("%d is not a power of 2", test_no);  getchar();}

3. All power of two numbers have only one bit set. So count the no. of set bits and if you get 1 then number is a power of 2. Please see http://geeksforgeeks.org/?p=1176 for counting set bits.

4. If we subtract a power of 2 numbers by 1 then all unset bits after the only set bit become set; and the set bit become unset.

For example for 4 ( 100) and 16(10000), we get following after subtracting 1

Page 47: Data structures all in one

3 –> 01115 –> 01111

So, if a number n is a power of 2 then bitwise & of n and n-1 will be zero. We can say n is a power of 2 or not based on value of n&(n-1). The expression n&(n-1) will not work when n is 0. To handle this case also, our expression will become n& (!n&(n-1)) (thanks to Mohammad for adding this case).Below is the implementation of this method.

#include<stdio.h>#define bool int

/* Function to check if x is power of 2*/bool isPowerOfTwo (int x){  /* First x in the below expression is for the case when x is 0 */  return x && (!(x&(x-1)));}

/*Driver program to test above function*/int main(){    int test_no = 15;    if(isPowerOfTwo(test_no))       printf("%d is a power of 2", test_no);    else       printf("%d is not a power of 2", test_no);    getchar();}

Position of rightmost set bitJune 19, 2009

Write a one line C function to return position of first 1 from right to left, in binary representation of an Integer.

I/P 18, Binary Representation 010010O/P 2I/P 19, Binary Representation 010011O/P 1

Let I/P be 12 (1100)

Algorithm: (Example 18(010010))

1. Take two's complement of the given no as all bits are reverted

Page 48: Data structures all in one

except the first '1' from right to left (10111)

2 Do an bit-wise & with original no, this will return no with therequired one only (00010)

3 Take the log2 of the no, you will get position -1 (1)

4 Add 1 (2)

Program:

#include<stdio.h>#include<math.h>

unsigned int getFirstSetBitPos(int n){   return log2(n&-n)+1;}

int main(){    int n = 12;    printf("%u", getFirstSetBitPos(n));    getchar();    return 0;}

Print reverse of a string using recursionJune 19, 2009

Write a recursive C function to print reverse of a given string.

Program:

# include <stdio.h>

/* Function to print reverse of the passed string */void reverse(char *str){   if(*str)   {       reverse(str+1);       printf("%c", *str);   }}

/* Driver program to test above function */int main(){

Page 49: Data structures all in one

   char a[] = "Geeks for Geeks";   reverse(a);   getchar();   return 0;}

Explanation: Recursive function (reverse) takes string pointer (str) as input and calls itself with next location to passed pointer (str+1). Recursion continues this way, when pointer reaches ‘\0′, all functions accumulated in stack print char at passed location (str) and return one by one.

Time Complexity: O(n)

Find the Number Occurring Odd Number of TimesJune 22, 2009

Given an array of positive integers. All numbers occur even number of times except one number which occurs odd number of times. Find the number in O(n) time & constant space.

Example:I/P = [1, 2, 3, 2, 3, 1, 3]O/P = 3

Algorithm: Do bitwise XOR of all the elements. Finally we get the number which has odd occurrences.

Program:

#include <stdio.h>

int getOddOccurrence(int ar[], int ar_size){     int i;     int res = 0;     for (i=0; i < ar_size; i++)        res = res ^ ar[i];

     return res;}

/* Diver function to test above function */int main()

Page 50: Data structures all in one

{     int ar[] = {2, 3, 5, 4, 5, 2, 4, 3, 5, 2, 4, 4, 2};     int n = sizeof(ar)/sizeof(ar[0]);     printf("%d", getOddOccurrence(ar, n));     return 0;}

Time Complexity: O(n)

Largest Sum Contiguous SubarrayJune 22, 2009

Write an efficient C program to find the sum of contiguous subarray within a one-dimensional array of numbers which has the largest sum.

Kadane’s Algorithm:

Initialize: max_so_far = 0 max_ending_here = 0

Loop for each element of the array (a) max_ending_here = max_ending_here + a[i] (b) if(max_ending_here < 0) max_ending_here = 0 (c) if(max_so_far < max_ending_here) max_so_far = max_ending_herereturn max_so_far

Explanation:Simple idea of the Kadane's algorithm is to look for all positive contiguous segments of the array (max_ending_here is used for this). And keep track of maximum sum contiguous segment among all positive segments (max_so_far is used for this). Each time we get a positive sum compare it with max_so_far and update max_so_far if it is greater than max_so_far

Lets take the example:{-2, -3, 4, -1, -2, 1, 5, -3}

Page 51: Data structures all in one

max_so_far = max_ending_here = 0

for i=0, a[0] = -2max_ending_here = max_ending_here + (-2)Set max_ending_here = 0 because max_ending_here < 0

for i=1, a[1] = -3max_ending_here = max_ending_here + (-3)Set max_ending_here = 0 because max_ending_here < 0

for i=2, a[2] = 4max_ending_here = max_ending_here + (4)max_ending_here = 4max_so_far is updated to 4 because max_ending_here greater than max_so_far which was 0 till now

for i=3, a[3] = -1max_ending_here = max_ending_here + (-1)max_ending_here = 3

for i=4, a[4] = -2max_ending_here = max_ending_here + (-2)max_ending_here = 1

for i=5, a[5] = 1max_ending_here = max_ending_here + (1)max_ending_here = 2

for i=6, a[6] = 5max_ending_here = max_ending_here + (5)max_ending_here = 7max_so_far is updated to 7 because max_ending_here is greater than max_so_far

for i=7, a[7] = -3max_ending_here = max_ending_here + (-3)max_ending_here = 4

Program:

#include<stdio.h>

Page 52: Data structures all in one

int maxSubArraySum(int a[], int size){   int max_so_far = 0, max_ending_here = 0;   int i;   for(i = 0; i < size; i++)   {     max_ending_here = max_ending_here + a[i];     if(max_ending_here < 0)        max_ending_here = 0;     if(max_so_far < max_ending_here)        max_so_far = max_ending_here;    }    return max_so_far;}

/*Driver program to test maxSubArraySum*/int main(){   int a[] = {-2, -3, 4, -1, -2, 1, 5, -3};   int n = sizeof(a)/sizeof(a[0]);   int max_sum = maxSubArraySum(a, n);   printf("Maximum contiguous sum is %d\n", max_sum);   getchar();   return 0;}

Notes:Algorithm doesn't work for all negative numbers. It simply returns 0 if all numbers are negative. For handling this we can add an extra phase before actual implementation. The phase will look if all numbers are negative, if they are it will return maximum of them (or smallest in terms of absolute value). There may be other ways to handle it though.

Above program can be optimized further, if we compare max_so_far with max_ending_here only if max_ending_here is greater than 0.

int maxSubArraySum(int a[], int size){   int max_so_far = 0, max_ending_here = 0;   int i;   for(i = 0; i < size; i++)   {     max_ending_here = max_ending_here + a[i];     if(max_ending_here < 0)         max_ending_here = 0;

     /* Do not compare for all elements. Compare only        when  max_ending_here > 0 */     else if (max_so_far < max_ending_here)         max_so_far = max_ending_here;   }   return max_so_far;}

Page 53: Data structures all in one

Time Complexity: O(n)Algorithmic Paradigm: Dynamic Programming

Now try below questionGiven an array of integers (possibly some of the elements negative), write a C program to find out the *maximum product* possible by adding 'n' consecutive integers in the array, n <= ARRAY_SIZE. Also give where in the array this sequence of n integers starts.

References:http://en.wikipedia.org/wiki/Kadane%27s_Algorithm

Implement Your Own sizeofJune 22, 2009

Here is an implementation.

#define my_sizeof(type) (char *)(&type+1)-(char*)(&type)int main(){    double x;    printf("%d", my_sizeof(x));    getchar();    return 0;}

You can also implement using function instead of macro, but function implementation cannot be done in C as C doesn’t support function overloading and sizeof() is supposed to receive parameters of all data types.

Note that above implementation assumes that size of character is one byte.

Time Complexity: O(1)Space Complexity: O(1)

Find the Missing NumberJune 22, 2009

You are given a list of n-1 integers and these integers are in the range of 1 to n. There are no duplicates in list. One of the integers is missing in the list. Write an efficient code to find the missing integer.

Page 54: Data structures all in one

Example:I/P [1, 2, 4, ,6, 3, 7, 8]O/P 5

METHOD 1(Use sum formula)Algorithm:

1. Get the sum of numbers total = n*(n+1)/22 Subtract all the numbers from sum and you will get the missing number.

Program:

#include<stdio.h>

/* getMissingNo takes array and size of array as arguments*/int getMissingNo (int a[], int n){    int i, total;    total  = (n+1)*(n+2)/2;    for ( i = 0; i< n; i++)       total -= a[i];    return total;}

/*program to test above function */int main(){    int a[] = {1,2,4,5,6};    int miss = getMissingNo(a,5);    printf("%d", miss);    getchar();}

Time Complexity: O(n)

METHOD 2(Use XOR)

1) XOR all the array elements, let the result of XOR be X1. 2) XOR all numbers from 1 to n, let XOR be X2.

Page 55: Data structures all in one

3) XOR of X1 and X2 gives the missing number.#include<stdio.h>

/* getMissingNo takes array and size of array as arguments*/int getMissingNo(int a[], int n){    int i;    int x1 = a[0]; /* For xor of all the elemets in arary */    int x2 = 1; /* For xor of all the elemets from 1 to n+1 */

    for (i = 1; i< n; i++)        x1 = x1^a[i];

    for ( i = 2; i <= n+1; i++)        x2 = x2^i;

    return (x1^x2);}

/*program to test above function */int main(){    int a[] = {1, 2, 4, 5, 6};    int miss = getMissingNo(a, 5);    printf("%d", miss);    getchar();}

Time Complexity: O(n)

In method 1, if the sum of the numbers goes beyond maximum allowed integer, then there can be integer overflow and we may not get correct answer. Method 2 has no such problems.

Power SetJune 22, 2009

Power Set Power set P(S) of a set S is the set of all subsets of S. For example S = {a, b, c} then P(s) = {{}, {a}, {b}, {c}, {a,b}, {a, c}, {b, c}, {a, b, c}}.

If S has n elements in it then P(s) will have 2^n elements

Algorithm:

Input: Set[], set_size1. Get the size of power set powet_set_size = pow(2, set_size)

Page 56: Data structures all in one

2 Loop for counter from 0 to pow_set_size (a) Loop for i = 0 to set_size (i) If ith bit in counter is set Print ith element from set for this subset (b) Print seperator for subsets i.e., newline

Example:

Set = [a,b,c]power_set_size = pow(2, 3) = 8Run for binary counter = 000 to 111

Value of Counter Subset 000 -> Empty set 001 -> a 011 -> ab 100 -> c 101 -> ac 110 -> bc 111 -> abc

Program:

#include <stdio.h>#include <math.h>

void printPowerSet(char *set, int set_size){    /*set_size of power set of a set with set_size      n is (2**n -1)*/    unsigned int pow_set_size = pow(2, set_size);    int counter, j;

    /*Run from counter 000..0 to 111..1*/    for(counter = 0; counter < pow_set_size; counter++)    {      for(j = 0; j < set_size; j++)       {          /* Check if jth bit in the counter is set             If set then pront jth element from set */          if(counter & (1<<j))            printf("%c", set[j]);       }       printf("\n");    }

Page 57: Data structures all in one

}

/*Driver program to test printPowerSet*/int main(){    char set[] = {'a','b','c'};    printPowerSet(set, 3);

    getchar();    return 0;}

Time Complexity: O(n2^n)

There are more efficient ways of doing this. Will update here soon with more efficient method.

References:http://en.wikipedia.org/wiki/Power_set

Condition To Print “HelloWord”June 22, 2009

What should be the “condition” so that the following code snippet prints both HelloWorld !

if "condition" printf ("Hello"); else printf("World");

Solution:

#include<stdio.h>int main(){    if(!printf("Hello"))        printf("Hello");    else        printf("World");    getchar();}

Explanation: Printf returns the number of character it has printed successfully. So, following solutions will also work

if (printf(“Hello”) < 0) orif (printf(“Hello”) < 1) etc

Page 58: Data structures all in one

Please comment if you find more solutions of this.

Change/add only one character and print ‘*’ exactly 20 timesJune 22, 2009

In the below code, change/add only one character and print ‘*’ exactly 20 times.

int main(){ int i, n = 20; for (i = 0; i < n; i--) printf("*"); getchar(); return 0;}

Solutions:

1. Replace i by n in for loop's third expression

#include <stdio.h>int main(){    int i, n = 20;    for (i = 0; i < n; n--)        printf("*");    getchar();    return 0;}

2. Put '-' before i in for loop's second expression

#include <stdio.h>int main(){    int i, n = 20;    for (i = 0; -i < n; i--)        printf("*");    getchar();    return 0;}

3. Replace < by + in for loop's second expression

#include <stdio.h>

Page 59: Data structures all in one

int main(){    int i, n = 20;    for (i = 0; i + n; i--)       printf("*");    getchar();    return 0;}

Let's extend the problem little.

Change/add only one character and print '*' exactly 21 times.

Solution: Put negation operator before i in for loop's second expression.

Explanation: Negation operator converts the number into its one's complement.

No. One's complement 0 (00000..00) -1 (1111..11) -1 (11..1111) 0 (00..0000) -2 (11..1110) 1 (00..0001) -3 (11..1101) 2 (00..0010)...............................................-20 (11..01100) 19 (00..10011)#include <stdio.h>int main(){    int i, n = 20;    for (i = 0; ~i < n; i--)        printf("*");    getchar();    return 0;}

Please comment if you find more solutions of above problems.

8 queen problemJune 22, 2009

The eight queens problem is the problem of placing eight queens on an 8×8 chessboard such that none of them attack one another (no two are in the same row, column, or diagonal). More generally, the n queens problem places n queens on an n×n chessboard.

There are different solutions for the problem.

Page 60: Data structures all in one

You can find detailed solutions at http://en.literateprograms.org/Eight_queens_puzzle_(C)

Tree TraversalsJune 23, 2009

Unlike linear data structures (Array, Linked List, Queues, Stacks, etc) which have only one logical way to traverse them, trees can be traversed in different ways. Following are the generally used ways for traversing trees.

Example Tree

Depth First Traversals:(a) Inorder(b) Preorder(c) Postorder

Breadth First or Level Order TraversalPlease see this post for Breadth First Traversal.

Inorder Traversal:

Algorithm Inorder(tree) 1. Traverse the left subtree, i.e., call Inorder(left-subtree) 2. Visit the root. 3. Traverse the right subtree, i.e., call Inorder(right-subtree)

Uses of InorderIn case of binary search trees (BST), Inorder traversal gives nodes in non-decreasing order. To get nodes of BST in non-increasing order, a

Page 61: Data structures all in one

variation of Inorder traversal where Inorder itraversal s reversed, can be used.Example: Inorder traversal for the above given figure is 4 2 5 1 3.

Preorder Traversal:

Algorithm Preorder(tree) 1. Visit the root. 2. Traverse the left subtree, i.e., call Preorder(left-subtree) 3. Traverse the right subtree, i.e., call Preorder(right-subtree)

Uses of PreorderPreorder traversal is used to create a copy of the tree. Preorder traversal is also used to get prefix expression on of an expression tree. Please see http://en.wikipedia.org/wiki/Polish_notation to know why prefix expressions are useful.Example: Preorder traversal for the above given figure is 1 2 4 5 3.

Postorder Traversal:

Algorithm Postorder(tree) 1. Traverse the left subtree, i.e., call Postorder(left-subtree) 2. Traverse the right subtree, i.e., call Postorder(right-subtree) 3. Visit the root.

Uses of PostorderPostorder traversal is used to delete the tree. Please see the question for deletion of tree for details. Postorder traversal is also useful to get the postfix expression of an expression tree. Please seehttp://en.wikipedia.org/wiki/Reverse_Polish_notation to for the usage of postfix expression.

Example: Postorder traversal for the above given figure is 4 5 2 3 1.

#include <stdio.h>#include <stdlib.h>

Page 62: Data structures all in one

/* A binary tree node has data, pointer to left child   and a pointer to right child */struct node{     int data;     struct node* left;     struct node* right;};

/* Helper function that allocates a new node with the   given data and NULL left and right pointers. */struct node* newNode(int data){     struct node* node = (struct node*)                                  malloc(sizeof(struct node));     node->data = data;     node->left = NULL;     node->right = NULL;

     return(node);}

/* Given a binary tree, print its nodes according to the  "bottom-up" postorder traversal. */void printPostorder(struct node* node){     if (node == NULL)        return;

     // first recur on left subtree     printPostorder(node->left);

     // then recur on right subtree     printPostorder(node->right);

     // now deal with the node     printf("%d ", node->data);}

/* Given a binary tree, print its nodes in inorder*/void printInorder(struct node* node){     if (node == NULL)          return;

     /* first recur on left child */     printInorder(node->left);

     /* then print the data of node */     printf("%d ", node->data);

     /* now recur on right child */     printInorder(node->right);}

/* Given a binary tree, print its nodes in inorder*/void printPreorder(struct node* node){

Page 63: Data structures all in one

     if (node == NULL)          return;

     /* first print data of node */     printf("%d ", node->data);

     /* then recur on left sutree */     printPreorder(node->left);

     /* now recur on right subtree */     printPreorder(node->right);}

/* Driver program to test above functions*/int main(){     struct node *root  = newNode(1);     root->left             = newNode(2);     root->right           = newNode(3);     root->left->left     = newNode(4);     root->left->right   = newNode(5);

     printf("\n Preorder traversal of binary tree is \n");     printPreorder(root);

     printf("\n Inorder traversal of binary tree is \n");     printInorder(root);

     printf("\n Postorder traversal of binary tree is \n");     printPostorder(root);

     getchar();     return 0;}

Time Complexity: O(n)Let us prove it:

Complexity function T(n) — for all problem where tree traversal is involved — can be defined as:

T(n) = T(k) + T(n – k – 1) + c

Where k is the number of nodes on one side of root and n-k-1 on the other side.

Let’s do analysis of boundary conditions

Case 1: Skewed tree (One of the subtrees is empty and other subtree is non-empty )

Page 64: Data structures all in one

k is 0 in this case.T(n) = T(0) + T(n-1) + cT(n) = 2T(0) + T(n-2) + 2cT(n) = 3T(0) + T(n-3) + 3cT(n) = 4T(0) + T(n-4) + 4c

…………………………………………………………………………………….T(n) = (n-1)T(0) + T(1) + (n-1)cT(n) = nT(0) + (n)c

Value of T(0) will be some constant say d. (traversing a empty tree will take some constants time)

T(n) = n(c+d)T(n) = (-)(n) (Theta of n)

Case 2: Both left and right subtrees have equal number of nodes.

T(n) = 2T(|_n/2_|) + c

This recursive function is in the standard form (T(n) = aT(n/b) + (-)(n) ) for master methodhttp://en.wikipedia.org/wiki/Master_theorem. If we solve it by master method we get (-)(n)

Auxiliary Space : If we don’t consider size of stack for function calls then O(1) otherwise O(n).

Write a C program to Calculate Size of a treeJune 23, 2009

Size of a tree is the number of elements present in the tree. Size of the below tree is 5.

Page 65: Data structures all in one

Example Tree

Size() function recursively calculates the size of a tree. It works as follows:

Size of a tree = Size of left subtree + 1 + Size of right subtree

Algorithm:

size(tree)1. If tree is empty then return 02. Else (a) Get the size of left subtree recursively i.e., call size( tree->left-subtree) (a) Get the size of right subtree recursively i.e., call size( tree->right-subtree) (c) Calculate size of the tree as following: tree_size = size(left-subtree) + size(right- subtree) + 1 (d) Return tree_size#include <stdio.h>#include <stdlib.h>

/* A binary tree node has data, pointer to left child   and a pointer to right child */struct node{    int data;    struct node* left;    struct node* right;};

/* Helper function that allocates a new node with the   given data and NULL left and right pointers. */

Page 66: Data structures all in one

struct node* newNode(int data){  struct node* node = (struct node*)                       malloc(sizeof(struct node));  node->data = data;  node->left = NULL;  node->right = NULL;

  return(node);}

/* Computes the number of nodes in a tree. */int size(struct node* node){  if (node==NULL)    return 0;  else    return(size(node->left) + 1 + size(node->right));}

/* Driver program to test size function*/int main(){  struct node *root = newNode(1);  root->left        = newNode(2);  root->right       = newNode(3);  root->left->left  = newNode(4);  root->left->right = newNode(5);

  printf("Size of the tree is %d", size(root));  getchar();  return 0;}

Time & Space Complexities: Since this program is similar to traversal of tree, time and space complexities will be same as Tree traversal (Please see our Tree Traversal post for details)

Write C Code to Determine if Two Trees are IdenticalJune 26, 2009

Two trees are identical when they have same data and arrangement of data is also same.

To identify if two trees are identical, we need to traverse both trees simultaneously, and while traversing we need to compare data and children of the trees.

Algorithm:

sameTree(tree1, tree2)

Page 67: Data structures all in one

1. If both trees are empty then return 1.2. Else If both trees are non -empty (a) Check data of the root nodes (tree1->data == tree2->data) (b) Check left subtrees recursively i.e., call sameTree( tree1->left_subtree, tree2->left_subtree) (c) Check right subtrees recursively i.e., call sameTree( tree1->right_subtree, tree2->right_subtree) (d) If a,b and c are true then return 1.3 Else return 0 (one is empty and other is not)#include <stdio.h>#include <stdlib.h>

/* A binary tree node has data, pointer to left child   and a pointer to right child */struct node{    int data;    struct node* left;    struct node* right;};

/* Helper function that allocates a new node with the   given data and NULL left and right pointers. */struct node* newNode(int data){    struct node* node = (struct node*)                             malloc(sizeof(struct node));    node->data  = data;    node->left  = NULL;    node->right = NULL;

    return(node);}

/* Given two trees, return true if they are structurally identical */int identicalTrees(struct node* a, struct node* b){    /*1. both empty */    if (a==NULL && b==NULL)        return 1;

    /* 2. both non-empty -> compare them */    else if (a!=NULL && b!=NULL)   {

Page 68: Data structures all in one

        return        (            a->data == b->data &&            identicalTrees(a->left, b->left) &&            identicalTrees(a->right, b->right)        );    }    /* 3. one empty, one not -> false */    else return 0;}

/* Driver program to test identicalTrees function*/int main(){    struct node *root1 = newNode(1);    struct node *root2 = newNode(1);    root1->left = newNode(2);    root1->right = newNode(3);    root1->left->left  = newNode(4);    root1->left->right = newNode(5);

    root2->left = newNode(2);    root2->right = newNode(3);    root2->left->left = newNode(4);    root2->left->right = newNode(5);

    if(identicalTrees(root1, root2))        printf("Both tree are identical.");    else        printf("Trees are not identical.");

    getchar();  return 0;}

Time Complexity:Complexity of the identicalTree() will be according to the tree with lesser number of nodes. Let number of nodes in two trees be m and n then complexity of sameTree() is O(m) where m < n.

Write a C Program to Find the Maximum Depth or Height of a TreeJune 27, 2009

Maximum depth or height of the below tree is 3.

Page 69: Data structures all in one

Example Tree

Recursively calculate height of left and right subtrees of a node and assign height to the node as max of the heights of two children plus 1. See below pseudo code and program for details.

Algorithm:

maxDepth()1. If tree is empty then return 02. Else (a) Get the max depth of left subtree recursively i.e., call maxDepth( tree->left-subtree) (a) Get the max depth of right subtree recursively i.e., call maxDepth( tree->right-subtree) (c) Get the max of max depths of left and right subtrees and add 1 to it for the current node. max_depth = max(max dept of left subtree, max depth of right subtree) + 1 (d) Return max_depth

See the below diagram for more clarity about execution of the recursive function maxDepth() for above example tree.

maxDepth('1') = max(maxDepth('2'), maxDepth('3')) + 1

Page 70: Data structures all in one

= 2 + 1 / \ / \ / \ / \ / \ maxDepth('1') maxDepth('3') = 1= max(maxDepth('4'), maxDepth('5')) + 1= 1 + 1 = 2 / \ / \ / \ / \ / \ maxDepth('4') = 1 maxDepth('5') = 1

Implementation:

#include<stdio.h>#include<stdlib.h>

/* A binary tree node has data, pointer to left child   and a pointer to right child */struct node{    int data;    struct node* left;    struct node* right;};

/* Compute the "maxDepth" of a tree -- the number of    nodes along the longest path from the root node    down to the farthest leaf node.*/int maxDepth(struct node* node){   if (node==NULL)       return 0;   else   {       /* compute the depth of each subtree */       int lDepth = maxDepth(node->left);       int rDepth = maxDepth(node->right);

       /* use the larger one */       if (lDepth > rDepth)           return(lDepth+1);

Page 71: Data structures all in one

       else return(rDepth+1);   }}

/* Helper function that allocates a new node with the   given data and NULL left and right pointers. */struct node* newNode(int data){    struct node* node = (struct node*)                                malloc(sizeof(struct node));    node->data = data;    node->left = NULL;    node->right = NULL;

    return(node);}

int main(){    struct node *root = newNode(1);

    root->left = newNode(2);    root->right = newNode(3);    root->left->left = newNode(4);    root->left->right = newNode(5);

    printf("Hight of tree is %d", maxDepth(root));

    getchar();    return 0;}

Time Complexity: O(n) (Please see our post Tree Traversal for details)

References:http://cslibrary.stanford.edu/110/BinaryTrees.html

Write a C program to Delete a Tree.June 27, 2009

To delete a tree we must traverse all the nodes of the tree and delete them one by one. So which traversal we should use – Inorder or Preorder or Postorder. Answer is simple – Postorder, because before deleting the parent node we should delete its children nodes first

We can delete tree with other traversals also with extra space complexity but why should we go for other traversals if we have Postorder available which does the work without storing anything in same time complexity.

Page 72: Data structures all in one

For the following tree nodes are deleted in order – 4, 5, 2, 3, 1

Example Tree

Program

#include<stdio.h>#include<stdlib.h>

/* A binary tree node has data, pointer to left child   and a pointer to right child */struct node{    int data;    struct node* left;    struct node* right;};

/* Helper function that allocates a new node with the   given data and NULL left and right pointers. */struct node* newNode(int data){    struct node* node = (struct node*)                           malloc(sizeof(struct node));

    node->data = data;    node->left = NULL;    node->right = NULL;    return(node);}

/*  This function traverses tree in post order to    to delete each and every node of the tree */void deleteTree(struct node* node){    if (node == NULL) return;

    /* first delete both subtrees */    deleteTree(node->left);    deleteTree(node->right);

    /* then delete the node */    printf("\n Deleting node: %d", node->data);    free(node);}

Page 73: Data structures all in one

/* Driver program to test deleteTree function*/int main(){    struct node *root = newNode(1);    root->left            = newNode(2);    root->right          = newNode(3);    root->left->left     = newNode(4);    root->left->right   = newNode(5);

    deleteTree(root);    root = NULL;

    printf("\n Tree deleted ");

    getchar();    return 0;}

The above deleteTree() function deletes the tree, but doesn’t change root to NULL which may cause problems if the user of deleteTree() doesn’t change root to NULL and tires to access values using root pointer. We can modify the deleteTree() function to take reference to the root node so that this problem doesn’t occur. See the following code.

#include<stdio.h>#include<stdlib.h>

/* A binary tree node has data, pointer to left child   and a pointer to right child */struct node{    int data;    struct node* left;    struct node* right;};

/* Helper function that allocates a new node with the   given data and NULL left and right pointers. */struct node* newNode(int data){    struct node* node = (struct node*)                           malloc(sizeof(struct node));

    node->data = data;    node->left = NULL;    node->right = NULL;    return(node);}

/*  This function is same as deleteTree() in the previous program */void _deleteTree(struct node* node){    if (node == NULL) return;

    /* first delete both subtrees */

Page 74: Data structures all in one

    _deleteTree(node->left);    _deleteTree(node->right);

    /* then delete the node */    printf("\n Deleting node: %d", node->data);    free(node);}

/* Deletes a tree and sets the root as NULL */void deleteTree(struct node** node_ref){  _deleteTree(*node_ref);  *node_ref = NULL;}

/* Driver program to test deleteTree function*/int main(){    struct node *root = newNode(1);    root->left            = newNode(2);    root->right          = newNode(3);    root->left->left     = newNode(4);    root->left->right   = newNode(5);

    // Note that we pass the address of root here    deleteTree(&root);    printf("\n Tree deleted ");

    getchar();    return 0;}

Time Complexity: O(n)Space Complexity: If we don’t consider size of stack for function calls then O(1) otherwise O(n)

Write an Efficient C Function to Convert a Binary Tree into its Mirror TreeJune 27, 2009

Mirror of a Tree: Mirror of a Binary Tree T is another Binary Tree M(T) with left and right children of all non-leaf nodes interchanged.

Page 75: Data structures all in one

Trees in the below figure are mirror of each other

Algorithm - Mirror(tree):

(1) Call Mirror for left-subtree i.e., Mirror(left-subtree)(2) Call Mirror for right-subtree i.e., Mirror(left-subtree)(3) Swap left and right subtrees. temp = left-subtree left-subtree = right-subtree right-subtree = temp

Program:

#include<stdio.h>#include<stdlib.h>

/* A binary tree node has data, pointer to left child   and a pointer to right child */struct node{    int data;    struct node* left;    struct node* right;};

/* Helper function that allocates a new node with the   given data and NULL left and right pointers. */struct node* newNode(int data)

{  struct node* node = (struct node*)                       malloc(sizeof(struct node));  node->data = data;  node->left = NULL;  node->right = NULL;

  return(node);}

/* Change a tree so that the roles of the  left and    right pointers are swapped at every node.

 So the tree...       4      / \     2   5    / \   1   3

Page 76: Data structures all in one

 is changed to...       4      / \     5   2        / \       3   1*/void mirror(struct node* node){  if (node==NULL)    return;  else  {    struct node* temp;

    /* do the subtrees */    mirror(node->left);    mirror(node->right);

    /* swap the pointers in this node */    temp        = node->left;    node->left  = node->right;    node->right = temp;  }}

/* Helper function to test mirror(). Given a binary   search tree, print out its data elements in   increasing sorted order.*/void inOrder(struct node* node){  if (node == NULL)    return;

  inOrder(node->left);  printf("%d ", node->data);

  inOrder(node->right);}

/* Driver program to test mirror() */int main(){  struct node *root = newNode(1);  root->left        = newNode(2);  root->right       = newNode(3);  root->left->left  = newNode(4);  root->left->right = newNode(5);

  /* Print inorder traversal of the input tree */  printf("\n Inorder traversal of the constructed tree is \n");  inOrder(root);

  /* Convert tree to its mirror */  mirror(root);

  /* Print inorder traversal of the mirror tree */  printf("\n Inorder traversal of the mirror tree is \n");

Page 77: Data structures all in one

  inOrder(root);

  getchar();  return 0;}

Time & Space Complexities: This program is similar to traversal of tree space and time complexities will be same as Tree traversal (Please see our Tree Traversal post for details)

Day-2

Output of C Programs | Set 1June 27, 2009

Predict the output of below programs.

Question 1

#include<stdio.h>

int main()

{

   int n;

   for(n = 7; n!=0; n--)

     printf("n = %d", n--);

   getchar();

   return 0;

}

Output:Above program goes in infinite loop because n is never zero when loop condition (n != 0) is checked.

Question 2

#include<stdio.h>

int main()

Page 78: Data structures all in one

{

   printf("%x", -1<<1);

   getchar();

   return 0;

}

Output is dependent on the compiler. For 32 bit compiler it would be fffffffe and for 16 bit it would be fffe.

Question 3

# include <stdio.h>

# define scanf  "%s Geeks For Geeks "

main()

{

   printf(scanf, scanf);

   getchar();

   return 0;

}

Output: %s Geeks For Geeks Geeks For GeeksExplanation: After pre-processing phase of compilation, printf statement will become.

printf("%s Geeks For Geeks ", "%s Geeks For Geeks ");

Now you can easily guess why output is %s Geeks For Geeks Geeks For Geeks.

Question 4

#include <stdlib.h>

#include <stdio.h>

enum {false, true};

Page 79: Data structures all in one

int main()

{

   int i = 1;

   do

   {

      printf("%d\n", i);

      i++;

      if (i < 15)

        continue;

   } while (false);

   getchar();

   return 0;

}

Output: 1Explanation: The do wile loop checks condition after each iteration. So after continue statement, control transfers to the statement while(false). Since the condition is false ‘i’ is printed only once.

Now try below program.

#include <stdlib.h>

#include <stdio.h>

enum {false, true};

int main()

{

   int i = 1;

   do

   {

     printf("%d\n", i);

     i++;

Page 80: Data structures all in one

     if (i < 15)

       break;

     } while (true);

     getchar();

     return 0;

}

Question 5

char *getString()

{

   char *str = "Nice test for strings";

   return str;

}

int main()

{

   printf("%s", getString());

   getchar();

   return 0;

}

Output: “Nice test for strings”The above program works because string constants are stored in Data Section (not in Stack Section). So, when getString returns *str is not lost.

Output of C Programs | Set 2June 29, 2009

Predict the output of below programs.

Question 1

Page 81: Data structures all in one

char *getString()

{

    char str[] = "Will I be printed?";

    return str;

}

int main()

{

    printf("%s", getString());

    getchar();

}

Output: Some garbage valueThe above program doesn’t work because array variables are stored in Stack Section. So, when getString returns values at str are deleted and str becomes dangling pointer.

Question 2

int main()

{

    static int i=5;

    if(--i){

        main();

        printf("%d ",i);

    }

}

Output: 0 0 0 0Explanation: Since i is a static variable and is stored in Data Section, all calls to main share same i.

Question 3

int main()

Page 82: Data structures all in one

{

    static int var = 5;

    printf("%d ",var--);

    if(var)

        main();

}

Output: 5 4 3 2 1Explanation: Same as previous question. The only difference here is, sequence of calling main and printf is changed, therefore different output.

Question 4

int main()

{

    int x;

    printf("%d",scanf("%d",&x));

    /* Suppose that input value given

        for above scanf is 20 */

    return 1;

}

Output: 1scanf returns the no. of inputs it has successfully read.

Question 5

# include <stdio.h>

int main()

{

   int i=0;

   for(i=0; i<20; i++)

   {

Page 83: Data structures all in one

     switch(i)

     {

       case 0:

         i+=5;

       case 1:

         i+=2;

       case 5:

         i+=5;

       default:

         i+=4;

         break;

     }

     printf("%d  ", i);

   }

   getchar();

   return 0;

}

Output: 16 21Explanation:Initially i = 0. Since case 0 is true i becomes 5, and since there is no break statement till last statement of switch block, i becomes 16. Now in next iteration no case is true, so execution goes to default and i becomes 21.

In C, if one case is true switch block is executed until it finds break statement. If no break statement is present all cases are executed after the true case. If you want to know why switch is implemented like this, well this implementation is useful for situations like below.

switch (c) { case 'a':

Page 84: Data structures all in one

case 'e': case 'i' : case 'o': case 'u': printf(" Vowel character"); break; default : printf("Not a Vowel character");; break; }Output of C Programs | Set 3June 29, 2009

Predict the output of the below program.

Question 1

#include <stdio.h>

int main()

{

  printf("%d", main);

  getchar();

  return 0;

}

Output: Address of function main.Explanation: Name of the function is actually a pointer variable to the function and prints the address of the function. Symbol table is implemented like this.

struct { char *name; int (*funcptr)();}symtab[] = { "func", func, "anotherfunc", anotherfunc,

Page 85: Data structures all in one

};

Question 2

#include <stdio.h>

int main()

{

   printf("\new_c_question\by");

   printf("\rgeeksforgeeks");

   getchar();

   return 0;

}

Output: geeksforgeekslExplanation: First printf prints “ew_c_questioy”. Second printf has \r in it so it goes back to start of the line and starts printing characters.

Now try to print following without using any of the escape characters.

new c questions bygeeksforgeeks

Question 3

# include<stdio.h>

# include<stdlib.h>

void fun(int *a)

{

    a = (int*)malloc(sizeof(int));

}

int main()

Page 86: Data structures all in one

{

    int *p;

    fun(p);

    *p = 6;

    printf("%d\n",*p);

    getchar();

    return(0);

}

It does not work. Try replacing “int *p;” with “int *p = NULL;” and it will try to dereference a null pointer.

This is because fun() makes a copy of the pointer, so when malloc() is called, it is setting the copied pointer to the memory location, not p. p is pointing to random memory before and after the call to fun(), and when you dereference it, it will crash.

If you want to add memory to a pointer from a function, you need to pass the address of the pointer (ie. double pointer).

Thanks to John Doe for providing the correct solution.

Question 4

#include <stdio.h>

int main()

{

    int i;

    i = 1, 2, 3;

    printf("i = %d\n", i);

    getchar();

    return 0;

Page 87: Data structures all in one

}

Output: 1The above program prints 1. Associativity of comma operator is from left to right, but = operator has higher precedence than comma operator.Therefore the statement i = 1, 2, 3 is treated as (i = 1), 2, 3 by the compiler.

Now it should be easy to tell output of below program.

#include <stdio.h>

int main()

{

    int i;

    i = (1, 2, 3);

    printf("i  = %d\n", i);

    getchar();

     return 0;

}

Question 5

#include <stdio.h>

int main()

{

    int first = 50, second = 60, third;

    third = first /* Will this comment work? */ + second;

    printf("%d /* And this? */ \n", third);

    getchar();

    return 0;

Page 88: Data structures all in one

}

Output: 110 /* And this? */Explanation: Compiler removes everything between “/*” and “*/” if they are not present inside double quotes (“”).

Check for Integer OverflowJune 29, 2009

Write a “C” function, int addOvf(int* result, int a, int b) If there is no overflow, the function places the resultant = sum a+b in “result” and returns 0. Otherwise it returns -1. The solution of casting to long and adding to find detecting the overflow is not allowed.

Method 1There can be overflow only if signs of two numbers are same, and sign of sum is opposite to the signs of numbers.

1) Calculate sum2) If both numbers are positive and sum is negative then return -1 Else If both numbers are negative and sum is positive then return -1 Else return 0#include<stdio.h>

#include<stdlib.h>

/* Takes pointer to result and two numbers as

    arguments. If there is no overflow, the function

    places the resultant = sum a+b in “result” and

    returns 0, otherwise it returns -1 */

 int addOvf(int* result, int a, int b)

 {

     *result = a + b;

     if(a > 0 && b > 0 && *result < 0)

Page 89: Data structures all in one

         return -1;

     if(a < 0 && b < 0 && *result > 0)

         return -1;

     return 0;

 }

 int main()

 {

     int *res = (int *)malloc(sizeof(int));

     int x = 2147483640;

     int y = 10;

     printf("%d", addOvf(res, x, y));

     printf("\n %d", *res);

     getchar();

     return 0;

}

Time Complexity : O(1)Space Complexity: O(1)

Method 2Thanks to Himanshu Aggarwal for adding this method. This method doesn’t modify *result if there us an overflow.

#include<stdio.h>

#include<limits.h>

#include<stdlib.h>

Page 90: Data structures all in one

int addOvf(int* result, int a, int b)

{

   if( a > INT_MAX - b)

     return -1;

   else

   {

     *result = a + b;

      return 0;

   }

}

int main()

{

  int *res = (int *)malloc(sizeof(int));

  int x = 2147483640;

  int y = 10;

  printf("%d", addOvf(res, x, y));

  printf("\n %d", *res);

  getchar();

  return 0;

}

Time Complexity : O(1)Space Complexity: O(1)

What is the best way in C to convert a number to a string?June 29, 2009

Solution: Use sprintf() function.

#include<stdio.h>

Page 91: Data structures all in one

int main()

{

    char result[50];

    float num = 23.34;

    sprintf(result, "%f", num);

    printf("\n The string for the num is %s", result);

    getchar();

}

You can also write your own function using ASCII values of numbers.

How will you show memory representation of C variables?June 30, 2009

Write a C program to show memory representation of C variables like int, float, pointer, etc.

Algorithm:Get the address and size of the variable. Typecast the address to char pointer. Now loop for size of the variable and print the value at the typecasted pointer.

Program:

#include <stdio.h>typedef unsigned char *byte_pointer;

/*show bytes takes byte pointer as an argument and prints memory contents from byte_pointer to byte_pointer + len */void show_bytes(byte_pointer start, int len) { int i; for (i = 0; i < len; i++) printf(" %.2x", start[i]); printf("\n");

Page 92: Data structures all in one

}

void show_int(int x){ show_bytes((byte_pointer) &x, sizeof(int));}

void show_float(float x) { show_bytes((byte_pointer) &x, sizeof(float));}

void show_pointer(void *x) { show_bytes((byte_pointer) &x, sizeof(void *));}

/* Drover program to test above functions */int main(){ int i = 1; float f = 1.0; int *p = &i; show_float(f); show_int(i); show_pointer(p); show_int(i); getchar(); return 0;}Output of C Programs | Set 4July 3, 2009

Page 93: Data structures all in one

Predict the output of below programs

Question 1

#include‹stdio.h›

int main()

{

    struct site

    {

        char name[] = "GeeksforGeeks";

        int no_of_pages = 200;

    };

    struct site *ptr;

    printf("%d",ptr->no_of_pages);

    printf("%s",ptr->name);

    getchar();

    return 0;

}

Output:Compiler error

Explanation:Note the difference between structure/union declaration and variable declaration. When you declare a structure, you actually declare a new data type suitable for your purpose. So you cannot initialize values as it is not a variable declaration but a data type declaration.

Reference:http://www.lix.polytechnique.fr/~liberti/public/computing/prog/c/C/SYNTAX/struct.html

Question 2

int main()

Page 94: Data structures all in one

{

    char a[2][3][3] = {'g','e','e','k','s','f','o',

                           'r','g','e','e','k','s'};

    printf("%s ", **a);

    getchar();

    return 0;

}

Output:geeksforgeeks

Explanation:We have created a 3D array that should have 2*3*3 (= 18) elements, but we are initializing only 13 of them. In C when we initialize less no of elements in an array all uninitialized elements become ‘\0′ in case of char and 0 in case of integers.

Question 3

int main()

{

   char str[]= "geeks\nforgeeks";

   char *ptr1, *ptr2;

   ptr1 = &str[3];

   ptr2 = str + 5;

   printf("%c", ++*str - --*ptr1 + *ptr2 + 2);

   printf("%s", str);

   getchar();

   return 0;

}

Page 95: Data structures all in one

Output:heejsforgeeks

Explanation:Initially ptr1 points to ‘k’ and ptr2 points to ‘\n’ in “geeks\nforgeeks”. In print statement value at str is incremented by 1 and value at ptr1 is decremented by 1. So string becomes “heejs\nforgeeks” .

First print statement becomesprintf(“%c”, ‘h’ – ‘j’ + ‘n’ + 2)

‘h’ – ‘j’ + ‘\n’ + 2 = -2 + ‘\n’ + 2 = ‘\n’

First print statements newline character. and next print statement prints “heejs\nforgeeks”.

Question 4

#include <stdio.h>

int fun(int n)

{

    int i, j, sum = 0;

    for(i = 1;i<=n;i++)

        for(j=i;j<=i;j++)

            sum=sum+j;

    return(sum);

}

int main()

{

    printf("%d", fun(15));

    getchar();

    return 0;

}

Page 96: Data structures all in one

Output: 120Explanation: fun(n) calculates sum of first n integers or we can say it returns n(n+1)/2.

Question 5

#include <stdio.h>

int main()

{

    int c = 5, no = 1000;

    do {

        no /= c;

    } while(c--);

    printf ("%d\n", no);

    return 0;

}

Output: Exception – Divide by zero

Explanation: There is a bug in the above program. It goes inside the do-while loop for c = 0 also. Be careful when you are using do-while loop like this!!

Ugly NumbersJuly 11, 2009

Ugly numbers are numbers whose only prime factors are 2, 3 or 5. The sequence1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, …shows the first 11 ugly numbers. By convention, 1 is included.Write a program to find and print the 150′th ugly number.

METHOD 1 (Simple)Thanks to Nedylko Draganov for suggesting this solution.

Page 97: Data structures all in one

Algorithm:Loop for all positive integers until ugly number count is smaller than n, if an integer is ugly than increment ugly number count.

To check if a number is ugly, divide the number by greatest divisible powers of 2, 3 and 5, if the number becomes 1 then it is an ugly number otherwise not.

For example, let us see how to check for 300 is ugly or not. Greatest divisible power of 2 is 4, after dividing 300 by 4 we get 75. Greatest divisible power of 3 is 3, after dividing 75 by 3 we get 25. Greatest divisible power of 5 is 25, after dividing 25 by 25 we get 1. Since we get 1 finally, 300 is ugly number.

Implementation:

# include<stdio.h>

# include<stdlib.h>

/*This function divides a by greatest divisible

  power of b*/

int maxDivide(int a, int b)

{

  while (a%b == 0)

   a = a/b;

  return a;

}

/* Function to check if a number is ugly or not */

int isUgly(int no)

{

  no = maxDivide(no, 2);

  no = maxDivide(no, 3);

  no = maxDivide(no, 5);

Page 98: Data structures all in one

  return (no == 1)? 1 : 0;

}

/* Function to get the nth ugly number*/

int getNthUglyNo(int n)

{

  int i = 1;

  int count = 1;   /* ugly number count */

  /*Check for all integers untill ugly count

    becomes n*/

  while (n > count)

  {

    i++;

    if (isUgly(i))

      count++;

  }

  return i;

}

/* Driver program to test above functions */

int main()

{

    unsigned no = getNthUglyNo(150);

    printf("150th ugly no. is %d ",  no);

    getchar();

    return 0;

}

Page 99: Data structures all in one

This method is not time efficient as it checks for all integers until ugly number count becomes n, but space complexity of this method is O(1)

METHOD 2 (Use Dynamic Programming)

Here is a time efficient solution with O(n) extra space

Algorithm:

1 Declare an array for ugly numbers: ugly[150]2 Initialize first ugly no: ugly[0] = 13 Initialize three array index variables i2, i3, i5 to point to 1st element of the ugly array: i2 = i3 = i5 =0; 4 Initialize 3 choices for the next ugly no: next_mulitple_of_2 = ugly[i2]*2; next_mulitple_of_3 = ugly[i3]*3 next_mulitple_of_5 = ugly[i5]*5;5 Now go in a loop to fill all ugly numbers till 150:For (i = 1; i < 150; i++ ) { /* These small steps are not optimized for good readability. Will optimize them in C program */ next_ugly_no = Min(next_mulitple_of_2, next_mulitple_of_3, next_mulitple_of_5); if (next_ugly_no == next_mulitple_of_2) { i2 = i2 + 1; next_mulitple_of_2 = ugly[i2]*2; } if (next_ugly_no == next_mulitple_of_3)

Page 100: Data structures all in one

{ i3 = i3 + 1; next_mulitple_of_3 = ugly[i3]*3; } if (next_ugly_no == next_mulitple_of_5) { i5 = i5 + 1; next_mulitple_of_5 = ugly[i5]*5; } ugly[i] = next_ugly_no }/* end of for loop */ 6.return next_ugly_no

Example:Let us see how it works

initialize ugly[] = | 1 | i2 = i3 = i5 = 0;

First iteration ugly[1] = Min(ugly[i2]*2, ugly[i3]*3, ugly[i5]*5) = Min(2, 3, 5) = 2 ugly[] = | 1 | 2 | i2 = 1, i3 = i5 = 0 (i2 got incremented )

Second iteration ugly[2] = Min(ugly[i2]*2, ugly[i3]*3, ugly[i5]*5) = Min(4, 3, 5) = 3 ugly[] = | 1 | 2 | 3 | i2 = 1, i3 = 1, i5 = 0 (i3 got incremented )

Third iteration

Page 101: Data structures all in one

ugly[3] = Min(ugly[i2]*2, ugly[i3]*3, ugly[i5]*5) = Min(4, 6, 5) = 4 ugly[] = | 1 | 2 | 3 | 4 | i2 = 2, i3 = 1, i5 = 0 (i2 got incremented )

Fourth iteration ugly[4] = Min(ugly[i2]*2, ugly[i3]*3, ugly[i5]*5) = Min(6, 6, 5) = 5 ugly[] = | 1 | 2 | 3 | 4 | 5 | i2 = 2, i3 = 1, i5 = 1 (i5 got incremented )

Fifth iteration ugly[4] = Min(ugly[i2]*2, ugly[i3]*3, ugly[i5]*5) = Min(6, 6, 10) = 6 ugly[] = | 1 | 2 | 3 | 4 | 5 | 6 | i2 = 3, i3 = 2, i5 = 1 (i2 and i3 got incremented )

Will continue same way till I < 150

Program:

# include<stdio.h>

# include<stdlib.h>

# define bool int

/* Function to find minimum of 3 numbers */

unsigned min(unsigned , unsigned , unsigned );

Page 102: Data structures all in one

/* Function to get the nth ugly number*/

unsigned getNthUglyNo(unsigned n)

{

    unsigned *ugly =

             (unsigned *)(malloc (sizeof(unsigned)*n));

    unsigned i2 = 0, i3 = 0, i5 = 0;

    unsigned i;

    unsigned next_multiple_of_2 = 2;

    unsigned next_multiple_of_3 = 3;

    unsigned next_multiple_of_5 = 5;

    unsigned next_ugly_no = 1;

    *(ugly+0) = 1;

    for(i=1; i<n; i++)

    {

       next_ugly_no = min(next_multiple_of_2,

                           next_multiple_of_3,

                           next_multiple_of_5);

       *(ugly+i) = next_ugly_no;

       if(next_ugly_no == next_multiple_of_2)

       {

           i2 = i2+1;

           next_multiple_of_2 = *(ugly+i2)*2;

       }

       if(next_ugly_no == next_multiple_of_3)

       {

           i3 = i3+1;

           next_multiple_of_3 = *(ugly+i3)*3;

       }

Page 103: Data structures all in one

       if(next_ugly_no == next_multiple_of_5)

       {

           i5 = i5+1;

           next_multiple_of_5 = *(ugly+i5)*5;

       }

    } /*End of for loop (i=1; i<n; i++) */

    return next_ugly_no;

}

/* Function to find minimum of 3 numbers */

unsigned min(unsigned a, unsigned b, unsigned c)

{

    if(a <= b)

    {

      if(a <= c)

        return a;

      else

        return c;

    }

    if(b <= c)

      return b;

    else

      return c;

}

/* Driver program to test above functions */

int main()

{

    unsigned no = getNthUglyNo(150);

Page 104: Data structures all in one

    printf("%dth ugly no. is %d ", 150, no);

    getchar();

    return 0;

}

Algorithmic Paradigm: Dynamic ProgrammingTime Complexity: O(n)Storage Complexity: O(n)

Little and Big Endian MysteryJuly 16, 2009

What are these?Little and big endian are two ways of storing multibyte data-types ( int, float, etc). In little endian machines, last byte of binary representation of the multibyte data-type is stored first. On the other hand, in big endian machines, first byte of binary representation of the multibyte data-type is stored first.

Suppose integer is stored as 4 bytes (For those who are using DOS based compilers such as C++ 3.0 , integer is 2 bytes) then a variable x with value 0×01234567 will be stored as following.

Memory representation of integer ox01234567 inside Big and little endian machines

How to see memory representation of multibyte data types on your machine?

Page 105: Data structures all in one

Here is a sample C code that shows the byte representation of int, float and pointer.

#include <stdio.h>

/* function to show bytes in memory, from location start to start+n*/

void show_mem_rep(char *start, int n)

{

    int i;

    for (i = 0; i < n; i++)

         printf(" %.2x", start[i]);

    printf("\n");

}

/*Main function to call above function for 0x01234567*/

int main()

{

   int i = 0x01234567;

   show_mem_rep((char *)&i, sizeof(i));

   getchar();

   return 0;

}

When above program is run on little endian machine, gives “67 45 23 01″ as output , while if it is run on endian machine, gives “01 23 45 67″ as output.

Is there a quick way to determine endianness of your machine?There are n no. of ways for determining endianness of your machine. Here is one quick way of doing the same.

#include <stdio.h>

int main()

Page 106: Data structures all in one

{

   unsigned int i = 1;

   char *c = (char*)&i;

   if (*c)

       printf("Little endian");

   else

       printf("Big endian");

   getchar();

   return 0;

}

In the above program, a character pointer c is pointing to an integer i. Since size of character is 1 byte when the character pointer is de-referenced it will contain only first byte of integer. If machine is little endian then *c will be 1 (because last byte is stored first) and if machine is big endian then *c will be 0.

Does endianness matter for programmers?Most of the times compiler takes care of endianness, however, endianness becomes an issue in following cases.

It matters in network programming: Suppose you write integers to file on a little endian machine and you transfer this file to a big endian machine. Unless there is little andian to big endian transformation, big endian machine will read the file in reverse order. You can find such a practical example here.

Standard byte order for networks is big endian, also known as network byte order. Before transferring data on network, data is first converted to network byte order (big endian).

Sometimes it matters when you are using type casting, below program is an example.

#include <stdio.h>

int main()

Page 107: Data structures all in one

{

    unsigned char arr[2] = {0x01, 0x00};

    unsigned short int x = *(unsigned short int *) arr;

    printf("%d", x);

    getchar();

    return 0;

}

In the above program, a char array is typecasted to an unsigned short integer type. When I run above program on little endian machine, I get 1 as output, while if I run it on a big endian machine I get 256. To make programs endianness independent, above programming style should be avoided.

What are bi-endians?Bi-endian processors can run in both modes little and big endian.

What are the examples of little, big endian and bi-endian machines ?Intel based processors are little endians. ARM processors were little endians. Current generation ARM processors are bi-endian.

Motorola 68K processors are big endians. PowerPC (by Motorola) and SPARK (by Sun) processors were big endian. Current version of these processors are bi-endians.

Does endianness effects file formats?File formats which have 1 byte as a basic unit are independent of endianness e..g., ASCII files . Other file formats use some fixed endianness forrmat e.g, JPEG files are stored in big endian format.

Which one is better — little endian or big endianThe term little and big endian came from Gulliver’s Travels by Jonathan Swift. Two groups could not agree by which end a egg should be opened -a-the little or the big. Just like the egg issue, there is no technological reason to choose one byte ordering convention

Page 108: Data structures all in one

over the other, hence the arguments degenerate into bickering about sociopolitical issues. As long as one of the conventions is selected and adhered to consistently, the choice is arbitrary.

Write a C function to print the middle of a given linked listJuly 16, 2009

Method 1:Traverse the whole linked list and count the no. of nodes. Now traverse the list again till count/2 and return the node at count/2.

Method 2:Traverse linked list using two pointers. Move one pointer by one and other pointer by two. When the fast pointer reaches end slow pointer will reach middle of the linked list.

#include<stdio.h>

#include<stdlib.h>

/* Link list node */

struct node

{

    int data;

    struct node* next;

};

/* Function to get the middle of the linked list*/

void printMiddle(struct node *head)

{

  struct node *slow_ptr = head;

  struct node *fast_ptr = head;

  if(head!=NULL)

Page 109: Data structures all in one

  {

       while((fast_ptr->next)!=NULL &&

               (fast_ptr->next->next)!=NULL)

       {

          fast_ptr = fast_ptr->next->next;

          slow_ptr = slow_ptr->next;

       }

       printf("The middle element is [%d]",slow_ptr->data);

  }

}

void push(struct node** head_ref, int new_data)

{

    /* allocate node */

    struct node* new_node =

            (struct node*) malloc(sizeof(struct node));

    /* put in the data  */

    new_node->data  = new_data;

    /* link the old list off the new node */

    new_node->next = (*head_ref);

    /* move the head to point to the new node */

    (*head_ref)    = new_node;

}

/* Drier program to test above function*/

int main()

Page 110: Data structures all in one

{

    /* Start with the empty list */

    struct node* head = NULL;

     push(&head, 20);

     push(&head, 4);

     push(&head, 15);

     printMiddle(head);

     return 0;

}

Method 3:Initialize mid element as head and initialize a counter as 0. Traverse the list from head, while traversing increment the counter and change mid to mid->next whenever the counter is odd. So the mid will move only half of the total length of the list.Thanks to Narendra Kangralkar for suggesting this method.

#include<stdio.h>

#include<stdlib.h>

/* Link list node */

struct node

{

    int data;

    struct node* next;

};

/* Function to get the middle of the linked list*/

void printMiddle(struct node *head)

Page 111: Data structures all in one

{

    int count = 0;

    struct node *mid = head;

    while (head != NULL)

    {

        /* update mid, when 'count' is odd number */

        if (count & 1)

            mid = mid->next;

        ++count;

        head = head->next;

    }

    /* if empty list is provided */

    if (mid != NULL)

        printf("\tThe middle element is %d\n\n", mid->data);

}

void push(struct node** head_ref, int new_data)

{

    /* allocate node */

    struct node* new_node =

        (struct node*) malloc(sizeof(struct node));

    /* put in the data  */

    new_node->data  = new_data;

Page 112: Data structures all in one

    /* link the old list off the new node */

    new_node->next = (*head_ref);

    /* move the head to point to the new node */

    (*head_ref)    = new_node;

}

/* Drier program to test above function*/

int main()

{

    /* Start with the empty list */

    struct node* head = NULL;

    push(&head, 20);

    push(&head, 4);

    push(&head, 30);

    printMiddle(head);

    return 0;

}

Nth node from the end of a Linked ListJuly 17, 2009

Given a Linked List and a number n, write a function that returns the value at the nth node from end of the Linked List.

Method 1 (Use length of linked list)1) Calculate the length of Linked List. Let the length be len.2) Print the (len – n + 1)th node from the begining of the Linked List.

#include<stdio.h>

#include<stdlib.h>

Page 113: Data structures all in one

/* Link list node */

struct node

{

  int data;

  struct node* next;

};

/* Function to get the nth node from the last of a linked list*/

void printNthFromLast(struct node* head, int n)

{

    int len = 0, i;

    struct node *temp = head;

    // 1) count the number of nodes in Linked List

    while (temp != NULL)

    {

        temp = temp->next;

        len++;

    }

    // check if value of n is not more than length of the linked list

    if (len < n)

      return;

    temp = head;

    // 2) get the (n-len+1)th node from the begining

    for (i = 1; i < len-n+1; i++)

Page 114: Data structures all in one

       temp = temp->next;

    printf ("%d", temp->data);

    return;

}

void push(struct node** head_ref, int new_data)

{

  /* allocate node */

  struct node* new_node =

          (struct node*) malloc(sizeof(struct node));

  /* put in the data  */

  new_node->data  = new_data;

  /* link the old list off the new node */

  new_node->next = (*head_ref);

  /* move the head to point to the new node */

  (*head_ref)    = new_node;

}

/* Drier program to test above function*/

int main()

{

  /* Start with the empty list */

  struct node* head = NULL;

Page 115: Data structures all in one

  // create linked 35->15->4->20

  push(&head, 20);

  push(&head, 4);

  push(&head, 15);

  push(&head, 35);

  printNthFromLast(head, 5);

  getchar();

  return 0;

}

Following is a recursive C code for the same method. Thanks to Anuj Bansal for providing following code.

void printNthFromLast(struct node* head, int n)

{

    static int i = 0;

    if(head == NULL)

       return;

    printNthFromLast(head->next, n);

    if(++i == n)

       printf("%d", head->data);

}

Time Complexity: O(n) where n is the length of linked list.

Method 2 (Use two pointers) Maintain two pointers – reference pointer and main pointer. Initialize both reference and main pointers to head. First move reference pointer to n nodes from head. Now move both pointers one by one until reference pointer reaches end. Now main pointer will point to nth node from the end. Return main pointer.

Page 116: Data structures all in one

Implementation:

#include<stdio.h>

#include<stdlib.h>

/* Link list node */

struct node

{

  int data;

  struct node* next;

};

/* Function to get the nth node from the last of a linked list*/

void printNthFromLast(struct node *head, int n)

{

  struct node *main_ptr = head;

  struct node *ref_ptr = head;

  int count = 0;

  if(head != NULL)

  {

     while( count < n )

     {

        if(ref_ptr == NULL)

        {

           printf("%d is greater than the no. of "

                    "nodes in list", n);

           return;

        }

        ref_ptr = ref_ptr->next;

Page 117: Data structures all in one

        count++;

     } /* End of while*/

     while(ref_ptr != NULL)

     {

        main_ptr = main_ptr->next;

        ref_ptr  = ref_ptr->next;

     }

     printf("Node no. %d from last is %d ",

              n, main_ptr->data);

  }

}

void push(struct node** head_ref, int new_data)

{

  /* allocate node */

  struct node* new_node =

          (struct node*) malloc(sizeof(struct node));

  /* put in the data  */

  new_node->data  = new_data;

  /* link the old list off the new node */

  new_node->next = (*head_ref);

  /* move the head to point to the new node */

  (*head_ref)    = new_node;

}

Page 118: Data structures all in one

/* Drier program to test above function*/

int main()

{

  /* Start with the empty list */

  struct node* head = NULL;

  push(&head, 20);

  push(&head, 4);

  push(&head, 15);

  printNthFromLast(head, 3);

  getchar();

}

Time Complexity: O(n) where n is the length of linked list.

Write a function to delete a Linked ListJuly 18, 2009

Algorithm: Iterate through the linked list and delete all the nodes one by one. Main point here is not to access next of the current pointer if current pointer is deleted.

Implementation:

#include<stdio.h>

#include<stdlib.h>

#include<assert.h>

/* Link list node */

struct node

{

    int data;

    struct node* next;

Page 119: Data structures all in one

};

/* Function to delete the entire linked list */

void deleteList(struct node** head_ref)

{

   /* deref head_ref to get the real head */

   struct node* current = *head_ref;

   struct node* next;

   while (current != NULL)

   {

       next = current->next;

       free(current);

       current = next;

   }

   /* deref head_ref to affect the real head back

      in the caller. */

   *head_ref = NULL;

}

/* Given a reference (pointer to pointer) to the head

  of a list and an int, push a new node on the front

  of the list. */

void push(struct node** head_ref, int new_data)

{

    /* allocate node */

    struct node* new_node =

            (struct node*) malloc(sizeof(struct node));

Page 120: Data structures all in one

    /* put in the data  */

    new_node->data  = new_data;

    /* link the old list off the new node */

    new_node->next = (*head_ref);

    /* move the head to point to the new node */

    (*head_ref)    = new_node;

}

/* Drier program to test count function*/

int main()

{

    /* Start with the empty list */

    struct node* head = NULL;

    /* Use push() to construct below list

     1->12->1->4->1  */

    push(&head, 1);

    push(&head, 4);

    push(&head, 1);

    push(&head, 12);

    push(&head, 1);

    printf("\n Deleting linked list");

    deleteList(&head);

    printf("\n Linked list deleted");

Page 121: Data structures all in one

    getchar();

}

Time Complexity: O(n)Space Complexity: O(1)

Write a function to delete a Linked ListJuly 18, 2009

Algorithm: Iterate through the linked list and delete all the nodes one by one. Main point here is not to access next of the current pointer if current pointer is deleted.

Implementation:

#include<stdio.h>

#include<stdlib.h>

#include<assert.h>

/* Link list node */

struct node

{

    int data;

    struct node* next;

};

/* Function to delete the entire linked list */

void deleteList(struct node** head_ref)

{

   /* deref head_ref to get the real head */

   struct node* current = *head_ref;

   struct node* next;

Page 122: Data structures all in one

   while (current != NULL)

   {

       next = current->next;

       free(current);

       current = next;

   }

   /* deref head_ref to affect the real head back

      in the caller. */

   *head_ref = NULL;

}

/* Given a reference (pointer to pointer) to the head

  of a list and an int, push a new node on the front

  of the list. */

void push(struct node** head_ref, int new_data)

{

    /* allocate node */

    struct node* new_node =

            (struct node*) malloc(sizeof(struct node));

    /* put in the data  */

    new_node->data  = new_data;

    /* link the old list off the new node */

    new_node->next = (*head_ref);

    /* move the head to point to the new node */

    (*head_ref)    = new_node;

Page 123: Data structures all in one

}

/* Drier program to test count function*/

int main()

{

    /* Start with the empty list */

    struct node* head = NULL;

    /* Use push() to construct below list

     1->12->1->4->1  */

    push(&head, 1);

    push(&head, 4);

    push(&head, 1);

    push(&head, 12);

    push(&head, 1);

    printf("\n Deleting linked list");

    deleteList(&head);

    printf("\n Linked list deleted");

    getchar();

}

Time Complexity: O(n)Space Complexity: O(1)

Write a function that counts the number of times a given int occurs in a Linked ListJuly 19, 2009

Here is a solution.

Page 124: Data structures all in one

Algorithm:

1. Initialize count as zero.2. Loop through each element of linked list: a) If element data is equal to the passed number then increment the count.3. Return count.

Implementation:

#include<stdio.h>

#include<stdlib.h>

/* Link list node */

struct node

{

    int data;

    struct node* next;

};

/* Given a reference (pointer to pointer) to the head

  of a list and an int, push a new node on the front

  of the list. */

void push(struct node** head_ref, int new_data)

{

    /* allocate node */

    struct node* new_node =

            (struct node*) malloc(sizeof(struct node));

    /* put in the data  */

    new_node->data  = new_data;

Page 125: Data structures all in one

    /* link the old list off the new node */

    new_node->next = (*head_ref);

    /* move the head to point to the new node */

    (*head_ref)    = new_node;

}

/* Counts the no. of occurences of a node

   (search_for) in a linked list (head)*/

int count(struct node* head, int search_for)

{

    struct node* current = head;

    int count = 0;

    while (current != NULL)

    {

        if (current->data == search_for)

           count++;

        current = current->next;

    }

    return count;

}

/* Drier program to test count function*/

int main()

{

    /* Start with the empty list */

    struct node* head = NULL;

Page 126: Data structures all in one

    /* Use push() to construct below list

     1->2->1->3->1  */

    push(&head, 1);

    push(&head, 3);

    push(&head, 1);

    push(&head, 2);

    push(&head, 1);

    /* Check the count function */

    printf("count of 1 is %d", count(head, 1));

    getchar();

}

Time Complexity: O(n)Auxiliary Space: O(1)

Understanding “extern” keyword in CJuly 19, 2009

I’m sure that this post will be as interesting and informative to C virgins (i.e. beginners) as it will be to those who are well versed in C. So let me start with saying that extern keyword applies to C variables (data objects) and C functions. Basically extern keyword extends the visibility of the C variables and C functions. Probably that’s is the reason why it was named as extern.

Though (almost) everyone knows the meaning of declaration and definition of a variable/function yet for the sake of completeness of this post, I would like to clarify them. Declaration of a variable/function simply declares that the variable/function exists somewhere in the program but the memory is not allocated for them. But the declaration of a variable/function serves an important role. And that is the type of the variable/function. Therefore, when a variable is declared, the program knows the data type of that variable. In case of function declaration, the program knows what are the arguments to that functions, their data types, the order of arguments and the return type

Page 127: Data structures all in one

of the function. So that’s all about declaration. Coming to the definition, when we define a variable/function, apart from the role of declaration, it also allocates memory for that variable/function. Therefore, we can think of definition as a super set of declaration. (or declaration as a subset of definition). From this explanation, it should be obvious that a variable/function can be declared any number of times but it can be defined only once. (Remember the basic principle that you can’t have two locations of the same variable/function). So that’s all about declaration and definition.

Now coming back to our main objective: Understanding “extern” keyword in C. I’ve explained the role of declaration/definition because it’s mandatory to understand them to understand the “extern” keyword. Let us first take the easy case. Use of extern with C functions. By default, the declaration and definition of a C function have “extern” prepended with them. It means even though we don’t use extern with the declaration/definition of C functions, it is present there. For example, when we write.

int foo(int arg1, char arg2);

There’s an extern present in the beginning which is hidden and the compiler treats it as below.

extern int foo(int arg1, char arg2);

Same is the case with the definition of a C function (Definition of a C function means writing the body of the function). Therefore whenever we define a C function, an extern is present there in the beginning of the function definition. Since the declaration can be done any number of times and definition can be done only once, we can notice that declaration of a function can be added in several C/H files or in a single C/H file several times. But we notice the actual definition of the function only once (i.e. in one file only). And as the extern extends the visibility to the whole program, the functions can be used (called) anywhere in any of the files of the whole program provided the declaration of the function is known. (By knowing the declaration of the function, C compiler knows that the definition of the function exists

Page 128: Data structures all in one

and it goes ahead to compile the program). So that’s all about extern with C functions.

Now let us the take the second and final case i.e. use of extern with C variables. I feel that it more interesting and information than the previous case where extern is present by default with C functions. So let me ask the question, how would you declare a C variable without defining it? Many of you would see it trivial but it’s important question to understand extern with C variables. The answer goes as follows.

extern int var;

Here, an integer type variable called var has been declared (remember no definition i.e. no memory allocation for var so far). And we can do this declaration as many times as needed. (remember that declaration can be done any number of times) So far so good. 

Now how would you define a variable. Now I agree that it is the most trivial question in programming and the answer is as follows.

int var;

Here, an integer type variable called var has been declared as well as defined. (remember that definition is the super set of declaration). Here the memory for var is also allocated. Now here comes the surprise, when we declared/defined a C function, we saw that an extern was present by default. While defining a function, we can prepend it with extern without any issues. But it is not the case with C variables. If we put the presence of extern in variable as default then the memory for them will not be allocated ever, they will be declared only. Therefore, we put extern explicitly for C variables when we want to declare them without defining them. Also, as the extern extends the visibility to the whole program, by externing a variable we can use the variables anywhere in the program provided we know the declaration of them and the variable is defined somewhere.

Now let us try to understand extern with examples.

Example 1:

int var;

Page 129: Data structures all in one

int main(void)

{

   var = 10;

   return 0;

}

Analysis: This program is compiled successfully. Here var is defined (and declared implicitly) globally.

Example 2:

extern int var;

int main(void)

{

  return 0;

}

Analysis: This program is compiled successfully. Here var is declared only. Notice var is never used so no problems.

Example 3:

extern int var;

int main(void)

{

 var = 10;

 return 0;

}

Analysis: This program throws error in compilation. Because var is declared but not defined anywhere. Essentially, the var isn’t allocated any memory. And the program is trying to change the value to 10 of a variable that doesn’t exist at all.

Page 130: Data structures all in one

Example 4:

#include "somefile.h"

extern int var;

int main(void)

{

 var = 10;

 return 0;

}

Analysis: Supposing that somefile.h has the definition of var. This program will be compiled successfully.

Example 5:

extern int var = 0;

int main(void)

{

 var = 10;

 return 0;

}

Analysis: Guess this program will work? Well, here comes another surprise from C standards. They say that..if a variable is only declared and an initializer is also provided with that declaration, then the memory for that variable will be allocated i.e. that variable will be considered as defined. Therefore, as per the C standard, this program will compile successfully and work.

So that was a preliminary look at “extern” keyword in C.

I’m sure that you want to have some take away from the reading of this post. And I would not disappoint you. In short, we can say

Page 131: Data structures all in one

1. Declaration can be done any number of times but definition only once.2. “extern” keyword is used to extend the visibility of variables/functions().3. Since functions are visible through out the program by default. The use of extern is not needed in function declaration/definition. Its use is redundant.4. When extern is used with a variable, it’s only declared not defined.5. As an exception, when an extern variable is declared with initialization, it is taken as definition of the variable as well.

Output of C Programs | Set 5July 30, 2009

Predict the output of below programs

Question 1

int main()

{

    while(1){

        if(printf("%d",printf("%d")))

            break;

        else

            continue;

    }

    return 0;

}

Output:Can’t be predicted

Explanation:The condition in while loop is 1 so at first shot it looks infinite loop. Then there are break and continue in the body of the while loop, so it may not be infinite loop. The break statement will be executed if the condition under if is met, otherwise continue will be executed. Since

Page 132: Data structures all in one

there’s no other statements after continue in the while loop, continue doesn’t serve any purpose. In fact it is extraneous. So let us see the if condition. If we look carefully, we will notice that the condition of the if will be met always, so break will be executed at the first iteration itself and we will come out of while loop. The reason why the condition of if will be met is printf function. Function printf always returns the no. of bytes it has output. For example, the return value of printf(“geeks”) will be 5 because printf will output 5 characters here. In our case, the inner printf will be executed first but this printf doesn’t have argument for format specifier i.e. %d. It means this printf will print any arbitrary value. But notice that even for any arbirary value, the no. of bytes output by inner printf would be non-zero. And those no. of bytes will work as argument to outer printf. The outer printf will print that many no. of bytes and return non-zero value always. So the condition for if is also true always. Therefore, the while loop be executed only once. As a side note, even without outer printf also, the condition for if is always true.

Question 2

int main()

{

    unsigned int i=10;

    while(i-- >= 0)

        printf("%u ",i);

    return 0;

}

Output:9 8 7 6 5 4 3 2 1 0 4294967295 4294967294 …… (on a machine where int is 4 bytes long)

9 8 7 6 5 4 3 2 1 0 65535 65534 …. (on a machine where int is 2 bytes long)

Explanation:Let us examine the condition of while loop. It is obvious that as far as

Page 133: Data structures all in one

the condition of while loop is met, printf will be executed. There are two operators in the condition of while loop: post-decrement operator and comparison operator. From operator precedence, we know that unary operator post-decrement has higher priority than comparison operator. But due to post-decrement property, the value of i will be decremented only after it had been used for comparison. So at the first iteration, the condition is true because 10>=0 and then i is decremented. Therefore 9 will be printed. Similarly the loop continues and the value of i keeps on decrementing. Let us see what what happen when condition of while loop becomes 0 >= 0. At this time, condition is met and i is decremented. Since i is unsigned integer, the roll-over happens and i takes the value of the highest +ve value an unsigned int can take. So i is never negative. Therefore, it becomes infinite while loop.

As a side note, if i was signed int, the while loop would have been terminated after printing the highest negative value.

Question 3

int main()

{

    int x,y=2,z,a;

    if ( x = y%2)

         z =2;

    a=2;

    printf("%d %d ",z,x);

    return 0;

}

Output:0

Explanation:This question has some stuff for operator precedence. If the condition of if is met, then z will be initialized to 2 otherwise z will contain garbage value. But the condition of if has two operators: assignment

Page 134: Data structures all in one

operator and modulus operator. The precedence of modulus is higher than assignment. So y%2 is zero and it’ll be assigned to x. So the value of x becomes zero which is also the effective condition for if. And therefore, condition of if is false.

Question 4

int main()

{

    int a[10];

    printf("%d",*a+1-*a+3);

    return 0;

}

Output: 4

Explanation:From operator precedence, de-reference operator has higher priority than addition/subtraction operator. So de-reference will be applied first. Here, a is an array which is not initialized. If we use a, then it will point to the first element of the array. Therefore *a will be the first element of the array. Suppose first element of array is x, then the argument inside printf becomes as follows. It’s effective value is 4.

x + 1 – x + 3 = 4

Question 5

#define prod(a,b) a*b

int main()

{

    int x=3,y=4;

    printf("%d",prod(x+2,y-1));

    return 0;

}

Page 135: Data structures all in one

Output:10

Explanation:This program deals with macros, their side effects and operator precedence. Here prod is a macro which multiplies its two arguments a and b. Let us take a closer look.

prod(a, b) = a*bprod(x+2, y-1) = x+2*y-1 = 3+2*4-1 = 3+8-1=10

If the programmer really wanted to multiply x+2 and y-1, he should have put parenthesis around a and b as follows.

prod(a,b) = (a)*(b)

This type of mistake in macro definition is called – macro side-effects.

Output of C Programs | Set 6July 30, 2009

Predict the output of below programs

Question 1

int main()

{

    unsigned int i=65000;

    while ( i++ != 0 );

    printf("%d",i);

    return 0;

}

Output:1

Explanation:It should be noticed that there’s a semi-colon in the body of while loop. So even though, nothing is done as part of while body, the

Page 136: Data structures all in one

control will come out of while only if while condition isn’t met. In other words, as soon as i inside the condition becomes 0, the condition will become false and while loop would be over. But also notice the post-increment operator in the condition of while. So first i will be compared with 0 and i will be incremented no matter whether condition is met or not. Since i is initialized to 65000, it will keep on incrementing till it reaches highest positive value. After that roll over happens, and the value of i becomes zero. The condition is not met, but i would be incremented i.e. to 1. Then printf will print 1.

Question 2

int main()

{

    int i=0;

    while ( +(+i--) != 0)

        i-=i++;

    printf("%d",i);

    return 0;

}

Output:-1

Explanation:Let us first take the condition of while loop. There are several operator there. Unary + operator doesn’t do anything. So the simplified condition becomes (i–) != 0. So i will be compared with 0 and then decremented no matter whether condition is true or false. Since i is initialized to 0, the condition of while will be false at the first iteration itself but i will be decremented to -1. The body of while loop will not be executed. And printf will print -1.

So it wasn’t that scary as it seemed to be!

Question 3

int main()

Page 137: Data structures all in one

{

    float f=5,g=10;

    enum{i=10,j=20,k=50};

    printf("%d\n",++k);

    printf("%f\n",f<<2);

    printf("%lf\n",f%g);

    printf("%lf\n",fmod(f,g));

    return 0;

}

Output:Program will not compile and give 3 errors

Explanation:Here, i, j and k are inside the enum and therefore, they are like constants. In other words, if want to us 10 anywhere in the program , we can use i instead. In the first printf, the value of i is being modified which is not allowed because it’s enum constant. In the second printf, left-shift operator is being applied on a float which is also not allowed. Similarly, in the third printf, modulus operator is being applied on float f and g which is also not allowed.

Question 4

int main()

{

    int i=10;

    void pascal f(int,int,int);

    f(i++, i++, i++);

    printf(" %d",i);

    return 0;

}

void pascal f(integer :i,integer:j,integer :k)

Page 138: Data structures all in one

{

  write(i,j,k);

}

Output:Program will give compile-time error

Explanation:Compiler specific question. Not all compilers support this.

Otherwise, pascal enforces left to right processing of arguments. So even though, the argument processing order can be changed by the use of pascal, we can’t use Pascal language routines such as write inside C program.

Question 5

void pascal f(int i,int j,int k)

{

  printf("%d %d %d",i, j, k);

}

void cdecl f(int i,int j,int k)

{

  printf("%d %d %d",i, j, k);

}

main()

{

    int i=10;

    f(i++,i++,i++);

    printf(" %d\n",i);

    i=10;

Page 139: Data structures all in one

    f(i++,i++,i++);

    printf(" %d",i);

}

Output:Compiler specific question. Not all the compilers allow this.

Explanation:This question deals with the argument passing mechanism. If we call a function, the order in which the arguments of the function are processed is not governed by C Standard. So one compiler can process the arguments from left to right while the other compiler can process them right to left. Usually, the programs are not affected with this because the arguments of the programs are different. For example if we call funtion fun as fun(i,j), then no matter in which order the arguments are processed, the value of i and j will be consistent.

But in this case, we are passing the arguments to function f using the same variable. So the order in which arguments are processed by the function will determine the value of those arguments. cdecl enforces right to left processing of arguments while pascal enforces left to right processing of arguments.

So the value of i, j and k inside the first function f will be 10, 11 and 12 respectively while the value of i, j and k inside the second function f will be 12, 11 and 10 respectively.

Given only a pointer to a node to be deleted in a singly linked list, how do you delete it?August 2, 2009

A simple solution is to traverse the linked list until you find the node you want to delete. But this solution requires pointer to the head node which contradicts the problem statement.

Fast solution is to copy the data from the next node to the node to be deleted and delete the next node. Something like following.

Page 140: Data structures all in one

struct node *temp = node_ptr->next; node_ptr->data = temp->data; node_ptr->next = temp->next; free(temp);

Program:

#include<stdio.h>

#include<assert.h>

#include<stdlib.h>

/* Link list node */

struct node

{

    int data;

    struct node* next;

};

/* Given a reference (pointer to pointer) to the head

of a list and an int, push a new node on the front

of the list. */

void push(struct node** head_ref, int new_data)

{

    /* allocate node */

   struct node* new_node =

             (struct node*) malloc(sizeof(struct node));

   /* put in the data  */

   new_node->data  = new_data;

   /* link the old list off the new node */

Page 141: Data structures all in one

   new_node->next = (*head_ref);

   /* move the head to point to the new node */

   (*head_ref)    = new_node;

}

void printList(struct node *head)

{

   struct node *temp = head;

   while(temp != NULL)

   {

      printf("%d  ", temp->data);

      temp = temp->next;

   }

}

void deleteNode(struct node *node_ptr)

{

   struct node *temp = node_ptr->next;

   node_ptr->data    = temp->data;

   node_ptr->next    = temp->next;

   free(temp);

}

/* Drier program to test above function*/

int main()

{

    /* Start with the empty list */

    struct node* head = NULL;

Page 142: Data structures all in one

    /* Use push() to construct below list

    1->12->1->4->1  */

    push(&head, 1);

    push(&head, 4);

    push(&head, 1);

    push(&head, 12);

    push(&head, 1);

    printf("\n Before deleting \n");

    printList(head);

    /* I m deleting the head itself.

        You can check for more cases */

   deleteNode(head);

   printf("\n After deleting \n");

   printList(head);

   getchar();

}

This solution doesn’t work if the node to be deleted is the last node of the list. To make this solution work we can mark the end node as a dummy node. But the programs/functions that are using this function should also be modified.

Try this problem for doubly linked list.

Let’s experiment with NetworkingAugust 2, 2009

Most of us have studied Computer Networks in a very abstract manner. In other words, not many of us know how the abstract

Page 143: Data structures all in one

concepts of layers and packets translate in real life networks such as the Internet. Therefore let us do an experiment and see whether these layers, packets etc. exist in any real network also. So get, set and ready to delve into this wonderful world of practical and experimental Networking!

The outline of our experiment is as follows. We will capture some live packets, and to understand what is inside those packets, we will analyze those packets by dissecting them. Sounds surgical? Yup, it is. J

To start with, we need to have a PC running Windows XP and connected to the Internet. If you are reading this article online, the chances are high that you have everything ready to experiment. Now let’s recall some of the theory stuff that we read in Networking Books. The first thing that almost every book tells us – networking architecture is layered; remember that 7 layer OSI protocol stack! So where are these protocol layers? In our experiment, we will use 5 layer Internet Protocol stack so that we can solve the mystery of these layers.

We start our experiment by installing Wireshark (earlier known as Ethereal). Wireshark is a Network Protocol Analyzer that can capture and analyze the packets transmitted/received via a Network Interface Card (NIC). [You need to bear with me this acronym because Networking is full of acronymsJ] We install Wireshark from http://www.wireshark.org/download.html (at the time of this writing, the latest Wireshark version is 1.0.3). While installing Wireshark, leave the default settings/options as it is. Now our experimental setup is ready. Run Wireshark and click on the first icon (List the available capture interfaces …). Now we see a pop up window that shows Capture Interfaces. See the snapshots as follows.

Page 144: Data structures all in one

The number and types of interfaces shown in Capture Interfaces window can be different for you depending on your PC’s configuration. For me it shows two interfaces and my Internet connection is through Broadcom Gigabit Interface. So choose the interface through which your Internet connection is available to you. Now let’s click on the Options button of this interface. Now we see a new window named Capture Options. In this window, type “port 80” in text field named Capture Filter. See the following snapshot for clarification.

Now we are ready to capture the packets passing through our NIC. By setting the filter to “port 80”, we have instructed Wireshark to capture only those packets that are because of http traffic (remember that we were always told that the default http port is 80!). Now click on the

Page 145: Data structures all in one

Start button on Capture Options window. You may see some packets in Wireshark if any program in your PC is accessing http traffic in the background; let’s not focus on that. Now open your browser and try to access http://google.comand now you should be seeing lot many packets getting captured in Wireshark. See the snapshot as follows.

Let’s start analyzing the captured packets. First of all, find the first instance of http packet that has   GET / HTTP/1.1 in its Info field. In the above snapshot, it’s shown in blue. If we take a closer look, we see that this packet has the headers of the all the 5 layers of the Internet Protocol stack.

Layer 1 – It is the Physical layer. Here Frames are shown at the physical layer.

Layer 2 – It is the Data Link layer. In this packet, we can see that Ethernet II is used as data link layer protocol. We can find the MAC address of the source and destination in this header.

Layer 3 – It is the Network layer. In this packet, we see that IP is used as Network layer protocol. We can see the source and destination IP in this header.

Layer 4 – It is the Transport layer. In this packet, TCP is used as Transport layer protocol. We can find the source and destination ports in this header.

Page 146: Data structures all in one

Layer 5 – It is the Application layer. In this packet, HTTP is used as Application layer protocol.

Let’s explore one of the layers. Other layers can be explored further in the similar fashion. If we expand the Layer 5 i.e. HTTP header, it looks as follows.

Here we see that Host is mentioned as google.com that is what we tried to access from browser. User Agent field of the HTTP header shows the browser details. In my case, it is Mozilla Firefox as evidenced from this header. Destination IP 64.233.187.99 should be one of the IP addresses assigned to Google server where the web server is hosted. It can be verified using a very handy utility command “nslookup”. The details of the other fields can be explored in the headers of the HTTP, TCP, IP, Ethernet II protocols. Some of the interesting fields are – Differentiated Services Field (also known as QoS field) in IP header, Window size in TCP header etc.

So we have seen that all those rhetorical concepts of layers etc. do exist in real networks also. And it sounds interesting when you dissect all the packets that pass through your interface card. By doing so, you can get to know what goes/comes through your PC!

The idea of this experiment is to provide a conducive platform so that you can explore your own the exciting world of Networking.  So welcome aboard!

Page 147: Data structures all in one

Write a C program to print all permutations of a given stringAugust 2, 2009

A permutation, also called an “arrangement number” or “order,” is a rearrangement of the elements of an ordered list S into a one-to-one correspondence with S itself. A string of length n has n! permutation.Source: Mathword(http://mathworld.wolfram.com/Permutation.html)

Below are the permutations of string ABC.ABC, ACB, BAC, BCA, CAB, CBA

Here is a solution using backtracking.

# include <stdio.h>

/* Function to swap values at two pointers */

void swap (char *x, char *y)

{

    char temp;

    temp = *x;

    *x = *y;

Page 148: Data structures all in one

    *y = temp;

}

/* Function to print permutations of string

   This function takes three parameters:

   1. String

   2. Starting index of the string

   3. Ending index of the string. */

void permute(char *a, int i, int n)

{

   int j;

   if (i == n)

     printf("%s\n", a);

   else

   {

        for (j = i; j <= n; j++)

       {

          swap((a+i), (a+j));

          permute(a, i+1, n);

          swap((a+i), (a+j)); //backtrack

       }

   }

}

/* Driver program to test above functions */

int main()

{

   char a[] = "ABC";

   permute(a, 0, 2);

   getchar();

Page 149: Data structures all in one

   return 0;

}

Algorithm Paradigm: BacktrackingTime Complexity: O(n*n!)

If you are given two traversal sequences, can you construct the binary tree?August 2, 2009

It depends on what traversals are given. If one of the traversal methods is Inorder then the tree can be constructed, otherwise not.

Therefore, following combination can uniquely identify a tree.

Inorder and Preorder.Inorder and Postorder.Inorder and Level-order.

And following do not.Postorder and Preorder.Preorder and Level-order.Postorder and Level-order.

For example, Preorder, Level-order and Postorder traversals are same for the trees given in above diagram.

Preorder Traversal = ABPostorder Traversal = BALevel-Order Traversal = AB

Page 150: Data structures all in one

So, even if three of them (Pre, Post and Level) are given, the tree can not be constructed.

Write an Efficient C Program to Reverse Bits of a NumberAugust 2, 2009

Method1 – SimpleLoop through all the bits of an integer. If a bit at ith position is set in the i/p no. then set the bit at (NO_OF_BITS – 1) – i in o/p. Where NO_OF_BITS is number of bits present in the given number.

/* Function to reverse bits of num */

unsigned int reverseBits(unsigned int num)

{

    unsigned int NO_OF_BITS = sizeof(num) * 8;

    unsigned int reverse_num = 0, i, temp;

    for (i = 0; i < NO_OF_BITS; i++)

    {

        temp = (num & (1 << i));

        if(temp)

            reverse_num |= (1 << ((NO_OF_BITS - 1) - i));

    }

    return reverse_num;

}

/* Driver function to test above function */

int main()

{

    unsigned int x = 2;

    printf("%u", reverseBits(x));

Page 151: Data structures all in one

    getchar();

}

Above program can be optimized by removing the use of variable temp. See below the modified code.

unsigned int reverseBits(unsigned int num)

{

    unsigned int NO_OF_BITS = sizeof(num) * 8;

    unsigned int reverse_num = 0;

    int i;

    for (i = 0; i < NO_OF_BITS; i++)

    {

        if((num & (1 << i)))

           reverse_num |= 1 << ((NO_OF_BITS - 1) - i);

   }

    return reverse_num;

}

Time Complexity: O(log n)Space Complexity: O(1)

Method 2 – StandardThe idea is to keep putting set bits of the num in reverse_num until num becomes zero. After num becomes zero, shift the remaining bits of reverse_num.

Let num is stored using 8 bits and num be 00000110. After the loop you will get reverse_num as 00000011. Now you need to left shift reverse_num 5 more times and you get the exact reverse 01100000.

unsigned int reverseBits(unsigned int num)

{

    unsigned int count = sizeof(num) * 8 - 1;

Page 152: Data structures all in one

    unsigned int reverse_num = num;

    num >>= 1;

    while(num)

    {

       reverse_num <<= 1;

       reverse_num |= num & 1;

       num >>= 1;

       count--;

    }

    reverse_num <<= count;

    return reverse_num;

}

int main()

{

    unsigned int x = 1;

    printf("%u", reverseBits(x));

    getchar();

}

Time Complexity: O(log n)Space Complexity: O(1)

Method 3 – Lookup Table:We can reverse the bits of a number in O(1) if we know the size of the number. We can implement it using look up table. Go through the below link for details. You will find some more interesting bit related stuff there.

http://www-graphics.stanford.edu/~seander/bithacks.html#BitReverseTable

Page 153: Data structures all in one

Write a function to reverse a linked listAugust 2, 2009

Iterative MethodIterate trough the linked list. In loop, change next to prev, prev to current and current to next.

Implementation of Iterative Method

#include<stdio.h>

#include<stdlib.h>

/* Link list node */

struct node

{

    int data;

    struct node* next;

};

/* Function to reverse the linked list */

static void reverse(struct node** head_ref)

{

    struct node* prev   = NULL;

    struct node* current = *head_ref;

    struct node* next;

    while (current != NULL)

    {

        next  = current->next;

        current->next = prev;

        prev = current;

        current = next;

Page 154: Data structures all in one

    }

    *head_ref = prev;

}

/* Function to push a node */

void push(struct node** head_ref, int new_data)

{

    /* allocate node */

    struct node* new_node =

            (struct node*) malloc(sizeof(struct node));

    /* put in the data  */

    new_node->data  = new_data;

    /* link the old list off the new node */

    new_node->next = (*head_ref);

    /* move the head to point to the new node */

    (*head_ref)    = new_node;

}

/* Function to print linked list */

void printList(struct node *head)

{

    struct node *temp = head;

    while(temp != NULL)

    {

        printf("%d  ", temp->data);

        temp = temp->next;

Page 155: Data structures all in one

    }

}

/* Drier program to test above function*/

int main()

{

    /* Start with the empty list */

    struct node* head = NULL;

     push(&head, 20);

     push(&head, 4);

     push(&head, 15);

     push(&head, 85);

     printList(head);

     reverse(&head);

     printf("\n Reversed Linked list \n");

     printList(head);

     getchar();

}

Time Complexity: O(n)Space Complexity: O(1)

Recursive Method:

1) Divide the list in two parts - first node and rest of the linked list. 2) Call reverse for the rest of the linked list. 3) Link rest to first. 4) Fix head pointer

Page 156: Data structures all in one

void recursiveReverse(struct node** head_ref)

{

    struct node* first;

    struct node* rest;

    /* empty list */

    if (*head_ref == NULL)

       return;

    /* suppose first = {1, 2, 3}, rest = {2, 3} */

    first = *head_ref;

    rest  = first->next;

    /* List has only one node */

    if (rest == NULL)

Page 157: Data structures all in one

       return;

    /* reverse the rest list and put the first element at the end */

    recursiveReverse(&rest);

    first->next->next  = first;

    /* tricky step -- see the diagram */

    first->next  = NULL;

    /* fix the head pointer */

    *head_ref = rest;

}

Time Complexity: O(n)Space Complexity: O(1)

References:http://cslibrary.stanford.edu/105/LinkedListProblems.pdf

Write a C function to detect loop in a linked listAugust 2, 2009

Below diagram shows a linked list with a loop

Following are different ways of doing thisUse Hashing:Traverse the list one by one and keep putting the node addresses in a Hash Table. At any point, if NULL is reached then return false and if

Page 158: Data structures all in one

next of current node points to any of the previously stored nodes in Hash then return true.

Mark Visited Nodes:This solution requires modifications to basic linked list data structure.  Have a visited flag with each node.  Traverse the linked list and keep marking visited nodes.  If you see a visited node again then there is a loop. This solution works in O(n) but requires additional information with each node.A variation of this solution that doesn’t require modification to basic data structure can be implemented using hash.  Just store the addresses of visited nodes in a hash and if you see an address that already exists in hash then there is a loop.

Floyd’s Cycle-Finding Algorithm:This is the fastest method. Traverse linked list using two pointers.  Move one pointer by one and other pointer by two.  If these pointers meet at some node then there is a loop.  If pointers do not meet then linked list doesn’t have loop.

Implementation of Floyd’s Cycle-Finding Algorithm:

#include<stdio.h>

#include<stdlib.h>

/* Link list node */

struct node

{

  int data;

  struct node* next;

};

void push(struct node** head_ref, int new_data)

{

  /* allocate node */

Page 159: Data structures all in one

  struct node* new_node =

  (struct node*) malloc(sizeof(struct node));

  /* put in the data  */

  new_node->data  = new_data;

  /* link the old list off the new node */

  new_node->next = (*head_ref);

  /* move the head to point to the new node */

  (*head_ref)    = new_node;

}

int detectloop(struct node *list)

{

  struct node  *slow_p = list, *fast_p = list;

  while(slow_p && fast_p &&

          fast_p->next )

  {

    slow_p = slow_p->next;

    fast_p  = fast_p->next->next;

    if (slow_p == fast_p)

    {

       printf("Found Loop");

       return 1;

    }

  }

  return 0;

Page 160: Data structures all in one

}

/* Drier program to test above function*/

int main()

{

  /* Start with the empty list */

  struct node* head = NULL;

  push(&head, 20);

  push(&head, 4);

  push(&head, 15);

  push(&head, 10);

  /* Create a loop for testing */

  head->next->next->next->next = head;

  detectloop(head);

  getchar();

}

Time Complexity: O(n)Auxiliary Space: O(1)

References:http://en.wikipedia.org/wiki/Cycle_detectionhttp://ostermiller.org/find_loop_singly_linked_list.html

Lucky NumbersAugust 6, 2009

Lucky numbers are subset of integers. Rather than going into much theory, let us see the process of arriving at lucky numbers,

Page 161: Data structures all in one

Take the set of integers1,2,3,4,5,6,7,8,9,10,11,12,14,15,16,17,18,19,……

First, delete every second number, we get following reduced set.1,3,5,7,9,11,13,15,17,19,…………

Now, delete every third number, we get1, 3, 7, 9, 13, 15, 19,….….

Continue this process indefinitely……Any number that does NOT get deleted due to above process is called “lucky”.

Therefore, set of lucky numbers is 1, 3, 7, 13,………

Now, given an integer ‘n’, write a function to say whether this number is lucky or not.

bool isLucky(int n)

Algorithm:Before every iteration, if we calculate position of the given no, then in a given iteration, we can determine if the no will be deleted. Suppose calculated position for the given no. is P before some iteration, and each Ith no. is going to be removed in this iteration, if P < I then input no is lucky, if P is such that P%I == 0 (I is a divisor of P), then input no is not lucky.

Recursive Way:

#include <stdio.h>

#define bool int

/* Returns 1 if n is a lucky no. ohterwise returns 0*/

bool isLucky(int n)

{

  static int counter = 2;

Page 162: Data structures all in one

  /*variable next_position is just for readability of

     the program we can remove it and use n only */

  int next_position = n;

  if(counter > n)

    return 1;

  if(n%counter == 0)

    return 0;

 /*calculate next position of input no*/

  next_position -= next_position/counter;

  counter++;

  return isLucky(next_position);

}

/*Driver function to test above function*/

int main()

{

  int x = 5;

  if( isLucky(x) )

    printf("%d is a lucky no.", x);

  else

    printf("%d is not a lucky no.", x);

  getchar();

}

Example:Let’s us take an example of 19

1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,15,17,18,19,20,21,……1,3,5,7,9,11,13,15,17,19,…..

Page 163: Data structures all in one

1,3,7,9,13,15,19,……….1,3,7,13,15,19,………1,3,7,13,19,………

In next step every 6th no .in sequence will be deleted. 19 will not be deleted after this step because position of 19 is 5th after this step. Therefore, 19 is lucky. Let’s see how above C code finds out:

Current function call Position after this call Counter for next call Next Call

isLucky(19 ) 10 3 isLucky(10)

isLucky(10) 7 4 isLucky(7)

isLucky(7) 6 5 isLucky(6)

isLucky(6) 5 6 isLucky(5)

When isLucky(6) is called, it returns 1 (because counter > n).

Iterative Way:Please see this comment for another simple and elegant implementation of the above algorithm.

Please write comments if you find any bug in the given programs or other ways to solve the same problem.

Does C support function overloading?August 6, 2009

First of all, what is function overloading? Function overloading is a feature of a programming language that allows one to have many functions with same name but with different signatures.This feature is present in most of the Object Oriented Languages such as C++ and Java. But C (not Object Oriented Language) doesn’t support this feature. However, one can achieve the similar functionality in C indirectly. One of the approach is as follows.

Have a void * type of pointer as an argument to the function. And another argument telling the actual data type of the first argument that is being passed.

Page 164: Data structures all in one

int foo(void * arg1, int arg2);

Suppose, arg2 can be interpreted as follows. 0 = Struct1 type variable, 1 = Struct2 type variable etc. Here Struct1 and Struct2 are user defined struct types.

While calling the function foo at different places…

foo(arg1, 0); /*Here, arg1 is pointer to struct type Struct1 variable*/ foo(arg1, 1); /*Here, arg1 is pointer to struct type Struct2 variable*/

Since the second argument of the foo keeps track the data type of the first type, inside the function foo, one can get the actual data type of the first argument by typecast accordingly. i.e. inside the foo function

if(arg2 == 0)

{

  struct1PtrVar = (Struct1 *)arg1;

}

else if(arg2 == 1)

{

  struct2PtrVar = (Struct2 *)arg1;

}

else

{

  /*Error Handling*/

}

There can be several other ways of implementing function overloading in C. But all of them will have to use pointers – the most powerful feature of C.In fact, it is said that without using the pointers, one can’t use C efficiently & effectively in a real world program!

Page 165: Data structures all in one

How can I return multiple values from a function?August 7, 2009

We all know that a function in C can return only one value. So how do we achieve the purpose of returning multiple values.Well, first take a look at the declaration of a function.

int foo(int arg1, int arg2);

So we can notice here that our interface to the function is through arguments and return value only. (Unless we talk about modifying the globals inside the function)

Let us take a deeper look…Even though a function can return only one value but that value can be of pointer type. That’s correct, now you’re speculating right!We can declare the function such that, it returns a structure type user defined variable or a pointer to it . And by the property of a structure, we know that a structure in C can hold multiple values of asymmetrical types (i.e. one int variable, four char variables, two float variables and so on…)

If we want the function to return multiple values of same data types, we could return the pointer to array of that data types.

We can also make the function return multiple values by using the arguments of the function. How? By providing the pointers as arguments.

Usually, when a function needs to return several values, we use one pointer in return instead of several pointers as argumentss.

Write a program to add two numbers in base 14August 8, 2009

Asked by Anshya.

Below are the different ways to add base 14 numbers.

Page 166: Data structures all in one

Method 1Thanks to Raj for suggesting this method.

1. Convert both i/p base 14 numbers to base 10. 2. Add numbers. 3. Convert the result back to base 14.

Method 2Just add the numbers in base 14 in same way we add in base 10. Add numerals of both numbers one by one from right to left. If there is a carry while adding two numerals, consider the carry for adding next numerals.

Let us consider the presentation of base 14 numbers same as hexadecimal numbers

A --> 10 B --> 11 C --> 12 D --> 13Example: num1 = 1 2 A num2 = C D 3

1. Add A and 3, we get 13(D). Since 13 is smaller than 14, carry becomes 0 and resultant numeral becomes D

2. Add 2, D and carry(0). we get 15. Since 15 is greater than 13, carry becomes 1 and resultant numeral is 15 - 14 = 1

3. Add 1, C and carry(1). we get 14. Since 14 is greater

Page 167: Data structures all in one

than 13, carry becomes 1 and resultant numeral is 14 - 14 = 0

Finally, there is a carry, so 1 is added as leftmost numeral and the result becomes 101D

Implementation of Method 2

# include <stdio.h>

# include <stdlib.h>

# define bool int

int getNumeralValue(char );

char getNumeral(int );

/* Function to add two numbers in base 14 */

char *sumBase14(char *num1,  char *num2)

{

   int l1 = strlen(num1);

   int l2 = strlen(num2);

   char *res;

   int i;

   int nml1, nml2, res_nml;

   bool carry = 0;

   if(l1 != l2)

   {

     printf("Function doesn't support numbers of different"

            " lengths. If you want to add such numbers then"

            " prefix smaller number with required no. of zeroes");

     getchar();

Page 168: Data structures all in one

     assert(0);

   }

   /* Note the size of the allocated memory is one

     more than i/p lenghts for the cases where we

     have carry at the last like adding D1 and A1 */

   res = (char *)malloc(sizeof(char)*(l1 + 1));

   /* Add all numerals from right to left */

   for(i = l1-1; i >= 0; i--)

   {

     /* Get decimal values of the numerals of

       i/p numbers*/

     nml1 = getNumeralValue(num1[i]);

     nml2 = getNumeralValue(num2[i]);

     /* Add decimal values of numerals and carry */

     res_nml = carry + nml1 + nml2;

     /* Check if we have carry for next addition

        of numerals */

     if(res_nml >= 14)

     {

       carry = 1;

       res_nml -= 14;

     }

     else

     {

       carry = 0;

     }

Page 169: Data structures all in one

     res[i+1] = getNumeral(res_nml);

   }

   /* if there is no carry after last iteration

      then result should not include 0th character

      of the resultant string */

   if(carry == 0)

     return (res + 1);

   /* if we have carry after last iteration then

     result should include 0th character */

   res[0] = '1';

   return res;

}

/* Function to get value of a numeral

  For example it returns 10 for input 'A'

  1 for '1', etc */

int getNumeralValue(char num)

{

  if( num >= '0' && num <= '9')

    return (num - '0');

  if( num >= 'A' && num <= 'D')

    return (num - 'A' + 10);

  /* If we reach this line caller is giving

    invalid character so we assert and fail*/

  assert(0);

}

Page 170: Data structures all in one

/* Function to get numeral for a value.

  For example it returns 'A' for input 10

  '1' for 1, etc */

char getNumeral(int val)

{

  if( val >= 0 && val <= 9)

    return (val + '0');

  if( val >= 10 && val <= 14)

    return (val + 'A' - 10);

  /* If we reach this line caller is giving

    invalid no. so we assert and fail*/

  assert(0);

}

/*Driver program to test above functions*/

int main()

{

    char *num1 = "DC2";

    char *num2 = "0A3";

    printf("Result is %s", sumBase14(num1, num2));

    getchar();

    return 0;

}

Notes:Above approach can be used to add numbers in any base. We don’t have to do string operations if base is smaller than 10.

Page 171: Data structures all in one

You can try extending the above program for numbers of different lengths.

Given a binary tree, print out all of its root-to-leaf paths one per line.August 9, 2009

Asked by Varun Bhatia

Here is the solution.

Algorithm:

initialize: pathlen = 0, path[1000] /*1000 is some max limit for paths, it can change*/

/*printPathsRecur traverses nodes of tree in preorder */printPathsRecur(tree, path[], pathlen) 1) If node is not NULL then a) push data to path array: path[pathlen] = node->data. b) increment pathlen pathlen++ 2) If node is a leaf node then print the path array. 3) Else a) Call printPathsRecur for left subtree printPathsRecur(node->left, path, pathLen) b) Call printPathsRecur for right subtree. printPathsRecur(node->right, path, pathLen)

Example:

Page 172: Data structures all in one

Example Tree

Output for the above example will be

1 2 4 1 2 5 1 3

Implementation:

/*program to print all of its root-to-leaf paths for a tree*/

#include <stdio.h>

#include <stdlib.h>

/* A binary tree node has data, pointer to left child

   and a pointer to right child */

struct node

{

    int data;

    struct node* left;

    struct node* right;

};

void printArray(int [], int);

void printPathsRecur(struct node*, int [], int);

struct node* newNode(int );

void printPaths(struct node*);

Page 173: Data structures all in one

/* Given a binary tree, print out all of its root-to-leaf

   paths, one per line. Uses a recursive helper to do the work.*/

void printPaths(struct node* node)

{

  int path[1000];

  printPathsRecur(node, path, 0);

}

/* Recursive helper function -- given a node, and an array containing

 the path from the root node up to but not including this node,

 print out all the root-leaf paths. */

void printPathsRecur(struct node* node, int path[], int pathLen)

{

  if (node==NULL) return;

  /* append this node to the path array */

  path[pathLen] = node->data;

  pathLen++;

  /* it's a leaf, so print the path that led to here */

  if (node->left==NULL && node->right==NULL)

  {

    printArray(path, pathLen);

  }

  else

  {

  /* otherwise try both subtrees */

    printPathsRecur(node->left, path, pathLen);

Page 174: Data structures all in one

    printPathsRecur(node->right, path, pathLen);

  }

}

/* Helper function that allocates a new node with the

   given data and NULL left and right pointers. */

struct node* newNode(int data)

{

  struct node* node = (struct node*)

                       malloc(sizeof(struct node));

  node->data = data;

  node->left = NULL;

  node->right = NULL;

  return(node);

}

/* Utility that prints out an array on a line */

void printArray(int ints[], int len)

{

  int i;

  for (i=0; i<len; i++) {

    printf("%d ", ints[i]);

  }

  printf("\n");

}

/* Driver program to test mirror() */

int main()

Page 175: Data structures all in one

{

  struct node *root = newNode(1);

  root->left        = newNode(2);

  root->right       = newNode(3);

  root->left->left  = newNode(4);

  root->left->right = newNode(5);

  /* Print all root-to-leaf paths of the input tree */

  printPaths(root);

  getchar();

  return 0;

}

References:http://cslibrary.stanford.edu/110/BinaryTrees.html

Lowest Common Ancestor in a Binary Search Tree.August 9, 2009

Given the values of two nodes in a *binary search tree*, write a c program to find the lowest common ancestor. You may assume that both values already exist in the tree.

The function prototype is as follows:

int FindLowestCommonAncestor(node* root, int value1, int value)

Page 176: Data structures all in one

I/P : 4 and 14 O/P : 8 (Here the common ancestors of 4 and 14, are {8,20}. Of {8,20}, the lowest one is 8).

Here is the solution

Algorithm:The main idea of the solution is — While traversing Binary Search Tree from top to bottom, the first node n we encounter with value between n1 and n2, i.e., n1 < n < n2 is the Lowest or Least Common Ancestor(LCA) of n1 and n2 (where n1 < n2). So just traverse the BST in pre-order, if you find a node with value in between n1 and n2 then n is the LCA, if it's value is greater than both n1 and n2 then our LCA lies on left side of the node, if it's value is smaller than both n1 and n2 then LCA lies on right side.

Implementation:

#include <stdio.h>

#include <stdlib.h>

/* A binary tree node has data, pointer to left child

   and a pointer to right child */

struct node

{

Page 177: Data structures all in one

    int data;

    struct node* left;

    struct node* right;

};

struct node* newNode(int );

/* Function to find least comman ancestor of n1 and n2 */

int leastCommanAncestor(struct node* root, int n1, int n2)

{

  /* If we have reached a leaf node then LCA doesn't exist

     If root->data is equal to any of the inputs then input is

     not valid. For example 20, 22 in the given figure */

  if(root == NULL || root->data == n1 || root->data == n2)

    return -1;

  /* If any of the input nodes is child of the current node

     we have reached the LCA. For example, in the above figure

     if we want to calculate LCA of 12 and 14, recursion should

     terminate when we reach 8*/

  if((root->right != NULL) &&

    (root->right->data == n1 || root->right->data == n2))

    return root->data;

  if((root->left != NULL) &&

    (root->left->data == n1 || root->left->data == n2))

    return root->data;

  if(root->data > n1 && root->data < n2)

    return root->data;

Page 178: Data structures all in one

  if(root->data > n1 && root->data > n2)

    return leastCommanAncestor(root->left, n1, n2);

  if(root->data < n1 && root->data < n2)

    return leastCommanAncestor(root->right, n1, n2);

}

/* Helper function that allocates a new node with the

   given data and NULL left and right pointers. */

struct node* newNode(int data)

{

  struct node* node = (struct node*)

                       malloc(sizeof(struct node));

  node->data  = data;

  node->left  = NULL;

  node->right = NULL;

  return(node);

}

/* Driver program to test mirror() */

int main()

{

  struct node *root  = newNode(2);

  root->left         = newNode(1);

  root->right        = newNode(4);

  root->right->left  = newNode(3);

  root->right->right = newNode(5);

/* Constructed binary search tree is

Page 179: Data structures all in one

            2

           / \

         1   4

             / \

           3   5

*/

  printf("\n The Least Common Ancestor is \n");

  printf("%d", leastCommanAncestor(root, 3, 5));

  getchar();

  return 0;

}

Note that above function assumes that n1 is smaller than n2.

Time complexity: Time complexity is O(Logn) for a balanced BST and O(n) for a skewed BST.

What is the purpose of a function prototype?August 12, 2009

The Function prototype serves the following purposes -

1) It tells the return type of the data that the function will return.2) It tells the number of arguments passed to the function.3) It tells the data types of the each of the passed arguments.4) Also it tells the order in which the arguments are passed to the function.

Therefore essentially, function prototype specifies the input/output interlace to the function i.e. what to give to the function and what to expect from the function.

Prototype of a function is also called signature of the function.

Page 180: Data structures all in one

What if one doesn’t specify the function prototype?Output of below kind of programs is generally asked at many places.

int main()

{

   foo();

   getchar();

   return 0;

}

void foo()

{

   printf("foo called");

}

If one doesn’t specify the function prototype, the behavior is specific to C standard (either C90 or C99) that the compilers implement. Up to C90 standard, C compilers assumed the return type of the omitted function prototype as int. And this assumption at compiler side may lead to unspecified program behavior.

Later C99 standard specified that compilers can no longer assume return type as int. Therefore, C99 became more restrict in type checking of function prototype. But to make C99 standard backward compatible, in practice, compilers throw the warning saying that the return type is assumed as int. But they go ahead with compilation. Thus, it becomes the responsibility of programmers to make sure that the assumed function prototype and the actual function type matches.

To avoid all this implementation specifics of C standards, it is best to have function prototype.

Function to check if a singly linked list is palindromeAugust 13, 2009

Page 181: Data structures all in one

Asked by Varun Bhatia.

METHOD 1 (By reversing the list)

1. Get the middle of the linked list. 2. Reverse the second half of the linked list. 3. Compare the first half and second half. 4. Construct the original linked list by reversing the second half again and attaching it back to the first half

Implementation:

/* Program to check if a linked list is palindrome */

#include<stdio.h>

#include<stdlib.h>

#define bool int

/* Link list node */

struct node

{

    char data;

    struct node* next;

};

Page 182: Data structures all in one

void reverse(struct node**);

bool compareLists(struct node*, struct node *);

/* Function to check if given linked list is

  palindrome or not */

bool isPalindrome(struct node *head)

{

   struct node *slow_ptr = head;

   struct node *fast_ptr = head;

   struct node *second_half;

   struct node *prev_of_slow_ptr = head;

   char res;

   if(head!=NULL)

   {

       /* Get the middle of the list. Move slow_ptr by 1

         and fast_ptrr by 2, slow_ptr will have the |_n/2_|th

         node */

       while((fast_ptr->next)!=NULL &&

               (fast_ptr->next->next)!=NULL)

       {

          fast_ptr = fast_ptr->next->next;

          /*We need previous of the slow_ptr for

           linked lists  with odd elements */

          prev_of_slow_ptr = slow_ptr;

          slow_ptr = slow_ptr->next;

       }

Page 183: Data structures all in one

       /* Case where we have even no of elements */

       if(fast_ptr->next != NULL)

       {

         second_half = slow_ptr->next;

         reverse(&second_half);

         slow_ptr->next = NULL;

         res = compareLists(head, second_half);

         /*construct the original list back*/

         reverse(&second_half);

         slow_ptr->next = second_half;

       }

       /* Case where we have odd no. of elements. Neither first

          nor second list should have the middle element */

       else

       {

          second_half = slow_ptr->next;

          prev_of_slow_ptr->next = NULL;

          reverse(&second_half);

          res = compareLists(head, second_half);

         /*construct the original list back*/

         reverse(&second_half);

         prev_of_slow_ptr->next = slow_ptr;

         slow_ptr->next = second_half;

       }

       return res;

Page 184: Data structures all in one

   }

}

/* Function to reverse the linked list  Note that this

    function may change the head */

void reverse(struct node** head_ref)

{

    struct node* prev   = NULL;

    struct node* current = *head_ref;

    struct node* next;

    while (current != NULL)

    {

        next  = current->next;

        current->next = prev;

        prev = current;

        current = next;

    }

    *head_ref = prev;

}

/* Function to check if two input lists have same data*/

int compareLists(struct node* head1, struct node *head2)

{

    struct node* temp1 = head1;

    struct node* temp2 = head2;

    while(temp1 && temp2)

    {

       if(temp1->data == temp2->data)

Page 185: Data structures all in one

       {

          temp1 = temp1->next;

          temp2 = temp2->next;

       }

       else return 0;

    }

    /* Both are empty reurn 1*/

    if(temp1 == NULL && temp2 == NULL)

       return 1;

    /* Will reach here when one is NULL

      and other is not */

    return 0;

}

/* Push a node to linked list. Note that this function

  changes the head */

void push(struct node** head_ref, char new_data)

{

    /* allocate node */

    struct node* new_node =

            (struct node*) malloc(sizeof(struct node));

    /* put in the data  */

    new_node->data  = new_data;

    /* link the old list off the new node */

    new_node->next = (*head_ref);

Page 186: Data structures all in one

    /* move the head to pochar to the new node */

    (*head_ref)    = new_node;

}

/* Drier program to test above function*/

int main()

{

    /* Start with the empty list */

    struct node* head = NULL;

     push(&head, 'p');

     push(&head, 'e');

     push(&head, 'e');

     push(&head, 'p');

     /* p->e->e->p */

     if(isPalindrome(head) == 1)

       printf("Linked list is Palindrome");

     else

       printf("Linked list is not Palindrome");

     getchar();

     return 0;

}

Time Complexity O(n)Auxiliary Space: O(1)

Page 187: Data structures all in one

METHOD 2 (Using Recursion)Thanks to Sharad Chandra for suggesting this approach.

Use two pointers left and right. Move right and left using recursion and check for following in each recursive call.1) Sub-list is palindrome.2) Value at current left and right are matching.

If both above conditions are true then return true.

#define bool int

#include<stdio.h>

#include<stdlib.h>

/* Link list node */

struct node

{

    char data;

    struct node* next;

};

bool isPalindrome(struct node **left, struct node *right)

{

   /* stop recursion here */

   if (!right)

      return true;

   /* If sub-list is not palindrome then no need to

       check for current left and right, return false */

   bool isp = isPalindrome(left, right->next);

   if (isp == false)

      return false;

Page 188: Data structures all in one

   /* Check values at current left and right */

   bool isp1 = (right->data == (*left)->data);

   /* Move left to next node */

   *left = (*left)->next; /* save next pointer */

   return isp1;

}

/* UTILITY FUNCTIONS */

/* Push a node to linked list. Note that this function

  changes the head */

void push(struct node** head_ref, char new_data)

{

    /* allocate node */

    struct node* new_node =

            (struct node*) malloc(sizeof(struct node));

    /* put in the data  */

    new_node->data  = new_data;

    /* link the old list off the new node */

    new_node->next = (*head_ref);

    /* move the head to pochar to the new node */

    (*head_ref)    = new_node;

}

Page 189: Data structures all in one

/* Drier program to test above function*/

int main()

{

    /* Start with the empty list */

    struct node* head = NULL;

     push(&head, 'r');

     push(&head, 'a');

     push(&head, 'd');

     push(&head, 'a');

     push(&head, 'r');

     /* r->a->d->a->r*/

     if(isPalindrome(&head, head) == 1)

       printf("Linked list is Palindrome");

     else

       printf("Linked list is not Palindrome");

     getchar();

     return 0;

}

Time Complexity: O(n)Auxiliary Space: O(n) if Function Call Stack size is considered, otherwise O(1).

Search an element in a sorted and pivoted arrayAugust 15, 2009

Question:An element in a sorted array can be found in O(log n) time via binary search. But suppose I rotate the sorted array at some pivot unknown

Page 190: Data structures all in one

to you beforehand. So for instance, 1 2 3 4 5 might become 3 4 5 1 2. Devise a way to find an element in the rotated array in O(log n) time.

Solution:Thanks to Ajay Mishra for initial solution.

Algorithm:Find the pivot point, divide the array in two sub-arrays and call binary search.The main idea for finding pivot is – for a sorted (in increasing order) and pivoted array, pivot element is the only only element for which next element to it is smaller than it.Using above criteria and binary search methodology we can get pivot element in O(logn) time

Input arr[] = {3, 4, 5, 1, 2}Element to Search = 1 1) Find out pivot point and divide the array in two sub-arrays. (pivot = 2) /*Index of 5*/ 2) Now call binary search for one of the two sub-arrays. (a) If element is greater than 0th element then search in left array (b) Else Search in right array (1 will go in else as 1 < 0th element(3)) 3) If element is found in selected sub-array then return index Else return -1.

Implementation:

Page 191: Data structures all in one

/* Program to search an element in a sorted and pivoted array*/

#include <stdio.h>

int findPivot(int[], int, int);

int binarySearch(int[], int, int, int);

/* Searches an element no in a pivoted sorted array arrp[]

   of size arr_size */

int pivotedBinarySearch(int arr[], int arr_size, int no)

{

   int pivot = findPivot(arr, 0, arr_size-1);

   // If we didn't find a pivot, then array is not rotated at all

   if (pivot == -1)

     return binarySearch(arr, 0, arr_size-1, no);

   // If we found a pivot, then first compare with pivot and then

   // search in two subarrays around pivot

   if (arr[pivot] == no)

     return pivot;

   if (arr[0] <= no)

     return binarySearch(arr, 0, pivot-1, no);

   else

     return binarySearch(arr, pivot+1, arr_size-1, no);

}

/* Function to get pivot. For array 3, 4, 5, 6, 1, 2

   it will return 3 */

int findPivot(int arr[], int low, int high)

Page 192: Data structures all in one

{

   if (high < low)

       return -1;

   int mid = (low + high)/2;   /*low + (high - low)/2;*/

   if (mid < high && arr[mid] > arr[mid + 1])

     return mid;

   if (arr[low] >= arr[mid])

     return findPivot(arr, low, mid-1);

   else

     return findPivot(arr, mid + 1, high);

}

/* Standard Binary Search function*/

int binarySearch(int arr[], int low, int high, int no)

{

   if (high < low)

       return -1;

   int mid = (low + high)/2;  /*low + (high - low)/2;*/

   if (no == arr[mid])

     return mid;

   if (no > arr[mid])

     return binarySearch(arr, (mid + 1), high, no);

   else

     return binarySearch(arr, low, (mid -1), no);

}

Page 193: Data structures all in one

/* Driver program to check above functions */

int main()

{

   int arr[] = {3, 4, 5, 1, 2};

   int arr_size = sizeof(arr)/sizeof(arr[0]);

   int no = 3;

   printf("Index of the element is %d", pivotedBinarySearch(arr, arr_size, no));

   return 0;

}

Output:

Index of the element is 0

Please note that the solution may not work for cases where the input array has duplicates.

Time Complexity O(logn)

The Great Tree-List Recursion Problem.August 15, 2009

Asked by Varun Bhatia.

Question:Write a recursive function treeToList(Node root) that takes an ordered binary tree and rearranges the internal pointers to make a circular doubly linked list out of the tree nodes. The”previous” pointers should be stored in the “small” field and the “next” pointers should be stored in the “large” field. The list should be arranged so that the nodes are in increasing order. Return the head pointer to the new list.

This is very well explained and implemented at http://cslibrary.stanford.edu/109/TreeListRecursion.html

Count set bits in an integerAugust 19, 2009

Page 194: Data structures all in one

Write an efficient program to count number of 1s in binary representation of an integer.

1. Simple Method Loop through all bits in an integer, check if a bit is set and if it is then increment the set bit count. See below program.

/* Function to get no of set bits in binary

   representation of passed binary no. */

int countSetBits(unsigned int n)

{

  unsigned int count = 0;

  while(n)

  {

    count += n & 1;

    n >>= 1;

  }

  return count;

}

/* Program to test function countSetBits */

int main()

{

    int i = 9;

    printf("%d", countSetBits(i));

    getchar();

    return 0;

}

Time Complexity: (-)(logn) (Theta of logn)

2. Brian Kernighan’s Algorithm:Subtraction of 1 from a number toggles all the bits (from right to left) till the rightmost set bit(including the righmost set bit). So if we

Page 195: Data structures all in one

subtract a number by 1 and do bitwise & with itself (n & (n-1)), we unset the righmost set bit. If we do n & (n-1) in a loop and count the no of times loop executes we get the set bit count.Beauty of the this solution is number of times it loops is equal to the number of set bits in a given integer.

1 Initialize count: = 0 2 If integer n is not zero (a) Do bitwise & with (n-1) and assign the value back to n n: = n&(n-1) (b) Increment count by 1 (c) go to step 2 3 Else return count

Implementation of Brian Kernighan’s Algorithm:

#include<stdio.h>

/* Function to get no of set bits in binary

   representation of passed binary no. */

int countSetBits(int n)

{

    unsigned int count = 0;

    while (n)

    {

      n &= (n-1) ;

      count++;

    }

    return count;

}

Page 196: Data structures all in one

/* Program to test function countSetBits */

int main()

{

    int i = 9;

    printf("%d", countSetBits(i));

    getchar();

    return 0;

}

Example for Brian Kernighan’s Algorithm:

n = 9 (1001) count = 0

Since 9 > 0, subtract by 1 and do bitwise & with (9-1) n = 9&8 (1001 & 1000) n = 8 count = 1

Since 8 > 0, subtract by 1 and do bitwise & with (8-1) n = 8&7 (1000 & 0111) n = 0 count = 2

Since n = 0, return count which is 2 now.

Time Complexity: O(logn)

3. Using Lookup table: We can count bits in O(1) time using lookup table. Please seehttp://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetTable for details.

Page 197: Data structures all in one

You can find one use of counting set bits at http://geeksforgeeks.org/?p=1465References:http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetNaive

Write a C macro PRINT(x) which prints xAugust 23, 2009

At the first look, it seems that writing a C macro which prints its argument is child’s play. Following program should work i.e. it should print x

#define PRINT(x) (x)

int main()

{

  printf("%s",PRINT(x));

  return 0;

}

But it would issue compile error because the data type of x, which is taken as variable by the compiler, is unknown. Now it doesn’t look so obvious. Isn’t it? Guess what, the followings also won’t work

#define PRINT(x) ('x')

#define PRINT(x) ("x")

But if we know one of lesser known traits of C language, writing such a macro is really a child’s play.   In C, there’s a # directive, also called ‘Stringizing Operator’, which does this magic. Basically # directive converts its argument in a string. Voila! it is so simple to do the rest. So the above program can be modified as below.

#define PRINT(x) (#x)

int main()

{

  printf("%s",PRINT(x));

Page 198: Data structures all in one

  return 0;

}

Now if the input is PRINT(x), it would print x. In fact, if the input is PRINT(geeks), it would print geeks.

You may find the details of this directive from Microsoft portal here.

Copy a linked list with next and arbit pointerAugust 24, 2009

You are given a Double Link List with one pointer of each node pointing to the next node just like in a single link list. The second pointer however CAN point to any node in the list and not just the previous node. Now write a program in O(n) time to duplicate this list. That is, write a program which will create a copy of this list.

Let us call the second pointer as arbit pointer as it can point to any arbitrary node in the linked list.

Arbitrary pointers are shown in red and next pointers in black

Figure 1

Method 1 (Uses O(n) extra space)This method stores the next and arbitrary mappings (of original list) in an array first, then modifies the original Linked List (to create copy), creates a copy. And finally restores the original list.

1) Create all nodes in copy linked list using next pointers.3) Store the node and its next pointer mappings of original linked list.3) Change next pointer of all nodes in original linked list to point to the

Page 199: Data structures all in one

corresponding node in copy linked list.Following diagram shows status of both Linked Lists after above 3 steps. The red arrow shows arbit pointers and black arrow shows next pointers.

Figure 2

4) Change the arbit pointer of all nodes in copy linked list to point to corresponding node in original linked list.5) Now construct the arbit pointer in copy linked list as below and restore the next pointer of nodes in the original linked list.

copy_list_node->arbit = copy_list_node->arbit->arbit->next; copy_list_node = copy_list_node->next;

6) Restore the next pointers in original linked list from the stored mappings(in step 2).

Time Complexity:  O(n)Auxiliary Space:  O(n)

Method 2 (Uses Constant Extra Space)Thanks to Saravanan Mani for providing this solution. This solution works using constant space.1) Create the copy of node 1 and insert it between node 1 & node 2 in original Linked List, create the copy of 2 and insert it between 2 & 3..

Page 200: Data structures all in one

Continue in this fashion, add the copy of N afte the Nth node2) Now copy the arbitrary link in this fashion

original->next->arbitrary = original->arbitrary->next; /*TRAVERSE TWO NODES*/

This works because original->next is nothing but copy of original and Original->arbitrary->next is nothing but copy of arbitrary.3) Now restore the original and copy linked lists in this fashion in a single loop.

original->next = original->next->next; copy->next = copy->next->next;

4) Make sure that last element of original->next is NULL.

Time Complexity: O(n)Auxiliary Space: O(1)

Asked by Varun Bhatia. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.

Memory efficient doubly linked listAugust 24, 2009

Asked by Varun Bhatia.

Question:Write a code for implementation of doubly linked list with use of single pointer in each node.

Solution:This question is solved and very well explained at http://www.linuxjournal.com/article/6828.

We also recommend to read http://en.wikipedia.org/wiki/XOR_linked_list

How to print % using printf()?

Page 201: Data structures all in one

August 30, 2009

Asked by Tanuj

Here is the standard prototype of printf function in C.

int printf(const char *format, ...);

The format string is composed of zero or more directives: ordinary characters (not %), which are copied unchanged to the output stream; and conversion specifications, each of argument (and it is an error if insufficiently many arguments are given).

The character % is followed by one of the following characters.

The flag characterThe field widthThe precisionThe length modifierThe conversion specifier:

See http://swoolley.org/man.cgi/3/printf for details of all the above characters. The main thing to note in the standard is the below line about conversion specifier.

A `%' is written. No argument is converted. The complete conversion specification is`%%'.

So we can print “%” using “%%”

/* Program to print %*/

#include<stdio.h>

/* Program to print %*/

int main()

{

   printf("%%");

   getchar();

   return 0;

Page 202: Data structures all in one

}

We can also print “%” using below.

printf("%c", '%');

printf("%s", "%");

How to declare a pointer to a function?September 1, 2009

Well, we assume that you know what does it mean by pointer in C. So how do we create a pointer to an integer in C?Huh..it is pretty simple..

int * ptrInteger; /*We have put a * operator between int and ptrInteger to create a pointer.*/

Here ptrInteger is a pointer to integer. If you understand this, then logically we should not have any problem in declaring a pointer to a function 

So let us first see ..how do we declare a function? For example,

int foo(int);

Here foo is a function that returns int and takes one argument of int type. So as a logical guy will think, by putting a * operator between int and foo(int) should create a pointer to a function i.e.

int * foo(int);

But Oops..C operator precedence also plays role here ..so in this case, operator () will take priority over operator *. And the above declaration will mean – a function foo with one argument of int type and return value of int * i.e. integer pointer. So it did something that we didn’t want to do. 

Page 203: Data structures all in one

So as a next logical step, we have to bind operator * with foo somehow. And for this, we would change the default precedence of C operators using () operator.

int (*foo)(int);

That’s it. Here * operator is with foo which is a function name. And it did the same that we wanted to do.

So that wasn’t as difficult as we thought earlier!

Find the node with minimum value in a Binary Search TreeSeptember 3, 2009

This is quite simple. Just traverse the node from root to left recursively until left is NULL. The node whose left is NULL is the node with minimum value.

For the above tree, we start with 20, then we move left 8, we keep on moving to left until we see NULL. Since left of 4 is NULL, 4 is the node with minimum value.

#include <stdio.h>

#include<stdlib.h>

/* A binary tree node has data, pointer to left child

   and a pointer to right child */

struct node

Page 204: Data structures all in one

{

    int data;

    struct node* left;

    struct node* right;

};

/* Helper function that allocates a new node

with the given data and NULL left and right

pointers. */

struct node* newNode(int data)

{

  struct node* node = (struct node*)

                       malloc(sizeof(struct node));

  node->data  = data;

  node->left  = NULL;

  node->right = NULL;

  return(node);

}

/* Give a binary search tree and a number,

inserts a new node with the given number in

the correct place in the tree. Returns the new

root pointer which the caller should then use

(the standard trick to avoid using reference

parameters). */

struct node* insert(struct node* node, int data)

{

  /* 1. If the tree is empty, return a new,

Page 205: Data structures all in one

      single node */

  if (node == NULL)

    return(newNode(data));

  else

  {

    /* 2. Otherwise, recur down the tree */

    if (data <= node->data)

        node->left  = insert(node->left, data);

    else

        node->right = insert(node->right, data);

    /* return the (unchanged) node pointer */

    return node;

  }

}

/* Given a non-empty binary search tree,

return the minimum data value found in that

tree. Note that the entire tree does not need

to be searched. */

int minValue(struct node* node) {

  struct node* current = node;

  /* loop down to find the leftmost leaf */

  while (current->left != NULL) {

    current = current->left;

  }

  return(current->data);

}

Page 206: Data structures all in one

/* Driver program to test sameTree function*/

int main()

{

  struct node* root = NULL;

  root = insert(root, 4);

  insert(root, 2);

  insert(root, 1);

  insert(root, 3);

  insert(root, 6);

  insert(root, 5);

  printf("\n Minimum value in BST is %d", minValue(root));

  getchar();

  return 0;

}

Time Complexity: O(n) Worst case happens for left skewed trees.

Similarly we can get the maximum value by recursively traversing the right node of a binary search tree.

References:http://cslibrary.stanford.edu/110/BinaryTrees.html

Merge an array of size n into another array of size m+nSeptember 5, 2009

Asked by BinodQuestion:There are two sorted arrays. First one is of size m+n containing only m elements. Another one is of size n and contains n elements. Merge these two arrays into the first array of size m+n such that the output is sorted.

Page 207: Data structures all in one

Input: array with m+n elements (mPlusN[]).

NA => Value is not filled/available in array mPlusN[]. There should be n such array blocks.

Input: array with n elements (N[]).

Output: N[] merged into mPlusN[] (Modified mPlusN[])

Algorithm:

Let first array be mPlusN[] and other array be N[]1) Move m elements of mPlusN[] to end.2) Start from nth element of mPlusN[] and 0th element of N[] and merge them into mPlusN[].

Implementation:

/* Assuming -1 is filled for the places where element

   is not available */

#define NA -1

/* Function to move m elements at the end of array

   mPlusN[] */

void moveToEnd(int mPlusN[], int size)

{

  int i = 0, j = size - 1;

Page 208: Data structures all in one

  for (i = size-1; i >= 0; i--)

    if(mPlusN[i] != NA)

    {

      mPlusN[j] = mPlusN[i];

      j--;

    }

}

/* Merges array N[] of size n into array mPlusN[]

   of size m+n*/

int merge(int mPlusN[], int N[], int m, int n)

{

  int i = n;  /* Current index of i/p part of mPlusN[]*/

  int j = 0; /* Current index of N[]*/

  int k = 0; /* Current index of of output mPlusN[]*/

  while(k <= (m+n))

  {

    /* Take the element from mPlusN[] if

       a) its value is smaller and we

          have not reached end of it

       b) We have reached end of N[] */

    if((i < (m+n) && mPlusN[i] <= N[j]) || ( j == n))

    {

      mPlusN[k] = mPlusN[i];

      k++;

      i++;

    }

    else

    {

      mPlusN[k] = N[j];

Page 209: Data structures all in one

      k++;

      j++;

    }

  }

}

/* Utility that prints out an array on a line */

void printArray(int arr[], int size)

{

  int i;

  for (i=0; i < size; i++)

    printf("%d ", arr[i]);

  printf("\n");

}

/* Driver function to test above functions */

int main()

{

  /* Initialize arrays */

  int mPlusN[9] = {2, 8, NA, NA, NA, 13, NA, 15, 20};

  int N[] = {5, 7, 9, 25};

  int m = 5, n = 4;

  /*Move the m elements at the end of mPlusN*/

  moveToEnd(mPlusN, 9);

  /*Merge N[] into mPlusN[] */

  merge(mPlusN, N, 5, 4);

Page 210: Data structures all in one

  /* Print the resultant mPlusN */

  printArray(mPlusN, 9);

  getchar();

}

Time Complexity: O(m+n)

Please write comment if you find any bug in the above program or a better way to solve the same problem.

Count number of bits to be flipped to convert A to BSeptember 5, 2009

Suggested by Dheeraj

Question: You are given two numbers A and B. Write a program to count number of bits needed to be flipped to convert A to B.

Solution:

1. Calculate XOR of A and B. a_xor_b = A ^ B 2. Count the set bits in the above calculated XOR result. countSetBits(a_xor_b)

XOR of two number will have set bits only at those places where A differs from B.

Example:

A = 1001001 B = 0010101 a_xor_b = 1011100 No of bits need to flipped = set bit count in a_xor_b i.e. 4

Page 211: Data structures all in one

To get the set bit count please see another post on this portal http://geeksforgeeks.org/?p=1176

Operating Systems | Set 1September 6, 2009

Following questions have been asked in GATE CS exam.

1. Which of the following is NOT a valid deadlock prevention scheme? (GATE CS 2000)(a) Release all resources before requesting a new resource(b) Number the resources uniquely and never request a lower numbered resource than the last one requested.(c) Never request a resource after releasing any resource(d) Request and all required resources be allocated before execution.

Answer: (c)References:http://www.cs.jhu.edu/~yairamir/cs418/os4/sld013.htmhttp://en.wikipedia.org/wiki/Deadlock

2. Let m[0]…m[4] be mutexes (binary semaphores) and P[0] …. P[4] be processes.Suppose each process P[i] executes the following:

wait (m[i]); wait(m[(i+1) mode 4]);

------

release (m[i]); release (m[(i+1)mod 4]);

This could cause (GATE CS 2000)(a) Thrashing(b) Deadlock(c) Starvation, but not deadlock(d) None of the above

Answer: (b)Explanation:

Page 212: Data structures all in one

You can easily see a deadlock in a situation where..P[0] has acquired m[0] and waiting for m[1]P[1] has acquired m[1] and waiting for m[2]P[2] has acquired m[2] and waiting for m[3]P[3] has acquired m[3] and waiting for m[0]

3. A graphics card has on board memory of 1 MB. Which of the following modes can thecard not support? (GATE CS 2000)(a) 1600 x 400 resolution with 256 colours on a 17 inch monitor(b) 1600 x 400 resolution with 16 million colours on a 14 inch monitor(c) 800 x 400 resolution with 16 million colours on a 17 inch monitor(d) 800 x 800 resolution with 256 colours on a 14 inch monitor

Answer: (b)Explanation:Monitor size doesn’t matter here. So, we can easily deduct that answer should be (b) as this has the highest memory requirements. Let us verify it.Number of bits required to store a 16M colors pixel = ceil(log2(16*1000000)) = 24Number of bytes required for 1600 x 400 resolution with 16M colors = (1600 * 400 * 24)/8 which is 192000000 (greater than 1MB).

4 Consider a virtual memory system with FIFO page replacement policy. For an arbitrary page access pattern, increasing the number of page frames in main memory will (GATE CS 2001)a) Always decrease the number of page faultsb) Always increase the number of page faultsc) Some times increase the number of page faultsd) Never affect the number of page faults

Answer: (c)Explanation:Incrementing the number of page frames doesn’t always decrease the page faults (Belady’s Anomaly). For details see http://en.wikipedia.org/wiki/Belady%27s_anomaly

Page 213: Data structures all in one

5. Which of the following requires a device driver? (GATE CS 2001)a) Registerb) Cachec) Main memoryd) Disk

Answer: (d)

Divide a string in N equal partsSeptember 9, 2009

Difficulty Level: Rookie

Question:Write a program to print N equal parts of a given string.

Solution:1) Get the size of the string using string function strlen()   (present in string.h)2) Get size of a part.

part_size = string_length/n

3) Loop through the input string. In loop, if index becomes multiple of part_size then put a part separator(“\n”)

Implementation:

#include<stdio.h>

#include<string.h>

/* Function to print n equal parts of str*/

void divideString(char *str, int n)

{

   int str_size = strlen(str);

Page 214: Data structures all in one

   int i;

   int part_size;

   /*Check if string can be divided in n equal parts */

   if(str_size%n != 0)

   {

     printf("Invalid Input: String size is not divisible by n");

     return;

   }

   /* Calculate the size of parts to find the division points*/

   part_size = str_size/n;

   for(i = 0; i< str_size; i++)

   {

     if(i%part_size == 0)

        printf("\n"); /* newline separator for different parts */

     printf("%c", str[i]);

   }

}

int main()

{

    /*length od string is 28*/

    char *str = "a_simple_divide_string_quest";

    /*Print 4 equal parts of the string */

    divideString(str, 4);

    getchar();

Page 215: Data structures all in one

    return 0;

}

In above solution, we are simply printing the N equal parts of the string. If we want individual parts to be stored then we need to allocate part_size + 1 memory for all N parts (1 extra for string termination character ‘\0′), and store the addresses of the parts in an array of character pointers.

Automata Theory | Set 1September 12, 2009

Following questions have been asked in GATE CS exam.

1. Let S and T be language over ={a,b} represented by the regular expressions (a+b*)* and (a+b)*, respectively. Which of the following is true? (GATE CS 2000)

(a) ScT (S is a subset of T)(b) TcS (T is a subset of S)(c) S=T(d) SnT=Ø

Answer: (c).

2. Let L denotes the language generated by the grammar S – OSO/00. Which of the following is true? (GATE CS 2000)(a) L = O(b) L is regular but not O(c) L is context free but not regular(d) L is not context free

Answer: (b)Explanation: Please note that grammar itself is not regular but language L is regular as L can be represented using a regular grammar, for example S -> S00/00.References:http://en.wikipedia.org/wiki/Regular_grammar

Page 216: Data structures all in one

3. Consider the following two statements:S1: { 0^2n |n >= l} is a regu1ar languageS2: { 0^m 0^n 0^(m+n) l m >= 1 and n >= 2} is a regu1ar languageWhich of the following statements is correct? (GATE CS 2001)a) Only S1 is correctb) Only S2 is correctc) Both S1 and S2 are correctd) None of S1 and S2 is correct

Answer: (c)Explanation:S1 can be written as (00)^n where n >= 1. And S2 can be written as (00)^(m+n) where m >=2 and n >= 1. S2 can be further reduced to (00)^x where x >= 3.We can easily write regular grammars for both S1 and S2.G1 -> G100/00 (For S1)G2 -> G200/000000 (For S2)

4. Which of the following statements in true? (GATE CS 2001) (a) If a language is context free it can always be accepted by a deterministic push-down automaton(b) The union of two context free languages is context free(c) The intersection of two context free languages is context free(d) The complement of a context free language is context free

Answer: (b)Explanation:Context-free languages are closed under the following operations. That is, if L and P are context-free languages and D is a regular language, the following languages are context-free as well:• the Kleene star L * of L• the image Ø(L) of L under a homomorphism Ø• the concatenation of L and P• the union of L and P• the intersection of L with a regular language D (L n D).Context-free languages are not closed under complement, intersection, or difference.

Page 217: Data structures all in one

Why a) is not true?The language recognized by deterministic pushdown automaton is deterministic context free language. Not all context-free languages are deterministic. This is unlike the situation for deterministic finite automata, which are also a subset of the nondeterministic finite automata but can recognize the same class of languages (as demonstrated by the subset construction).References:http://en.wikipedia.org/wiki/Context-free_languagehttp://en.wikipedia.org/wiki/Deterministic_pushdown_automaton

5. Given an arbitrary non-deterministic finite automaton (NFA) with N states, the maximum number of states in an equivalent minimized DFA is at least. (GATE CS 2001)(a) N^2(b) 2^N(c) 2N(d) N!

Answer: (b)References:http://en.wikipedia.org/wiki/Powerset_construction

Output of C Programs | Set 7September 13, 2009

Predict the output of below programs

Question 1

int main()

{

    int i = 0;

    while (i <= 4)

    {

       printf("%d", i);

       if (i > 3)

Page 218: Data structures all in one

        goto inside_foo;

       i++;

    }

    getchar();

    return 0;

}

void foo()

{

   inside_foo:

     printf("PP");

}

Output: Compiler error: Label “inside_foo” used but not defined.

Explanation: Scope of a label is within a function. We cannot goto a label from other function.

Question 2

#define a 10

int main()

{

  #define a 50

  printf("%d",a);

  getchar();

  return 0;

}

Output: 50

Page 219: Data structures all in one

Preprocessor doesn’t give any error if we redefine a preprocessor directive. It may give warning though. Preprocessor takes the most recent value before use of and put it in place of a.

Now try following

#define a 10

int main()

{

  printf("%d ",a);

  #define a 50

  printf("%d ",a);

  getchar();

  return 0;

}

Question 3

int main()

{

     char str[] = "geeksforgeeks";

     char *s1 = str, *s2 = str;

     int i;

     for(i = 0; i < 7; i++)

     {

        printf(" %c ", *str);

        ++s1;

     }

     for(i = 0; i < 6; i++)

Page 220: Data structures all in one

     {

        printf(" %c ", *s2);

        ++s2;

      }

      getchar();

      return 0;

}

Outputg g g g g g g g e e k s f

ExplanationBoth s1 and s2 are initialized to str. In first loop str is being printed and s1 is being incremented, so first loop will print only g. In second loop s2 is incremented and s2 is printed so second loop will print “g e e k s f ”

Question 4

int main()

{

    char str[] = "geeksforgeeks";

    int i;

    for(i=0; str[i]; i++)

        printf("\n%c%c%c%c", str[i], *(str+i), *(i+str), i[str]);

    getchar();

    return 0;

}

Output:ggggeeee

Page 221: Data structures all in one

eeeekkkkssssffffoooorrrrggggeeeeeeeekkkkssss

Explanaition:Following are different ways of indexing both array and string.

arr[i]*(arr + i)*(i + arr)i[arr]

So all of them print same character.

Question 5

int main()

{

    char *p;

    printf("%d %d ", sizeof(*p), sizeof(p));

    getchar();

    return 0;

}

Output: Compiler dependent. I got output as “1 4″

Explanation:Output of the above program depends on compiler. sizeof(*p) gives size of character. If characters are stored as 1 byte then sizeof(*p)

Page 222: Data structures all in one

gives 1.sizeof(p) gives the size of pointer variable. If pointer variables are stored as 4 bytes then it gives 4.

Given a string, find its first non-repeating characterSeptember 16, 2009

Algorithm:

1) Scan the string from left to right and construct the count array.2) Again, scan the string from left to right and check for count of each character, if you find an element who's count is 1, return it.

Example:

Input string: str = geeksforgeeks1: Construct character count array from the input string. .... count['e'] = 4 count['f'] = 1 count['g'] = 2 count['k'] = 2 ……2: Get the first character who's count is 1 ('f').

Implementation:

#include<stdlib.h>

#include<stdio.h>

#define NO_OF_CHARS 256

/* Returns an array of size 256 containg count

Page 223: Data structures all in one

   of characters in the passed char array */

int *getCharCountArray(char *str)

{

   int *count = (int *)calloc(sizeof(int), NO_OF_CHARS);

   int i;

   for (i = 0; *(str+i);  i++)

      count[*(str+i)]++;

   return count;

}

/* The function returns index of first non-repeating

   character in a string. If all characters are repeating

   then reurns -1 */

int firstNonRepeating(char *str)

{

  int *count = getCharCountArray(str);

  int index = -1, i;

  for (i = 0; *(str+i);  i++)

  {

    if(count[*(str+i)] == 1)

    {

      index = i;

      break;

    }

  }

  return index;

}

Page 224: Data structures all in one

/* Driver program to test above function */

int main()

{

  char str[] = "geeksforgeeks";

  int index =  firstNonRepeating(str);

  if(index == -1)

    printf("Either all characters are repeating or string is empty");

  else

   printf("First non-repeating character is %c", str[index]);

  getchar();

  return 0;

}

Time Complexity: O(n)

Given a linked list which is sorted, how will you insert in sorted waySeptember 17, 2009

Algorithm: Let input linked list is sorted in increasing order.

1) If Linked list is empty then make the node as head and return it.2) If value of the node to be inserted is smaller than value of head node then insert the node at start and make it head.3) In a loop, find the appropriate node after which the input node (let 9) is to be inserted. To find the appropriate node start from head, keep moving until you reach a node GN (10 in the below diagram) who's value is greater than the input node. The node just before GN is the appropriate

Page 225: Data structures all in one

node (7).4) Insert the node (9) after the appropriate node (7) found in step 3.

Initial Linked List

Linked List after insertion of 9

Implementation:

/* Program to insert in a sorted list */

#include<stdio.h>

#include<stdlib.h>

/* Link list node */

struct node

{

    int data;

    struct node* next;

};

/* function to insert a new_node in a list. Note that this

  function expects a pointer to head_ref as this can modify the

  head of the input linked list (similar to push())*/

void sortedInsert(struct node** head_ref, struct node* new_node)

{

  struct node* current;

  /* Special case for the head end */

Page 226: Data structures all in one

  if (*head_ref == NULL || (*head_ref)->data >= new_node->data)

  {

    new_node->next = *head_ref;

    *head_ref = new_node;

  }

  else

  {

    /* Locate the node before the point of insertion */

    current = *head_ref;

    while (current->next!=NULL && current->next->data < new_node->data)

    {

      current = current->next;

    }

    new_node->next = current->next;

    current->next = new_node;

  }

}

/* BELOW FUNCTIONS ARE JUST UTILITY TO TEST sortedInsert */

/* Given a reference (pointer to pointer) to the head

  of a list and an int, push a new node on the front

  of the list. */

void push(struct node** head_ref, int new_data)

{

    /* allocate node */

    struct node* new_node =

            (struct node*) malloc(sizeof(struct node));

Page 227: Data structures all in one

    /* put in the data  */

    new_node->data  = new_data;

    /* link the old list off the new node */

    new_node->next = (*head_ref);

    /* move the head to point to the new node */

    (*head_ref)    = new_node;

}

/* Function to print linked list */

void printList(struct node *head)

{

    struct node *temp = head;

    while(temp != NULL)

    {

        printf("%d  ", temp->data);

        temp = temp->next;

    }

}

/* Drier program to test count function*/

int main()

{

    /* Start with the empty list */

    struct node* head = NULL;

    int value_to_insert;

    /* Use push() to construct below list

Page 228: Data structures all in one

     2->5->7->10->15  */

    push(&head, 15);

    push(&head, 10);

    push(&head, 7);

    push(&head, 5);

    push(&head, 2);

    /* Let us try inserting 9 */

    value_to_insert = 9;

    struct node* new_node =

            (struct node*) malloc(sizeof(struct node));

    new_node->data  = value_to_insert;

    printf("\n List before insertion of %d \n", value_to_insert);

    printList(head);

    sortedInsert(&head, new_node);

    printf("\n List after insertion of %d \n", value_to_insert);

    printList(head);

    getchar();

    return 1;

}

Shorter Implementation using double pointersThanks to Murat M Ozturk for providing this solution. Please see Murat M Ozturk’s comment below for complete function. The code uses double pointer to keep track of the next pointer of the previous node (after which new node is being inserted).

Page 229: Data structures all in one

Note that below line in code changes current to have address of next pointer in a node.

current = &((*current)->next);

Also, note below comments.

new_node->next = *current; /* Copies the value-at-address current to new_node's next pointer*/

*current = new_node;  /* Fix next pointer of the node (using it's address) after which new_node is being inserted */

Time Complexity: O(n)

References:http://cslibrary.stanford.edu/105/LinkedListProblems.pdf

Operating Systems | Set 2September 18, 2009

Following questions have been asked in GATE CS exam.

1. Consider a machine with 64 MB physical memory and a 32-bit virtual address space. If the page size is 4KB, what is the approximate size of the page table? (GATE 2001)(a) 16 MB(b) 8 MB(c) 2 MB(d) 24 MB

Answer: (c)Explanation:A page entry is used to get address of physical memory. Here we assume that single level of Paging is happening. So the resulting page table will contain entries for all the pages of the Virtual address space.

Page 230: Data structures all in one

Number of entries in page table = (virtual address space size)/(page size)

Using above formula we can say that there will be 2^(32-12) = 2^20 entries in page table.No. of bits required to address the 64MB Physical memory = 26.So there will be 2^(26-12) = 2^14 page frames in the physical memory. And page table needs to store the address of all these 2^14 page frames. Therefore, each page table entry will contain 14 bits address of the page frame and 1 bit for valid-invalid bit.Since memory is byte addressable. So we take that each page table entry is 16 bits i.e. 2 bytes long.

Size of page table = (total number of page table entries) *(size of a page table entry) = (2^20 *2) = 2MB

For the clarity of the concept, please see the following figure. As per our question, here p = 20, d = 12 and f = 14.

2. Consider Peterson’s algorithm for mutual exclusion between

Page 231: Data structures all in one

two concurrent processes i and j. The program executed by process is shown below.

repeat flag [i] = true; turn = j; while ( P ) do no-op; Enter critical section, perform actions, then exit critical section flag [ i ] = false; Perform other non-critical section actions. until false;

For the program to guarantee mutual exclusion, the predicate P in the while loop should be (GATE 2001)a) flag [j] = true and turn = ib) flag [j] = true and turn = jc) flag [i] = true and turn = jd) flag [i] = true and turn = i

Answer: (b)Basically, Peterson’s algorithm provides guaranteed mutual exclusion by using the two following constructs – flag[] and turn. flag[] controls that the willingness of a process to be entered in critical section. While turn controls the process that is allowed to be entered in critical section. So by replacing P with the following,

flag [j] = true and turn = j

process i will not enter critical section if process j wants to enter critical section and it is process j’sturn to enter critical section. The same concept can be extended for more than two processes. For details, refer the following.References:http://en.wikipedia.org/wiki/Peterson%27s_algorithm

3 More than one word are put in one cache block to (GATE 2001)

Page 232: Data structures all in one

(a) exploit the temporal locality of reference in a program(b) exploit the spatial locality of reference in a program(c) reduce the miss penalty(d) none of the above

Answer: (b)Temporal locality refers to the reuse of specific data and/or resources within relatively small time durations. Spatial locality refers to the use of data elements within relatively close storage locations.To exploit the spatial locality, more than one word are put into cache block.References:http://en.wikipedia.org/wiki/Locality_of_reference

4. Which of the following statements is false? (GATE 2001) a) Virtual memory implements the translation of a program’s address space into physical memory address spaceb) Virtual memory allows each program to exceed the size of the primary memoryc) Virtual memory increases the degree of multiprogrammingd) Virtual memory reduces the context switching overhead

Answer: (d)In a system with virtual memory context switch includes extra overhead in switching of address spaces.References:http://www.itee.adfa.edu.au/~spike/CSA2/Lectures00/lecture.vm.htm

5. Consider a set of n tasks with known runtimes r1, r2, … rn to be run on a uniprocessor machine. Which of the following processor scheduling algorithms will result in the maximum throughput? (GATE 2001) (a) Round-Robin(b) Shortest-Job-First(c) Highest-Response-Ratio-Next(d) First-Come-First-Served

Page 233: Data structures all in one

Answer: (b)

Operating Systems | Set 3September 21, 2009

Following questions have been asked in GATE CS exam.

1. Suppose the time to service a page fault is on the average 10 milliseconds, while a memory access takes 1 microsecond. Then a 99.99% hit ratio results in average memory access time of (GATE CS 2000)(a) 1.9999 milliseconds(b) 1 millisecond(c) 9.999 microseconds(d) 1.9999 microseconds

Answer: (d)Explanation:

Average memory access time = [(% of page miss)*(time to service a page fault) + (% of page hit)*(memory access time)]/100

So, average memory access time in microseconds is.(99.99*1 + 0.01*10*1000)/100 = (99.99+100)/1000 = 199.99/1000 =1.9999 µs

2. Which of the following need not necessarily be saved on a context switch between processes? (GATE CS 2000)(a) General purpose registers(b) Translation look-aside buffer(c) Program counter(d) All of the above

Answer: (b)Explanation:In a process context switch, the state of the first process must be

Page 234: Data structures all in one

saved somehow, so that, when the scheduler gets back to the execution of the first process, it can restore this state and continue.

The state of the process includes all the registers that the process may be using, especially the program counter, plus any other operating system specific data that may be necessary.

A Translation lookaside buffer (TLB) is a CPU cache that memory management hardware uses to improve virtual address translation speed. A TLB has a fixed number of slots that contain page table entries, which map virtual addresses to physical addresses. On a context switch, some TLB entries can become invalid, since the virtual-to-physical mapping is different. The simplest strategy to deal with this is to completely flush the TLB.References:http://en.wikipedia.org/wiki/Context_switchhttp://en.wikipedia.org/wiki/Translation_lookaside_buffer#Context_switch

3. Where does the swap space reside ? (GATE 2001)(a) RAM(b) Disk(c) ROM(d) On-chip cacheAnswer: (b)Explanation:Swap space is an area on disk that temporarily holds a process memory image. When physical memory demand is sufficiently low, process memory images are brought back into physical memory from the swap area. Having sufficient swap space enables the system to keep some physical memory free at all times.References:http://docs.hp.com/en/B2355-90672/ch06s02.html

4. Which of the following does not interrupt a running process? (GATE CS 2001)(a) A device

Page 235: Data structures all in one

(b) Timer(c) Scheduler process(d) Power failure

Answer: (c)Explanation:Scheduler process doesn’t interrupt any process, it’s Job is to select the processes for following three purposes.Long-term scheduler(or job scheduler) –selects which processes should be brought into the ready queueShort-term scheduler(or CPU scheduler) –selects which process should be executed next and allocates CPU.Mid-term Scheduler (Swapper)- present in all systems with virtual memory, temporarily removes processes from main memory and places them on secondary memory (such as a disk drive) or vice versa. The mid-term scheduler may decide to swap out a process which has not been active for some time, or a process which has a low priority, or a process which is page faulting frequently, or a process which is taking up a large amount of memory in order to free up main memory for other processes, swapping the process back in later when more memory is available, or when the process has been unblocked and is no longer waiting for a resource.

5. Which of the following scheduling algorithms is non-preemptive? (GATE CS 2002)

a) Round Robinb) First-In First-Outc) Multilevel Queue Schedulingd) Multilevel Queue Scheduling with Feedback

Answer: (b)

DAY 3Database Management Systems | Set 1

Page 236: Data structures all in one

September 23, 2009

Following questions have been asked in GATE CS exam.

1. Given the relations

employee (name, salary, deptno) anddepartment (deptno, deptname, address)

Which of the following queries cannot be expressed using the basic relational algebraoperations (U, -, x,  , p)? (GATE CS 2000)(a) Department address of every employee(b) Employees whose name is the same as their department name(c) The sum of all employees’ salaries(d) All employees of a given department

Answer: (c)

Explanation:The six basic operators of relational algebra are the selection( ), the projection( ), the Cartesian product (x) (also called the cross product or cross join), the set union (U), the set difference (-), and the rename (p). These six operators are fundamental in the sense that none of them can be omitted without losing expressive power. Many other operators have been defined in terms of these six. Among the most important are set intersection, division, and the natural join, but aggregation is not possible with these basic relational algebra operations. So, we cannot run sum of all employees’ salaries with the six operations.

References:http://en.wikipedia.org/wiki/Relational_algebrahttp://faculty.ksu.edu.sa/zitouni/203%20Haseb%20%20Lecture%20Notes/Relional%20Algebra.pdf

Page 237: Data structures all in one

2. Given the following relation instance.

x y z1 4 21 5 31 6 33 2 2

Which of the following functional dependencies are satisfied by the instance? (GATE CS 2000)(a) XY -> Z and Z -> Y(b) YZ -> X and Y -> Z(c) YZ -> X and X -> Z(d) XZ -> Y and Y -> X

Answer: (b)

Explanation:A functional dependency (FD) is a constraint between two sets of attributes in a relation from a database. A FD X->Y require that the value of X uniquely determines the value of Y where X and Y are set of attributes. FD is a generalization of the notion of a key.

Given that X, Y, and Z are sets of attributes in a relation R, one can derive several properties of functional dependencies. Among the most important are Armstrong’s axioms, which are used in database normalization:

* Subset Property (Axiom of Reflexivity): If Y is a subset of X, then X ? Y* Augmentation (Axiom of Augmentation): If X -> Y, then XZ -> YZ* Transitivity (Axiom of Transitivity): If X -> Y and Y -> Z, then X -> Z

From these rules, we can derive these secondary rules:

Page 238: Data structures all in one

* Union: If X -> Y and X -> Z, then X -> YZ* Decomposition: If X -> YZ, then X -> Y and X -> Z* Pseudotransitivity: If X -> Y and YZ -> W, then XZ -> W

In the above question, Y uniquely determines X and Z, for a given value of Y you can easily find out values of X and Z.So, Y -> X and Y -> Z hold for above schema.From rule of augmentation we can say YZ->X. If we understand the notion of FD, we don’t need to apply axioms to find out which option is true, just by looking at the schema and options we can say that (b) is true.

References:http://www.cse.iitb.ac.in/~sudarsha/db-book/slide-dir/ch7.pdfhttp://en.wikipedia.org/wiki/Functional_dependency

3. Given relations r(w, x) and s(y, z), the result ofselect distinct w, xfrom r, sis guaranteed to be same as r, provided (GATE CS 2000)(a) r has no duplicates and s is non-empty(b) r and s have no duplicates(c) s has no duplicates and r is non-empty(d) r and s have the same number of tuples

Answer: (a)

Explanation:The query selects all attributes of r. Since we have distinct in query, result can be equal to r only if r doesn’t have duplicates.

If we do not give any attribute on which we want to join two tables, then the queries like above become equivalent to Cartesian product. Cartisian product of two sets will be empty if any of the two sets is empty. So, s should have atleast one record to get all rows of r.

Page 239: Data structures all in one

4. In SQL, relations can contain null values, and comparisons with null values are treated as unknown. Suppose all comparisons with a null value are treated as false. Which of thefollowing pairs is not equivalent? (GATE CS 2000)(a) x = 5, not (not (x = 5)(b) x = 5, x > 4 and x < 6, where x is an integer(c) x < 5, not(x = 5)(d) None of the above

Answer (c)

Explanation:It doesn’t need much explanation. For all values smaller than 5, x < 5 will always be true but x = 5 will be false.

5. Consider a schema R(A, B, C, D) and functional dependencies A -> B and C -> D. Then the decomposition of R into R1 (A, B) and R2(C, D) is (GATE CS 2001)a) dependency preserving and loss less joinb) loss less join but not dependency preservingc) dependency preserving but not loss less joind) not dependency preserving and not loss less join

Answer: (c)

Explanation:Dependency Preserving Decomposition:Decomposition of R into R1 and R2 is a dependency preserving decomposition if closure of functional dependencies after decomposition is same as closure of of FDs before decomposition.A simple way is to just check whether we can derive all the original FDs from the FDs present after decomposition.

Page 240: Data structures all in one

In the above question R(A, B, C, D) is decomposed into R1 (A, B) and R2(C, D) and there are only two FDs A -> B and C -> D. So, the decomposition is dependency preserving

Lossless-Join Decomposition:Decomposition of R into R1 and R2 is a lossless-join decomposition if at least one of the following functional dependencies are in F+ (Closure of functional dependencies)

R1 R2 R1 OR R1 R2 R2In the above question R(A, B, C, D) is decomposed into R1 (A, B) and R2(C, D), and R1   R2 is empty. So, the decomposition is not lossless.

References:http://www.cs.sfu.ca/CC/354/han/materia/notes/354notes-chapter6/node1.html

Median of two sorted arraysSeptember 28, 2009

Question: There are 2 sorted arrays A and B of size n each. Write an algorithm to find the median of the array obtained after merging the above 2 arrays(i.e. array of length 2n). The complexity should be O(log(n))

Median: In probability theory and statistics, a median is described as the number separating the higher half of a sample, a population, or a probability distribution, from the lower half.The median of a finite list of numbers can be found by arranging all the numbers from lowest value to highest value and picking the middle one.

For getting the median of input array { 12, 11, 15, 10, 20 }, first sort the array. We get { 10, 11, 12, 15, 20 } after sorting. Median is the middle element of the sorted array which is 12.

Page 241: Data structures all in one

There are different conventions to take median of an array with even number of elements, one can take the mean of the two middle values, or first middle value, or second middle value.

Let us see different methods to get the median of two sorted arrays of size n each. Since size of the set for which we are looking for median is even (2n), we are taking average of middle two numbers in all below solutions.

Method 1 (Simply count while Merging)Use merge procedure of merge sort. Keep track of count while comparing elements of two arrays. If count becomes n(For 2n elements), we have reached the median. Take the average of the elements at indexes n-1 and n in the merged array. See the below implementation.

Implementation:

#include <stdio.h>

/* This function returns median of ar1[] and ar2[].   Assumptions in this function:   Both ar1[] and ar2[] are sorted arrays   Both have n elements */int getMedian(int ar1[], int ar2[], int n){    int i = 0;  /* Current index of i/p array ar1[] */    int j = 0; /* Current index of i/p array ar2[] */    int count;    int m1 = -1, m2 = -1;

    /* Since there are 2n elements, median will be average     of elements at index n-1 and n in the array obtained after     merging ar1 and ar2 */    for (count = 0; count <= n; count++)    {        /*Below is to handle case where all elements of ar1[] are          smaller than smallest(or first) element of ar2[]*/        if (i == n)        {            m1 = m2;            m2 = ar2[0];            break;        }

        /*Below is to handle case where all elements of ar2[] are          smaller than smallest(or first) element of ar1[]*/        else if (j == n)        {            m1 = m2;            m2 = ar1[0];

Page 242: Data structures all in one

            break;        }

        if (ar1[i] < ar2[j])        {            m1 = m2;  /* Store the prev median */            m2 = ar1[i];            i++;        }        else        {            m1 = m2;  /* Store the prev median */            m2 = ar2[j];            j++;        }    }

    return (m1 + m2)/2;}

/* Driver program to test above function */int main(){    int ar1[] = {1, 12, 15, 26, 38};    int ar2[] = {2, 13, 17, 30, 45};

    int n1 = sizeof(ar1)/sizeof(ar1[0]);    int n2 = sizeof(ar2)/sizeof(ar2[0]);    if (n1 == n2)        printf("Median is %d", getMedian(ar1, ar2, n1));    else        printf("Doesn't work for arrays of unequal size");    getchar();    return 0;}

Time Complexity: O(n)

Method 2 (By comparing the medians of two arrays)This method works by first getting medians of the two sorted arrays and then comparing them.

Let ar1 and ar2 be the input arrays.

Algorithm:

1) Calculate the medians m1 and m2 of the input arrays ar1[] and ar2[] respectively.

Page 243: Data structures all in one

2) If m1 and m2 both are equal then we are done. return m1 (or m2)3) If m1 is greater than m2, then median is present in one of the below two subarrays. a) From first element of ar1 to m1 (ar1[0...|_n/2_|]) b) From m2 to last element of ar2 (ar2[|_n/2_|...n-1])4) If m2 is greater than m1, then median is present in one of the below two subarrays. a) From m1 to last element of ar1 (ar1[|_n/2_|...n-1]) b) From first element of ar2 to m2 (ar2[0...|_n/2_|])5) Repeat the above process until size of both the subarrays becomes 2.6) If size of the two arrays is 2 then use below formula to get the median. Median = (max(ar1[0], ar2[0]) + min(ar1[1], ar2[1]))/2

Example:

ar1[] = {1, 12, 15, 26, 38} ar2[] = {2, 13, 17, 30, 45}

For above two arrays m1 = 15 and m2 = 17

For the above ar1[] and ar2[], m1 is smaller than m2. So median is present in one of the following two subarrays.

[15, 26, 38] and [2, 13, 17]

Let us repeat the process for above two subarrays:

Page 244: Data structures all in one

m1 = 26 m2 = 13.

m1 is greater than m2. So the subarrays become

[15, 26] and [13, 17]Now size is 2, so median = (max(ar1[0], ar2[0]) + min(ar1[1], ar2[1]))/2 = (max(15, 13) + min(26, 17))/2 = (15 + 17)/2 = 16

Implementation:

#include<stdio.h>

int max(int, int); /* to get maximum of two integers */int min(int, int); /* to get minimum of two integeres */int median(int [], int); /* to get median of a sorted array */

/* This function returns median of ar1[] and ar2[].   Assumptions in this function:   Both ar1[] and ar2[] are sorted arrays   Both have n elements */int getMedian(int ar1[], int ar2[], int n){    int m1; /* For median of ar1 */    int m2; /* For median of ar2 */

    /* return -1  for invalid input */    if (n <= 0)        return -1;

    if (n == 1)        return (ar1[0] + ar2[0])/2;

    if (n == 2)        return (max(ar1[0], ar2[0]) + min(ar1[1], ar2[1])) / 2;

    m1 = median(ar1, n); /* get the median of the first array */    m2 = median(ar2, n); /* get the median of the second array */

    /* If medians are equal then return either m1 or m2 */    if (m1 == m2)        return m1;

     /* if m1 < m2 then median must exist in ar1[m1....] and ar2[....m2] */    if (m1 < m2)    {        if (n % 2 == 0)            return getMedian(ar1 + n/2 - 1, ar2, n - n/2 +1);        else

Page 245: Data structures all in one

            return getMedian(ar1 + n/2, ar2, n - n/2);    }

    /* if m1 > m2 then median must exist in ar1[....m1] and ar2[m2...] */    else    {        if (n % 2 == 0)            return getMedian(ar2 + n/2 - 1, ar1, n - n/2 + 1);        else            return getMedian(ar2 + n/2, ar1, n - n/2);    }}

/* Function to get median of a sorted array */int median(int arr[], int n){    if (n%2 == 0)        return (arr[n/2] + arr[n/2-1])/2;    else        return arr[n/2];}

/* Driver program to test above function */int main(){    int ar1[] = {1, 2, 3, 6};    int ar2[] = {4, 6, 8, 10};    int n1 = sizeof(ar1)/sizeof(ar1[0]);    int n2 = sizeof(ar2)/sizeof(ar2[0]);    if (n1 == n2)      printf("Median is %d", getMedian(ar1, ar2, n1));    else     printf("Doesn't work for arrays of unequal size");

    getchar();    return 0;}

/* Utility functions */int max(int x, int y){    return x > y? x : y;}

int min(int x, int y){    return x > y? y : x;}

Time Complexity: O(logn)Algorithmic Paradigm: Divide and Conquer

Method 3 (By doing binary search for the median):The basic idea is that if you are given two arrays ar1[] and ar2[] and

Page 246: Data structures all in one

know the length of each, you can check whether an element ar1[i] is the median in constant time. Suppose that the median is ar1[i]. Since the array is sorted, it is greater than exactly i values in array ar1[]. Then if it is the median, it is also greater than exactly j = n – i – 1 elements in ar2[].It requires constant time to check if ar2[j] <= ar1[i] <= ar2[j + 1]. If ar1[i] is not the median, then depending on whether ar1[i] is greater or less than ar2[j] and ar2[j + 1], you know that ar1[i] is either greater than or less than the median. Thus you can binary search for median in O(lg n) worst-case time.

For two arrays ar1 and ar2, first do binary search in ar1[]. If you reach at the end (left or right) of the first array and don't find median, start searching in the second array ar2[].

1) Get the middle element of ar1[] using array indexes left and right. Let index of the middle element be i.2) Calculate the corresponding index j of ar2[] j = n – i – 1 3) If ar1[i] >= ar2[j] and ar1[i] <= ar2[j+1] then ar1[i] and ar2[j] are the middle elements. return average of ar2[j] and ar1[i]4) If ar1[i] is greater than both ar2[j] and ar2[j+1] then do binary search in left half (i.e., arr[left ... i-1])5) If ar1[i] is smaller than both ar2[j] and ar2[j+1] then do binary search in right half (i.e., arr[i+1....right])6) If you reach at any corner of ar1[] then do binary search in ar2[]

Example:

ar1[] = {1, 5, 7, 10, 13} ar2[] = {11, 15, 23, 30, 45}

Page 247: Data structures all in one

Middle element of ar1[] is 7. Let us compare 7 with 23 and 30, since 7 smaller than both 23 and 30, move to right in ar1[]. Do binary search in {10, 13}, this step will pick 10. Now compare 10 with 15 and 23. Since 10 is smaller than both 15 and 23, again move to right. Only 13 is there in right side now. Since 13 is greater than 11 and smaller than 15, terminate here. We have got the median as 12 (average of 11 and 13)

Implementation:

#include<stdio.h>

int getMedianRec(int ar1[], int ar2[], int left, int right, int n);

/* This function returns median of ar1[] and ar2[].   Assumptions in this function:   Both ar1[] and ar2[] are sorted arrays   Both have n elements */int getMedian(int ar1[], int ar2[], int n){    return getMedianRec(ar1, ar2, 0, n-1, n);}

/* A recursive function to get the median of ar1[] and ar2[]   using binary search */int getMedianRec(int ar1[], int ar2[], int left, int right, int n){    int i, j;

    /* We have reached at the end (left or right) of ar1[] */    if(left > right)        return getMedianRec(ar2, ar1, 0, n-1, n);

    i = (left + right)/2;    j = n - i - 1;  /* Index of ar2[] */

    /* Recursion terminates here.*/    if (ar1[i] > ar2[j] && (j == n-1 || ar1[i] <= ar2[j+1]))    {        /*ar1[i] is decided as median 2, now select the median 1           (element just before ar1[i] in merged array) to get the           average of both*/        if (ar2[j] > ar1[i-1] || i == 0)            return (ar1[i] + ar2[j])/2;        else            return (ar1[i] + ar1[i-1])/2;    }

    /*Search in left half of ar1[]*/    else if (ar1[i] > ar2[j] && j != n-1 && ar1[i] > ar2[j+1])        return getMedianRec(ar1, ar2, left, i-1, n);

    /*Search in right half of ar1[]*/    else /* ar1[i] is smaller than both ar2[j] and ar2[j+1]*/

Page 248: Data structures all in one

        return getMedianRec(ar1, ar2, i+1, right, n);}

/* Driver program to test above function */int main(){    int ar1[] = {1, 12, 15, 26, 38};    int ar2[] = {2, 13, 17, 30, 45};    int n1 = sizeof(ar1)/sizeof(ar1[0]);    int n2 = sizeof(ar2)/sizeof(ar2[0]);    if (n1 == n2)        printf("Median is %d", getMedian(ar1, ar2, n1));    else        printf("Doesn't work for arrays of unequal size");

    getchar();    return 0;}

Time Complexity: O(logn)Algorithmic Paradigm: Divide and Conquer

The above solutions can be optimized for the cases when all elements of one array are smaller than all elements of other array. For example, in method 3, we can change the getMedian() function to following so that these cases can be handled in O(1) time. Thanks to nutcracker for suggesting this optimization.

/* This function returns median of ar1[] and ar2[].   Assumptions in this function:   Both ar1[] and ar2[] are sorted arrays   Both have n elements */int getMedian(int ar1[], int ar2[], int n){   // If all elements of array 1 are smaller then   // median is average of last element of ar1 and   // first element of ar2   if (ar1[n-1] < ar2[0])     return (ar1[n-1]+ar2[0])/2;

   // If all elements of array 1 are smaller then   // median is average of first element of ar1 and   // last element of ar2   if (ar2[n-1] < ar1[0])     return (ar2[n-1]+ar1[0])/2;

   return getMedianRec(ar1, ar2, 0, n-1, n);}

References:http://en.wikipedia.org/wiki/Median

Page 249: Data structures all in one

http://ocw.alfaisal.edu/NR/rdonlyres/Electrical-Engineering-and-Computer-Science/6-046JFall-2005/30C68118-E436-4FE3-8C79-6BAFBB07D935/0/ps9sol.pdf ds3etph5wn

C Language | Set 1October 3, 2009

Following questions have been asked in GATE CS exam.

1. Consider the following three C functions :

[PI] int * g (void)

{

  int x = 10;

  return (&x);

}

[P2] int * g (void)

{

  int * px;

  *px = 10;

  return px;

}

[P3] int *g (void)

{

  int *px;

  px = (int *) malloc (sizeof(int));

  *px = 10;

  return px;

}

Which of the above three functions are likely to cause problems with pointers? (GATE 2001)

Page 250: Data structures all in one

(a) Only P3(b) Only P1 and P3(c) Only P1 and P2(d) P1, P2 and P3

Answer: (c)Eplaination: In P1, variable x is a local variable to g(), and g() returns address of this variable. x will vanish after g() has returned as x exists on stack. So, &x will become a dangling pointer.In P2, pointer variable px is being assigned a value without allocating memory to it.P3 works perfectly fine. Memory is allocated to pointer variable px using malloc(). So, px exists on heap, it’s existence will remain in memory even after return of g() as it is on heap.

2. The value of j at the end of the execution of the following C program. (GATE CS 2000)

int incr (int i)

{

   static int count = 0;

   count = count + i;

   return (count);

}

main ()

{

   int i,j;

   for (i = 0; i <=4; i++)

      j = incr(i);

}

(a) 10(b) 4

Page 251: Data structures all in one

(c) 6(d) 7

Answer (a)Eplaination: count is static variable in incr(). Statement static int count = 0 will assign count to 0 only in first call. Other calls to this function will take the old values of count.Count will become 0 after the call incr(0)Count will become 1 after the call incr(1)Count will become 3 after the call incr(2)Count will become 6 after the call incr(3)Count will become 10 after the call incr(4)

3. Consider the following C declaration

struct {

    short s [5]

    union {

         float y;

         long z;

    }u;

} t;

Assume that objects of the type short, float and long occupy 2 bytes, 4 bytes and 8 bytes, respectively. The memory requirement for variable t, ignoring alignmentconsiderations, is (GATE CS 2000)(a) 22 bytes(b) 14 bytes(c) 18 bytes(d) 10 bytes

Answer: (c)Explanation: Short array s[5] will take 10 bytes as size of short is 2

Page 252: Data structures all in one

bytes. Since u is a union, memory allocated to u will be max of float y(4 bytes) and long z(8 bytes). So, total size will be 18 bytes (10 + 8).

4. The number of tokens in the following C statement.

printf("i = %d, &i = %x", i, &i);

is (GATE 2000)(a) 3(b) 26(c) 10(d) 21

Answer (c)Explanation:In a C source program, the basic element recognized by the compiler is the “token.” A token is source-program text that the compiler does not break down into component elements.There are 6 types of C tokens : identifiers, keywords, constants, operators, string literals and other separators. There are total 10 tokens in the above printf statement.

5. The following C declarations

struct node

{

   int i;

   float j;

};

struct node *s[10] ;

define s to be (GATE CS 2000)

Page 253: Data structures all in one

(a) An array, each element of which is a pointer to a structure of type node(b) A structure of 2 fields, each field being a pointer to an array of 10 elements(c) A structure of 3 fields: an integer, a float, and an array of 10 elements(d) An array, each element of which is a structure of type node.

Answer: (a)

Compiler Theory | Set 1October 4, 2009

Following questions have been asked in GATE CS exam.

1. Which of the following derivations does a top-down parser use while parsing an input string? The input is assumed to be scanned in left to right order (GATE CS 2000).(a) Leftmost derivation(b) Leftmost derivation traced out in reverse(c) Rightmost derivation(d) Rightmost derivation traced out in reverse

Answer (a)

Top-down parsing (LL)In top down parsing, we just start with the start symbol and compare the right side of the different productions against the first piece of input to see which of the productions should be used.

A top down parser is called LL parser because it parses the input from Left to right, and constructs aLeftmost derivation of the sentence.

Algorithm (Top Down Parsing)

a) In the current string, choose leftmost nonterminal. b) Choose a production for the chosen nonterminal.

Page 254: Data structures all in one

c) In the string, replace the nonterminal by the right-hand-side of the rule. d) Repeat until no more nonterminals.

LL grammars are often classified by numbers, such as LL(1), LL(0) and so on. The number in the parenthesis tells the maximum number of terminals we may have to look at at a time to choose the right production at any point in the grammar.

The most common (and useful) kind of LL grammar is LL(1) where you can always choose the right production by looking at only the first terminal on the input at any given time. With LL(2) you have to look at two symbols, and so on. There exist grammars that are not LL(k) grammars for any fixed value of k at all, and they are sadly quite common.

Let us see an example of top down parsing for following grammar. Let input string be ax.

S -> Ax A -> a A -> b

An LL(1) parser starts with S and asks “which production should I attempt?” Naturally, it predicts the only alternative of S. From there it tries to match A by calling method A (in a recursive-descent parser). Lookahead a predicts production

A -> a

The parser matches a, returns to S and matches x. Done. The derivation tree is:

S / \ A x | a

Page 255: Data structures all in one

References:http://www.garshol.priv.no/download/text/bnf.htmlhttp://en.wikipedia.org/wiki/Top-down_parsinghttp://www.cs.wm.edu/~noonan/animations/lderive.htmlhttp://en.wikipedia.org/wiki/LL_parser

2. The process of assigning load addresses to the various parts of the program and adjusting the code and data in the program to reflect the assigned addresses is called (GATE CS 2001)a) Assemblyb) Parsingc) Relocationd) Symbol resolution

Answer: (c)Relocation is the process of replacing symbolic references or names of libraries with actual usable addresses in memory before running a program. It is typically done by the linker during compilation (at compile time), although it can be done at runtime by a relocating loader. Compilers or assemblers typically generate the executable with zero as the lower-most starting address. Before the execution of object code, these addresses should be adjusted so that they denote the correct runtime addresses.

Relocation is typically done in two steps:1. Each object code has various sections like code, data, .bss etc. To combine all the objects to a single executable, the linker merges all sections of similar type into a single section of that type. The linker then assigns runtime addresses to each section and each symbol. At this point, the code (functions) and data (global variables) will have unique runtime addresses.2. Each section refers to one or more symbols which should be modified so that they point to the correct runtime addresses.

References:http://en.wikipedia.org/wiki/Relocation_(computer_science)

Page 256: Data structures all in one

3. Which of the following statements is false? (GATE CS 2001)a) An unambiguous grammar has same leftmost and rightmost derivationb) An LL(1) parser is a top-down parserc) LALR is more powerful than SLRd) An ambiguous grammar can never be LR(k) for any k

Answer: (a) If a grammar has more than one leftmost (or rightmost) derivation for a single sentential form, the grammar is ambiguous. The leftmost and rightmost derivations for a sentential form may differ, even in an unambiguous grammar

4. Which of the following grammar rules violate the requirements of an operator grammar? P, Q, R are nonterminals, and r,s,t are terminals (GATE CS 2004).(i) P -> QR(ii) P -> QsR(iii) P -> (iV) P -> QtRr

a) (i) onlyb) (i) and (iii) onlyc) (ii) and (iii) onlyd) (iii) and (iv) only

Answer: (b)Explanation:An operator precedence parser is a bottom-up parser that interprets an operator-precedence grammar. For example, most calculators use operator precedence parsers to convert from the human-readable infix notation with order of operations format into an internally optimized computer-readable format like Reverse Polish notation (RPN).

An operator precedence grammar is a kind of context-free grammar that can be parsed with an operator-precedence parser. It has the

Page 257: Data structures all in one

property that no production has either an empty ( ) right-hand side or two adjacent nonterminals in its right-hand side. These properties allow the terminals of the grammar to be described by a precedence relation, and the a parser that exploits that relation is considerably simpler than more general-purpose parsers such as LALR parsers.

References:http://en.wikipedia.org/wiki/Operator-precedence_grammarhttp://en.wikipedia.org/wiki/Operator-precedence_parser

5. Consider the grammar with the following translation rules and E as the start symbol.E -> E1 #T {E.value = E1.value * T.value}| T {E.value = T.value}T -> T1 & F {T.value = T1.value + F.value}|F {T.value= F.value}F -> num {F.value = num.value}

Compute E.value for the root of the parse tree for the expression:2 # 3 & 5 # 6 &4. (GATE CS 2004)a) 200b) 180c) 160d) 40

Answer: (c)Explanation:We can calculate the value by constructing the parse tree for the expression 2 # 3 & 5 # 6 &4.

Alternatively, we can calculate by considering following precedence and associativity rules.Precedence in a grammar is enforced by making sure that a production rule with higher precedence operator will never produce an expression with operator with lower precedence.In the given grammar ‘&’ has higher precedence than ‘#’.

Page 258: Data structures all in one

Left associativity for operator * in a grammar is enforced by making sure that for a production rule like S -> S1 * S2 in grammar, S2 should never produce an expression with *. On the other hand, to ensure right associativity, S1 should never produce an expression with *.In the given grammar, both ‘#’ and & are left-associative.

So expression 2 # 3 & 5 # 6 &4 will become((2 # (3 & 5)) # (6 & 4))Let us apply translation rules, we get((2 * (3 + 5)) * (6 + 4)) = 160.

Data Structures and Algorithms | Set 1October 6, 2009

Following questions have been asked in GATE CS exam

1. Let LASTPOST, LASTIN and LASTPRE denote the last vertex visited in a postorder, inorder and preorder traversal. Respectively, of a complete binary tree. Which of the following is always true? (GATE CS 2000)(a) LASTIN = LASTPOST(b) LASTIN = LASTPRE(c) LASTPRE = LASTPOST(d) None of the above

Answer (d)

It is given that the given tree is complete binary tree. For a complete binary tree, the last visited node will always be same for inorder and preorder traversal. None of the above is true even for a complete binary tree.

The option (a) is incorrect because the last node visited in Inorder traversal is right child and last node visited in Postorder traversal is root.

The option (c) is incorrect because the last node visited in Preorder traversal is right child and last node visited in Postorder traversal is root.

Page 259: Data structures all in one

For option (b), see the following counter example. Thanks to Hunaif Muhammed for providing the correct explanation.

1 / \ 2 3 / \ /4 5 6

Inorder traversal is 4 2 5 1 6 3Preorder traversal is 1 2 4 5 3 6

2. The most appropriate matching for the following pairs

X: depth first search 1: heapY: breadth-first search 2: queueZ: sorting 3: stack

is (GATE CS 2000):(a) X—1 Y—2 Z-3(b) X—3 Y—1 Z-2(c) X—3 Y—2 Z-1(d) X—2 Y—3 Z-1

Answer: (c)Stack is used for Depth first SearchQueue is used for Breadth First SearchHeap is used for sorting

3. Consider the following nested representation of binary trees: (X Y Z) indicates Y and Z are the left and right sub stress, respectively, of node X. Note that Y and Z may be NULL, or further nested. Which of the following represents a valid binary tree?

Page 260: Data structures all in one

(a) (1 2 (4 5 6 7))(b) (1 (2 3 4) 5 6) 7)(c) (1 (2 3 4)(5 6 7))(d) (1 (2 3 NULL) (4 5))

Answer (c)

4. Let s be a sorted array of n integers. Let t(n) denote the time taken for the most efficient algorithm to determined if there are two elements with sum less than 1000 in s. which of the following statements is true? (GATE CS 2000)a) t (n) is 0 (1)b) n < t (n) < nc) n log 2 n < t (n) < d) t (n) = 

Answer (a)Let array be sorted in ascending order, if sum of first two elements is less than 1000 then there are  two elements with sum less than 1000 otherwise not. For array sorted in descending order we need to check last two elements. For an array data structure, number of operations are fixed in both the cases and not dependent on n, complexity is O(1)

5. B+ trees are preferred to binary trees in databases because (GATE CS 2000)(a) Disk capacities are greater than memory capacities(b) Disk access is much slower than memory access(c) Disk data transfer rates are much less than memory data transfer rates(d) Disks are more reliable than memory

Answer (b)Disk access is slow and  B+ Tree   provide search in less number of disk hits. This is primarily because unlike binary seach trees, B+ trees have very high fanout (typically on the order of 100 or more), which

Page 261: Data structures all in one

reduces the number of I/O operations required to find an element in the tree.

C Language | Set 2October 7, 2009

Following questions have been asked in GATE CS exam.

1. Consider the following C program segment:

char p[20];

char *s = "string";

int length = strlen(s);

int i;

for (i = 0; i < length; i++)

     p[i] = s[length — i];

printf("%s",p);

The output of the program is (GATE CS 2004)a) gnirtsb) gnirtc) stringd) no output is printed

Answer(d)Let us consider below line inside the for loopp[i] = s[length — i];For i = 0, p[i] will be s[6 — 0] and s[6] is ‘\0′So p[0] becomes ‘\0’. It doesn’t matter what comes in p[1], p[2]….. as P[0] will not change for i >0. Nothing is printed if we print a string with first character ‘\0′

2. Consider the following C function

void swap (int a, int b)

Page 262: Data structures all in one

{

   int temp;

   temp = a;

   a = b;

   b = temp;

}

In order to exchange the values of two variables x and y. (GATE CS 2004)

a) call swap (x, y)b) call swap (&x, &y)c) swap (x,y) cannot be used as it does not return any valued) swap (x,y) cannot be used as the parameters are passed by value

Answer(d)Why a, b and c are incorrect?a) call swap (x, y) will not cause any effect on x and y as parameters are passed by value.b) call swap (&x, &y) will no work as function swap() expects values not addresses (or pointers).c) swap (x, y) cannot be used but reason given is not correct.

3. Consider the following C function:

int f(int n)

{

   static int i = 1;

   if (n >= 5)

      return n;

   n = n+i;

   i++;

   return f(n);

Page 263: Data structures all in one

}

The value returned by f(1) is (GATE CS 2004)a) 5b) 6c) 7d) 8

Answer (c)Since i is static, first line of f() is executed only once.

Execution of f(1) i = 1 n = 2 i = 2 Call f(2) i = 2 n = 4 i = 3 Call f(4) i = 3 n = 7 i = 4 Call f(7) since n >= 5 return n(7)

4. Consider the following program fragment for reversing the digits in a given integer to obtain a new integer. Let n = D1D2…Dm

int n, rev;

rev = 0;

while (n > 0)

{

   rev = rev*10 + n%10;

Page 264: Data structures all in one

   n = n/10;

}

The loop invariant condition at the end of the ith iteration is:(GATE CS 2004)

a) n = D1D2….Dm-i and rev = DmDm-1…Dm-i+1b) n = Dm-i+1…Dm-1Dm and rev = Dm-1….D2D1c) n   revd) n = D1D2….Dm and rev = DmDm-1…D2D1

Answer (a)

5. Consider the following C program

main()

{

   int x, y, m, n;

   scanf ("%d %d", &x, &y);

   /* x > 0 and y > 0 */

   m = x; n = y;

   while (m != n)

   {

      if(m>n)

         m = m - n;

      else

         n = n - m;

   }

   printf("%d", n);

}

Page 265: Data structures all in one

The program computes (GATE CS 2004)a) x + y using repeated subtractionb) x mod y using repeated subtractionc) the greatest common divisor of x and yd) the least common multiple of x and y

Answer(c)This is an implementation of Euclid’s algorithm to find GCD

Write a function to get the intersection point of two Linked Lists.October 10, 2009

There are two singly linked lists in a system. By some programming error the end node of one of the

linked list got linked into the second list, forming a inverted Y shaped list. Write a program to get the

point where two linked list merge.

Above diagram shows an example with two linked list having 15 as intersection point.

Method 1(Simply use two loops)

Use 2 nested for loops. Outer loop will be for each node of the 1st list and inner loop will be for 2nd

list. In the inner loop, check if any of nodes of 2nd list is same as the current node of first linked list.

Time complexity of this method will be O(mn) where m and n are the number of nodes in two lists.

Method 2 (Mark Visited Nodes)

This solution requires modifications to basic linked list data structure. Have a visited flag with each

node. Traverse the first linked list and keep marking visited nodes. Now traverse second linked list, If

you see a visited node again then there is an intersection point, return the intersecting node. This

solution works in O(m+n) but requires additional information with each node. A variation of this

Page 266: Data structures all in one

solution that doesn’t require modification to basic data structure can be implemented using hash.

Traverse the first linked list and store the addresses of visited nodes in a hash. Now traverse the

second linked list and if you see an address that already exists in hash then return the intersecting

node.

Method 3(Using difference of node counts)

1) Get count of the nodes in first list, let count be c1.

2) Get count of the nodes in second list, let count be c2.

3) Get the difference of counts d = abs(c1 – c2)

4) Now traverse the bigger list from the first node till d nodes so that from here onwards both the lists

have equal no of nodes.

5) Then we can traverse both the lists in parallel till we come across a common node. (Note that

getting a common node is done by comparing the address of the nodes)

#include<stdio.h>

#include<stdlib.h>

/* Link list node */

struct node

{

  int data;

  struct node* next;

};

/* Function to get the counts of node in a linked list */

int getCount(struct node* head);

/* function to get the intersection point of two linked

   lists head1 and head2 where head1 has d more nodes than

   head2 */

int _getIntesectionNode(int d, struct node* head1, struct node* head2);

/* function to get the intersection point of two linked

   lists head1 and head2 */

Page 267: Data structures all in one

int getIntesectionNode(struct node* head1, struct node* head2)

{

  int c1 = getCount(head1);

  int c2 = getCount(head2);

  int d;

  if(c1 > c2)

  {

    d = c1 - c2;

    return _getIntesectionNode(d, head1, head2);

  }

  else

  {

    d = c2 - c1;

    return _getIntesectionNode(d, head2, head1);

  }

}

/* function to get the intersection point of two linked

   lists head1 and head2 where head1 has d more nodes than

   head2 */

int _getIntesectionNode(int d, struct node* head1, struct node* head2)

{

  int i;

  struct node* current1 = head1;

  struct node* current2 = head2;

  for(i = 0; i < d; i++)

  {

Page 268: Data structures all in one

    if(current1 == NULL)

    {  return -1; }

    current1 = current1->next;

  }

  while(current1 !=  NULL && current2 != NULL)

  {

    if(current1 == current2)

      return current1->data;

    current1= current1->next;

    current2= current2->next;

  }

  return -1;

}

/* Takes head pointer of the linked list and

   returns the count of nodes in the list */

int getCount(struct node* head)

{

  struct node* current = head;

  int count = 0;

  while (current != NULL)

  {

    count++;

    current = current->next;

  }

Page 269: Data structures all in one

  return count;

}

/* IGNORE THE BELOW LINES OF CODE. THESE LINES

   ARE JUST TO QUICKLY TEST THE ABOVE FUNCTION */

int main()

{

  /*

    Create two linked lists

    1st 3->6->9->15->30

    2nd 10->15->30

    15 is the intersection point

  */

  struct node* newNode;

  struct node* head1 =

            (struct node*) malloc(sizeof(struct node));

  head1->data  = 10;

  struct node* head2 =

            (struct node*) malloc(sizeof(struct node));

  head2->data  = 3;

  newNode = (struct node*) malloc (sizeof(struct node));

  newNode->data = 6;

  head2->next = newNode;

Page 270: Data structures all in one

  newNode = (struct node*) malloc (sizeof(struct node));

  newNode->data = 9;

  head2->next->next = newNode;

  newNode = (struct node*) malloc (sizeof(struct node));

  newNode->data = 15;

  head1->next = newNode;

  head2->next->next->next  = newNode;

  newNode = (struct node*) malloc (sizeof(struct node));

  newNode->data = 30;

  head1->next->next= newNode;

  head1->next->next->next = NULL;

  printf("\n The node of intersection is %d \n",

          getIntesectionNode(head1, head2));

  getchar();

}

Time Complexity: O(m+n)

Auxiliary Space: O(1)

Method 4(Make circle in first list)

Thanks to Saravanan Man for providing below solution.

1. Traverse the first linked list(count the elements) and make a circular linked list. (Remember last

node so that we can break the circle later on).

2. Now view the problem as find the loop in the second linked list. So the problem is solved.

3. Since we already know the length of the loop(size of first linked list) we can traverse those many

number of nodes in second list, and then start another pointer from the beginning of second list. we

have to traverse until they are equal, and that is the required intersection point.

4. remove the circle from the linked list.

Page 271: Data structures all in one

Time Complexity: O(m+n)

Auxiliary Space: O(1)

Method 5 (Reverse the first list and make equations)

Thanks to Saravanan Mani for providing this method.

1) Let X be the length of the first linked list until intersection point. Let Y be the length of the second linked list until the intersection point. Let Z be the length of the linked list from intersection point to End of the linked list including the intersection node. We Have X + Z = C1; Y + Z = C2;2) Reverse first linked list.3) Traverse Second linked list. Let C3 be the length of second list - 1. Now we have X + Y = C3 We have 3 linear equations. By solving them, we get X = (C1 + C3 – C2)/2; Y = (C2 + C3 – C1)/2; Z = (C1 + C2 – C3)/2; WE GOT THE INTERSECTION POINT.4) Reverse first linked list.

Advantage: No Comparison of pointers.

Disadvantage : Modifying linked list(Reversing list).

Time complexity: O(m+n)

Auxiliary Space: O(1)

Method 6 (Traverse both lists and compare addresses of last nodes) This method is only to

detect if there is an intersection point or not. (Thanks to NeoTheSaviour for suggesting this)

1) Traverse the list 1, store the last node address

Page 272: Data structures all in one

2) Traverse the list 2, store the last node address.3) If nodes stored in 1 and 2 are same then they are intersecting.

Time complexity of this method is O(m+n) and used Auxiliary space is O(1)

Find the two non-repeating elements in an array of repeating elementsOctober 21, 2009

Asked by SGGiven an array in which all numbers except two are repeated once. (i.e. we have 2n+2 numbers and n numbers are occurring twice and remaining two have occurred once). Find those two numbers in the most efficient way.

Method 1(Use Sorting)First sort all the elements. In the sorted array, by comparing adjacent elements we can easily get the non-repeating elements. Time complexity of this method is O(nLogn)

Method 2(Use XOR)Let x and y be the non-repeating elements we are looking for and arr[] be the input array. First calculate the XOR of all the array elements.

xor = arr[0]^arr[1]^arr[2].....arr[n-1]

All the bits that are set in xor will be set in one non-repeating element (x or y) and not in other. So if we take any set bit of xor and divide the elements of the array in two sets – one set of elements with same bit set and other set with same bit not set. By doing so, we will get x in one set and y in another set. Now if we do XOR of all the elements in first set, we will get first non-repeating element, and by doing same in other set we will get the second non-repeating element.

Let us see an example. arr[] = {2, 4, 7, 9, 2, 4}1) Get the XOR of all the elements. xor = 2^4^7^9^2^4 = 14 (1110)

Page 273: Data structures all in one

2) Get a number which has only one set bit of the xor. Since we can easily get the rightmost set bit, let us use it. set_bit_no = xor & ~(xor-1) = (1110) & ~(1101) = 0010 Now set_bit_no will have only set as rightmost set bit of xor.3) Now divide the elements in two sets and do xor of elements in each set, and we get the non-repeating elements 7 and 9. Please see implementation for this step.

Implementation:

#include <stdio.h>

#include <stdlib.h>

/* This finction sets the values of *x and *y to nonr-epeating

 elements in an array arr[] of size n*/

void get2NonRepeatingNos(int arr[], int n, int *x, int *y)

{

  int xor = arr[0]; /* Will hold xor of all elements */

  int set_bit_no;  /* Will have only single set bit of xor */

  int i;

  *x = 0;

  *y = 0;

  /* Get the xor of all elements */

  for(i = 1; i < n; i++)

   xor ^= arr[i];

Page 274: Data structures all in one

  /* Get the rightmost set bit in set_bit_no */

  set_bit_no = xor & ~(xor-1);

  /* Now divide elements in two sets by comparing rightmost set

   bit of xor with bit at same position in each element. */

  for(i = 0; i < n; i++)

  {

    if(arr[i] & set_bit_no)

     *x = *x ^ arr[i]; /*XOR of first set */

    else

     *y = *y ^ arr[i]; /*XOR of second set*/

  }

}

/* Driver program to test above function */

int main()

{

  int arr[] = {2, 3, 7, 9, 11, 2, 3, 11};

  int *x = (int *)malloc(sizeof(int));

  int *y = (int *)malloc(sizeof(int));

  get2NonRepeatingNos(arr, 8, x, y);

  printf("The non-repeating elements are %d and %d", *x, *y);

  getchar();

}

Time Complexity: O(n)Auxiliary Space: O(1)

Find the two non-repeating elements in an array of repeating elements

Page 275: Data structures all in one

October 21, 2009

Asked by SGGiven an array in which all numbers except two are repeated once. (i.e. we have 2n+2 numbers and n numbers are occurring twice and remaining two have occurred once). Find those two numbers in the most efficient way.

Method 1(Use Sorting)First sort all the elements. In the sorted array, by comparing adjacent elements we can easily get the non-repeating elements. Time complexity of this method is O(nLogn)

Method 2(Use XOR)Let x and y be the non-repeating elements we are looking for and arr[] be the input array. First calculate the XOR of all the array elements.

xor = arr[0]^arr[1]^arr[2].....arr[n-1]

All the bits that are set in xor will be set in one non-repeating element (x or y) and not in other. So if we take any set bit of xor and divide the elements of the array in two sets – one set of elements with same bit set and other set with same bit not set. By doing so, we will get x in one set and y in another set. Now if we do XOR of all the elements in first set, we will get first non-repeating element, and by doing same in other set we will get the second non-repeating element.

Let us see an example. arr[] = {2, 4, 7, 9, 2, 4}1) Get the XOR of all the elements. xor = 2^4^7^9^2^4 = 14 (1110)2) Get a number which has only one set bit of the xor. Since we can easily get the rightmost set bit, let us use it. set_bit_no = xor & ~(xor-1) = (1110) & ~(1101) = 0010 Now set_bit_no will have only set as rightmost set bit of xor.

Page 276: Data structures all in one

3) Now divide the elements in two sets and do xor of elements in each set, and we get the non-repeating elements 7 and 9. Please see implementation for this step.

Implementation:

#include <stdio.h>

#include <stdlib.h>

/* This finction sets the values of *x and *y to nonr-epeating

 elements in an array arr[] of size n*/

void get2NonRepeatingNos(int arr[], int n, int *x, int *y)

{

  int xor = arr[0]; /* Will hold xor of all elements */

  int set_bit_no;  /* Will have only single set bit of xor */

  int i;

  *x = 0;

  *y = 0;

  /* Get the xor of all elements */

  for(i = 1; i < n; i++)

   xor ^= arr[i];

  /* Get the rightmost set bit in set_bit_no */

  set_bit_no = xor & ~(xor-1);

  /* Now divide elements in two sets by comparing rightmost set

   bit of xor with bit at same position in each element. */

Page 277: Data structures all in one

  for(i = 0; i < n; i++)

  {

    if(arr[i] & set_bit_no)

     *x = *x ^ arr[i]; /*XOR of first set */

    else

     *y = *y ^ arr[i]; /*XOR of second set*/

  }

}

/* Driver program to test above function */

int main()

{

  int arr[] = {2, 3, 7, 9, 11, 2, 3, 11};

  int *x = (int *)malloc(sizeof(int));

  int *y = (int *)malloc(sizeof(int));

  get2NonRepeatingNos(arr, 8, x, y);

  printf("The non-repeating elements are %d and %d", *x, *y);

  getchar();

}

Time Complexity: O(n)Auxiliary Space: O(1)

Write a program to reverse an arrayOctober 30, 2009

Iterative way:1) Initialize start and end indexes. start = 0, end = n-12) In a loop, swap arr[start] with arr[end] and change start and end as follows.start = start +1; end = end – 1

/* Function to reverse arr[] from start to end*/

Page 278: Data structures all in one

void rvereseArray(int arr[], int start, int end)

{

  int temp;

  while(start < end)

  {

    temp = arr[start];

    arr[start] = arr[end];

    arr[end] = temp;

    start++;

    end--;

  }

}

/* Utility that prints out an array on a line */

void printArray(int arr[], int size)

{

  int i;

  for (i=0; i < size; i++)

    printf("%d ", arr[i]);

  printf("\n");

}

/* Driver function to test above functions */

int main()

{

  int arr[] = {1, 2, 3, 4, 5, 6};

  printArray(arr, 6);

Page 279: Data structures all in one

  rvereseArray(arr, 0, 5);

  printf("Reversed array is \n");

  printArray(arr, 6);

  getchar();

  return 0;

}

Time Complexity: O(n)

Recursive Way:1) Initialize start and end indexesstart = 0, end = n-12) Swap arr[start] with arr[end]3) Recursively call reverse for rest of the array.

/* Function to reverse arr[] from start to end*/

void rvereseArray(int arr[], int start, int end)

{

   int temp;

   if(start >= end)

     return;

   temp = arr[start];

   arr[start] = arr[end];

   arr[end] = temp;

   rvereseArray(arr, start+1, end-1);

}

/* Utility that prints out an array on a line */

void printArray(int arr[], int size)

{

  int i;

  for (i=0; i < size; i++)

Page 280: Data structures all in one

    printf("%d ", arr[i]);

  printf("\n");

}

/* Driver function to test above functions */

int main()

{

  int arr[] = {1, 2, 3, 4, 5};

  printArray(arr, 5);

  rvereseArray(arr, 0, 4);

  printf("Reversed array is \n");

  printArray(arr, 5);

  getchar();

  return 0;

}

Time Complexity: O(n)

Rotate bits of a numberOctober 31, 2009

Bit Rotation: A rotation (or circular shift) is an operation similar to shift except that the bits that fall off at one end are put back to the other end.

In left rotation, the bits that fall off at left end are put back at right end.

In right rotation, the bits that fall off at right end are put back at left end.

Example:Let n is stored using 8 bits. Left rotation of n = 11100101 by 3 makes n = 00101111 (Left shifted by 3 and first 3 bits are put back in last ). If n is stored using 16 bits or 32 bits then left rotation of n (000…

Page 281: Data structures all in one

11100101) becomes 00..0011100101000.Right rotation of n = 11100101 by 3 makes n = 10111100 (Right shifted by 3 and last 3 bits are put back in first ) if n is stored using 8 bits. If n is stored using 16 bits or 32 bits then right rotation of n (000…11100101) by 3 becomes 101000..0011100.

#include<stdio.h>

#define INT_BITS 32

/*Function to left rotate n by d bits*/

int leftRotate(int n, unsigned int d)

{

   /* In n<<d, last d bits are 0. To put first 3 bits of n at

     last, do bitwise or of n<<d with n >>(INT_BITS - d) */

   return (n << d)|(n >> (INT_BITS - d));

}

/*Function to right rotate n by d bits*/

int rightRotate(int n, unsigned int d)

{

   /* In n>>d, first d bits are 0. To put last 3 bits of at

     first, do bitwise or of n>>d with n <<(INT_BITS - d) */

   return (n >> d)|(n << (INT_BITS - d));

}

/* Driver program to test above functions */

int main()

{

  int n = 16;

  int d = 2;

  printf("Left Rotation of %d by %d is ", n, d);

Page 282: Data structures all in one

  printf("%d", leftRotate(n, d));

  printf("\nRight Rotation of %d by %d is ", n, d);

  printf("%d", rightRotate(n, d));

  getchar();

}

Compute the minimum or maximum of two integers without branchingNovember 1, 2009

On some rare machines where branching is expensive, the below obvious approach to find minimum can be slow as it uses branching.

/* The obvious approach to find minimum (involves branching) */

int min(int x, int y)

{

  return (x < y) ? x : y

}

Below are the methods to get minimum(or maximum) without using branching. Typically, the obvious approach is best, though.

Method 1(Use XOR and comparison operator)

Minimum of x and y will be

y ^ ((x ^ y) & -(x < y))

It works because if x < y, then -(x < y) will be all ones, so r = y ^ (x ^ y) & ~0 = y ^ x ^ y = x. Otherwise, if x >= y, then -(x < y) will be all zeros, so r = y ^ ((x ^ y) & 0) = y. On some machines, evaluating (x < y) as 0 or 1 requires a branch instruction, so there may be no advantage.

To find the maximum, use

x ^ ((x ^ y) & -(x < y));#include<stdio.h>

Page 283: Data structures all in one

/*Function to find minimum of x and y*/

int min(int x, int y)

{

  return y ^ ((x ^ y) & -(x < y));

}

/*Function to find maximum of x and y*/

int max(int x, int y)

{

  return x ^ ((x ^ y) & -(x < y));

}

/* Driver program to test above functions */

int main()

{

  int x = 15;

  int y = 6;

  printf("Minimum of %d and %d is ", x, y);

  printf("%d", min(x, y));

  printf("\nMaximum of %d and %d is ", x, y);

  printf("%d", max(x, y));

  getchar();

}

Method 2(Use subtraction and shift)If we know that

INT_MIN <= (x - y) <= INT_MAX

, then we can use the following, which are faster because (x - y) only needs to be evaluated once.

Page 284: Data structures all in one

Minimum of x and y will be

y + ((x - y) & ((x - y) >>(sizeof(int) * CHAR_BIT - 1)))

This method shifts the subtraction of x and y by 31 (if size of integer is 32). If (x-y) is smaller than 0, then (x -y)>>31 will be 1. If (x-y) is greater than or equal to 0, then (x -y)>>31 will be 0.So if x >= y, we get minimum as y + (x-y)&0 which is y.If x < y, we get minimum as y + (x-y)&1 which is x.

Similarly, to find the maximum use

x - ((x - y) & ((x - y) >> (sizeof(int) * CHAR_BIT - 1)))#include<stdio.h>

#define CHAR_BIT 8

/*Function to find minimum of x and y*/

int min(int x, int y)

{

  return y + ((x - y) & ((x - y) >>

            (sizeof(int) * CHAR_BIT - 1)));

}

/*Function to find maximum of x and y*/

int max(int x, int y)

{

  return x - ((x - y) & ((x - y) >>

            (sizeof(int) * CHAR_BIT - 1)));

}

/* Driver program to test above functions */

Page 285: Data structures all in one

int main()

{

  int x = 15;

  int y = 6;

  printf("Minimum of %d and %d is ", x, y);

  printf("%d", min(x, y));

  printf("\nMaximum of %d and %d is ", x, y);

  printf("%d", max(x, y));

  getchar();

}

Note that the 1989 ANSI C specification doesn't specify the result of signed right-shift, so above method is not portable. If exceptions are thrown on overflows, then the values of x and y should be unsigned or cast to unsigned for the subtractions to avoid unnecessarily throwing an exception, however the right-shift needs a signed operand to produce all one bits when negative, so cast to signed there.

Source:http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax

Level Order Tree TraversalNovember 7, 2009

Level order traversal of a tree is breadth first traversal for the tree.

Example Tree

Level order traversal of the above tree is 1 2 3 4 5

Page 286: Data structures all in one

METHOD 1 (Use function to print a given level)

Algorithm:There are basically two functions in this method. One is to print all nodes at a given level (printGivenLevel), and other is to print level order traversal of the tree (printLevelorder). printLevelorder makes use of printGivenLevel to print nodes at all levels one by one starting from root.

/*Function to print level order traversal of tree*/printLevelorder(tree)for d = 1 to height(tree) printGivenLevel(tree, d);

/*Function to print all nodes at a given level*/printGivenLevel(tree, level)if tree is NULL then return;if level is 1, then print(tree->data);else if level greater than 1, then printGivenLevel(tree->left, level-1); printGivenLevel(tree->right, level-1);

Implementation:

#include <stdio.h>

#include <stdlib.h>

/* A binary tree node has data, pointer to left child

   and a pointer to right child */

struct node

{

    int data;

    struct node* left;

Page 287: Data structures all in one

    struct node* right;

};

/*Function protoypes*/

void printGivenLevel(struct node* root, int level);

int height(struct node* node);

struct node* newNode(int data);

/* Function to print level order traversal a tree*/

void printLevelOrder(struct node* root)

{

  int h = height(root);

  int i;

  for(i=1; i<=h; i++)

    printGivenLevel(root, i);

}

/* Print nodes at a given level */

void printGivenLevel(struct node* root, int level)

{

  if(root == NULL)

    return;

  if(level == 1)

    printf("%d ", root->data);

  else if (level > 1)

  {

    printGivenLevel(root->left, level-1);

    printGivenLevel(root->right, level-1);

  }

Page 288: Data structures all in one

}

/* Compute the "height" of a tree -- the number of

    nodes along the longest path from the root node

    down to the farthest leaf node.*/

int height(struct node* node)

{

   if (node==NULL)

       return 0;

   else

   {

     /* compute the height of each subtree */

     int lheight = height(node->left);

     int rheight = height(node->right);

     /* use the larger one */

     if (lheight > rheight)

         return(lheight+1);

     else return(rheight+1);

   }

}

/* Helper function that allocates a new node with the

   given data and NULL left and right pointers. */

struct node* newNode(int data)

{

  struct node* node = (struct node*)

                       malloc(sizeof(struct node));

  node->data = data;

Page 289: Data structures all in one

  node->left = NULL;

  node->right = NULL;

  return(node);

}

/* Driver program to test above functions*/

int main()

{

  struct node *root = newNode(1);

  root->left        = newNode(2);

  root->right       = newNode(3);

  root->left->left  = newNode(4);

  root->left->right = newNode(5);

  printf("Level Order traversal of binary tree is \n");

  printLevelOrder(root);

  getchar();

  return 0;

}

Time Complexity: O(n^2) in worst case. For a skewed tree, printGivenLevel() takes O(n) time where n is the number of nodes in the skewed tree. So time complexity of printLevelOrder() is O(n) + O(n-1) + O(n-2) + .. + O(1) which is O(n^2).

Page 290: Data structures all in one

METHOD 2 (Use Queue)

Algorithm:For each node, first the node is visited and then it’s child nodes are put in a FIFO queue.

printLevelorder(tree)1) Create an empty queue q2) temp_node = root /*start from root*/3) Loop while temp_node is not NULL a) print temp_node->data. b) Enqueue temp_node’s children (first left then right children) to q c) Dequeue a node from q and assign it’s value to temp_node

Implementation:Here is a simple implementation of the above algorithm. Queue is implemented using an array with maximum size of 500. We can implement queue as linked list also.

#include <stdio.h>

#include <stdlib.h>

#define MAX_Q_SIZE 500

/* A binary tree node has data, pointer to left child

   and a pointer to right child */

struct node

{

    int data;

    struct node* left;

    struct node* right;

};

Page 291: Data structures all in one

/* frunction prototypes */

struct node** createQueue(int *, int *);

void enQueue(struct node **, int *, struct node *);

struct node *deQueue(struct node **, int *);

/* Given a binary tree, print its nodes in level order

   using array for implementing queue */

void printLevelOrder(struct node* root)

{

  int rear, front;

  struct node **queue = createQueue(&front, &rear);

  struct node *temp_node = root;

  while(temp_node)

  {

    printf("%d ", temp_node->data);

    /*Enqueue left child */

    if(temp_node->left)

      enQueue(queue, &rear, temp_node->left);

    /*Enqueue right child */

    if(temp_node->right)

      enQueue(queue, &rear, temp_node->right);

    /*Dequeue node and make it temp_node*/

    temp_node = deQueue(queue, &front);

  }

}

Page 292: Data structures all in one

/*UTILITY FUNCTIONS*/

struct node** createQueue(int *front, int *rear)

{

  struct node **queue =

   (struct node **)malloc(sizeof(struct node*)*MAX_Q_SIZE);

  *front = *rear = 0;

  return queue;

}

void enQueue(struct node **queue, int *rear, struct node *new_node)

{

  queue[*rear] = new_node;

  (*rear)++;

}

struct node *deQueue(struct node **queue, int *front)

{

  (*front)++;

  return queue[*front - 1];

}

/* Helper function that allocates a new node with the

   given data and NULL left and right pointers. */

struct node* newNode(int data)

{

  struct node* node = (struct node*)

                       malloc(sizeof(struct node));

Page 293: Data structures all in one

  node->data = data;

  node->left = NULL;

  node->right = NULL;

  return(node);

}

/* Driver program to test above functions*/

int main()

{

  struct node *root = newNode(1);

  root->left        = newNode(2);

  root->right       = newNode(3);

  root->left->left  = newNode(4);

  root->left->right = newNode(5);

  printf("Level Order traversal of binary tree is \n");

  printLevelOrder(root);

  getchar();

  return 0;

}

Time Complexity: O(n) where n is number of nodes in the binary tree

References:http://en.wikipedia.org/wiki/Breadth-first_traversal

Program to count leaf nodes in a binary treeNovember 7, 2009

A node is a leaf node if both left and right child nodes of it are NULL.

Page 294: Data structures all in one

Here is an algorithm to get the leaf node count.

getLeafCount(node)1) If node is NULL then return 0.2) Else If left and right child nodes are NULL return 1.3) Else recursively calculate leaf count of the tree using below formula. Leaf count of a tree = Leaf count of left subtree + Leaf count of right subtree

Example Tree

Leaf count for the above tree is 3.

Implementation:

#include <stdio.h>

#include <stdlib.h>

/* A binary tree node has data, pointer to left child

   and a pointer to right child */

struct node

{

    int data;

    struct node* left;

Page 295: Data structures all in one

    struct node* right;

};

/* Function to get the count of leaf nodes in a binary tree*/

unsigned int getLeafCount(struct node* node)

{

  if(node == NULL)

    return 0;

  if(node->left == NULL && node->right==NULL)

    return 1;

  else

    return getLeafCount(node->left)+

           getLeafCount(node->right);

}

/* Helper function that allocates a new node with the

   given data and NULL left and right pointers. */

struct node* newNode(int data)

{

  struct node* node = (struct node*)

                       malloc(sizeof(struct node));

  node->data = data;

  node->left = NULL;

  node->right = NULL;

  return(node);

}

/*Driver program to test above functions*/

Page 296: Data structures all in one

int main()

{

  /*create a tree*/

  struct node *root = newNode(1);

  root->left        = newNode(2);

  root->right       = newNode(3);

  root->left->left  = newNode(4);

  root->left->right = newNode(5);

  /*get leaf count of the above created tree*/

  printf("Leaf count of the tree is %d", getLeafCount(root));

  getchar();

  return 0;

}

Time & Space Complexities: Since this program is similar to traversal of tree, time and space complexities will be same as Tree traversal (Please see our Tree Traversal post for details)

Program for array rotationNovember 10, 2009

Write a function rotate(ar[], d, n) that rotates arr[] of size n by d elements.

Rotation of the above array by 2 will make array

METHOD 1 (Use temp array)

Page 297: Data structures all in one

Input arr[] = [1, 2, 3, 4, 5, 6, 7], d = 2, n =71) Store d elements in a temp array temp[] = [1, 2]2) Shift rest of the arr[] arr[] = [3, 4, 5, 6, 7, 6, 7]3) Store back the d elements arr[] = [3, 4, 5, 6, 7, 1, 2]

Time complexity O(n)Auxiliary Space: O(d)

METHOD 2 (Rotate one by one)

leftRotate(arr[], d, n)start For i = 0 to i < d Left rotate all elements of arr[] by oneend

To rotate by one, store arr[0] in a temporary variable temp, move arr[1] to arr[0], arr[2] to arr[1] …and finally temp to arr[n-1]

Let us take the same example arr[] = [1, 2, 3, 4, 5, 6, 7], d = 2Rotate arr[] by one 2 timesWe get [2, 3, 4, 5, 6, 7, 1] after first rotation and [ 3, 4, 5, 6, 7, 1, 2] after second rotation.

/*Function to left Rotate arr[] of size n by 1*/

void leftRotatebyOne(int arr[], int n);

/*Function to left rotate arr[] of size n by d*/

void leftRotate(int arr[], int d, int n)

{

  int i;

Page 298: Data structures all in one

  for (i = 0; i < d; i++)

    leftRotatebyOne(arr, n);

}

void leftRotatebyOne(int arr[], int n)

{

  int i, temp;

  temp = arr[0];

  for (i = 0; i < n-1; i++)

     arr[i] = arr[i+1];

  arr[i] = temp;

}

/* utility function to print an array */

void printArray(int arr[], int size)

{

  int i;

  for(i = 0; i < size; i++)

    printf("%d ", arr[i]);

}

/* Driver program to test above functions */

int main()

{

   int arr[] = {1, 2, 3, 4, 5, 6, 7};

   leftRotate(arr, 2, 7);

   printArray(arr, 7);

   getchar();

   return 0;

Page 299: Data structures all in one

}

Time complexity: O(n*d)Auxiliary Space: O(1)

METHOD 3 (A Juggling Algorithm)This is an extension of method 2. Instead of moving one by one, divide the array in different setswhere number of sets is equal to GCD of n and d and move the elements within sets.If GCD is 1 as is for the above example array (n = 7 and d =2), then elements will be moved within one set only, we just start with temp = arr[0] and keep moving arr[I+d] to arr[I] and finally store temp at the right place.

Here is an example for n =12 and d = 3. GCD is 3 and

Let arr[] be {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}

a) Elements are first moved in first set – (See below diagram for this movement)

arr[] after this step --> {4 2 3 7 5 6 10 8 9 1 11 12}

b) Then in second set. arr[] after this step --> {4 5 3 7 8 6 10 11 9 1 2 12}

Page 300: Data structures all in one

c) Finally in third set. arr[] after this step --> {4 5 6 7 8 9 10 11 12 1 2 3}/* function to print an array */

void printArray(int arr[], int size);

/*Fuction to get gcd of a and b*/

int gcd(int a,int b);

/*Function to left rotate arr[] of siz n by d*/

void leftRotate(int arr[], int d, int n)

{

  int i, j, k, temp;

  for (i = 0; i < gcd(d, n); i++)

  {

    /* move i-th values of blocks */

    temp = arr[i];

    j = i;

    while(1)

    {

      k = j + d;

      if (k >= n)

        k = k - n;

      if (k == i)

        break;

      arr[j] = arr[k];

      j = k;

    }

    arr[j] = temp;

  }

Page 301: Data structures all in one

}

/*UTILITY FUNCTIONS*/

/* function to print an array */

void printArray(int arr[], int size)

{

  int i;

  for(i = 0; i < size; i++)

    printf("%d ", arr[i]);

}

/*Fuction to get gcd of a and b*/

int gcd(int a,int b)

{

   if(b==0)

     return a;

   else

     return gcd(b, a%b);

}

/* Driver program to test above functions */

int main()

{

   int arr[] = {1, 2, 3, 4, 5, 6, 7};

   leftRotate(arr, 2, 7);

   printArray(arr, 7);

   getchar();

   return 0;

}

Page 302: Data structures all in one

Time complexity: O(n)Auxiliary Space: O(1)

Please see following posts for other methods of array rotation:Block swap algorithm for array rotationReversal algorithm for array rotation

References:http://www.cs.bell-labs.com/cm/cs/pearls/s02b.pdf

Reversal algorithm for array rotationNovember 10, 2009

Write a function rotate(arr[], d, n) that rotates arr[] of size n by d elements.

Rotation of the above array by 2 will make array

Method 4(The Reversal Algorithm)Please read this   for first three methods of array rotation.

Algorithm:

rotate(arr[], d, n) reverse(arr[], 1, d) ; reverse(arr[], d + 1, n); reverse(arr[], l, n);

Let AB are the two parts of the input array where A = arr[0..d-1] and B = arr[d..n-1]. The idea of the algorithm is:Reverse A to get ArB. /* Ar is reverse of A */

Page 303: Data structures all in one

Reverse B to get ArBr. /* Br is reverse of B */Reverse all to get (ArBr) r = BA.

For arr[] = [1, 2, 3, 4, 5, 6, 7], d =2 and n = 7A = [1, 2] and B = [3, 4, 5, 6, 7]Reverse A, we get ArB = [2, 1, 3, 4, 5, 6, 7]Reverse B, we get ArBr = [2, 1, 7, 6, 5, 4, 3]Reverse all, we get (ArBr)r = [3, 4, 5, 6, 7, 1, 2]

Implementation:

/*Utility function to print an array */

void printArray(int arr[], int size);

/* Utility function to reverse arr[] from start to end */

void rvereseArray(int arr[], int start, int end);

/* Function to left rotate arr[] of size n by d */

void leftRotate(int arr[], int d, int n)

{

  rvereseArray(arr, 0, d-1);

  rvereseArray(arr, d, n-1);

  rvereseArray(arr, 0, n-1);

}

/*UTILITY FUNCTIONS*/

/* function to print an array */

void printArray(int arr[], int size)

{

  int i;

  for(i = 0; i < size; i++)

    printf("%d ", arr[i]);

Page 304: Data structures all in one

  printf("%\n ");

}

/*Function to reverse arr[] from index start to end*/

void rvereseArray(int arr[], int start, int end)

{

  int i;

  int temp;

  while(start < end)

  {

    temp = arr[start];

    arr[start] = arr[end];

    arr[end] = temp;

    start++;

    end--;

  }

}

/* Driver program to test above functions */

int main()

{

   int arr[] = {1, 2, 3, 4, 5, 6, 7};

   leftRotate(arr, 2, 7);

   printArray(arr, 7);

   getchar();

   return 0;

}

Time Complexity: O(n)

Page 305: Data structures all in one

References:http://www.cs.bell-labs.com/cm/cs/pearls/s02b.pdf

Block swap algorithm for array rotationNovember 14, 2009

Write a function rotate(ar[], d, n) that rotates arr[] of size n by d elements.

Rotation of the above array by 2 will make array

Algorithm:

Initialize A = arr[0..d-1] and B = arr[d..n-1]1) Do following until size of A is equal to size of B

a) If A is shorter, divide B into Bl and Br such that Br is of same length as A. Swap A and Br to change ABlBr into BrBlA. Now A is at its final place, so recur on pieces of B.

b) If A is longer, divide A into Al and Ar such that Al is of same length as B Swap Al and B to change AlArB into BArAl. Now B is at its final place, so recur on pieces of A.

2) Finally when A and B are of equal size, block swap them.

Page 306: Data structures all in one

Recursive Implementation:

#include<stdio.h>

/*Prototype for utility functions */

void printArray(int arr[], int size);

void swap(int arr[], int fi, int si, int d);

void leftRotate(int arr[], int d, int n)

{

  /* Return If number of elements to be rotated is

    zero or equal to array size */

  if(d == 0 || d == n)

    return;

  /*If number of elements to be rotated is exactly

    half of array size */

  if(n-d == d)

  {

    swap(arr, 0, n-d, d);

    return;

  }

 /* If A is shorter*/

  if(d < n-d)

  {

    swap(arr, 0, n-d, d);

    leftRotate(arr, d, n-d);

  }

  else /* If B is shorter*/

Page 307: Data structures all in one

  {

    swap(arr, 0, d, n-d);

    leftRotate(arr+n-d, 2*d-n, d); /*This is tricky*/

  }

}

/*UTILITY FUNCTIONS*/

/* function to print an array */

void printArray(int arr[], int size)

{

  int i;

  for(i = 0; i < size; i++)

    printf("%d ", arr[i]);

  printf("%\n ");

}

/*This function swaps d elements starting at index fi

  with d elements starting at index si */

void swap(int arr[], int fi, int si, int d)

{

   int i, temp;

   for(i = 0; i<d; i++)

   {

     temp = arr[fi + i];

     arr[fi + i] = arr[si + i];

     arr[si + i] = temp;

   }

}

Page 308: Data structures all in one

/* Driver program to test above functions */

int main()

{

   int arr[] = {1, 2, 3, 4, 5, 6, 7};

   leftRotate(arr, 2, 7);

   printArray(arr, 7);

   getchar();

   return 0;

}

Iterative Implementation:Here is iterative implementation of the same algorithm. Same utility function swap() is used here.

void leftRotate(int arr[], int d, int n)

{

  int i, j;

  if(d == 0 || d == n)

    return;

  i = d;

  j = n - d;

  while (i != j)

  {

    if(i < j) /*A is shorter*/

    {

      swap(arr, d-i, d+j-i, i);

      j -= i;

    }

    else /*B is shorter*/

    {

Page 309: Data structures all in one

      swap(arr, d-i, d, j);

      i -= j;

    }

    // printArray(arr, 7);

  }

  /*Finally, block swap A and B*/

  swap(arr, d-i, d, i);

}

Time Complexity: O(n)

Please see following posts for other methods of array rotation:http://geeksforgeeks.org/?p=2398http://geeksforgeeks.org/?p=2838

References:http://www.cs.bell-labs.com/cm/cs/pearls/s02b.pdf

Data Structures and Algorithms | Set 3November 15, 2009

Following questions have asked in GATE CS exam.

1. Suppose you are given an array s[1...n] and a procedure reverse (s,i,j) which reverses the order of elements in a between positions i and j (both inclusive). What does the following sequence

do, where 1 < k <= n: reverse (s, 1, k); reverse (s, k + 1, n); reverse (s, 1, n);

(GATE CS 2000)(a) Rotates s left by k positions(b) Leaves s unchanged(c) Reverses all elements of s(d) None of the above

Page 310: Data structures all in one

Answer: (a)Effect of the above 3 reversals for any k is equivalent to left rotation of the array of size n by k. Please see this post for details.If we rotate an array n times for k = 1 to n, we get the same array back.

2. The best data structure to check whether an arithmetic expression has balanced parentheses is a (GATE CS 2004)a) queueb) stackc) treed) list

Answer(b)There are three types of parentheses [ ] { } (). Below is an arbit c code segment which has parentheses of all three types.

void func(int c, int a[])

{

   return ((c +2)  + arr[(c-2)]) ;

}

Stack is a straightforward choice for checking if left and right parentheses are balanced. Here is a algorithm to do the same.

/*Return 1 if expression has balanced parentheses */

bool areParenthesesBalanced(expression )

{

   for each character in expression

   {

      if(character == ’(’ || character == ’{’ || character == ’[’)

        push(stack, character);

      if(character == ’)’ || character == ’}’ || character == ’]’)

      {

Page 311: Data structures all in one

         if(isEmpty(stack))

           return 0; /*We are seeing a right parenthesis

                       without a left pair*/

         /* Pop the top element from stack, if it is not a pair

             bracket of character then there is a mismatch.

             This will happen for expressions like {(}) */

         else if (! isMatchingPair(pop(stack), character) )

           return 0;

      }

   }

   if(isEmpty(stack))

     return 1; /*balanced*/

   else

     return 0;  /*not balanced*/

} /* End of function to check parentheses */

/* Returns 1 if character1 and character2 are matching left

   and right parentheses */

bool isMatchingPair(character1, character2)

{

   if(character1 == ‘(‘ && character2 == ‘)’)

     return 1;

   else If(character1 == ‘{‘ && character2 == ‘}’)

     return 1;

   else If(character1 == ‘[‘ && character2 == ‘]’)

     return 1;

   else

Page 312: Data structures all in one

     return 0;

}

3. Level order traversal of a rooted tree can be done by starting from the root and performing (GATE CS 2004)a) preorder traversalb) in-order traversalc) depth first searchd) breadth first search

Answer(d)See this post for details

4. Given the following input (4322, 1334, 1471, 9679, 1989, 6171, 6173, 4199) and the hash function x mod 10, which of the following statements are true?i. 9679, 1989, 4199 hash to the same valueii. 1471, 6171 has to the same valueiii. All elements hash to the same valueiv. Each element hashes to a different value(GATE CS 2004)

a) i onlyb) ii onlyc) i and ii onlyd) iii or iv

Answer (c)

5. Postorder traversal of a given binary search tree, T produces the following sequence of keys10, 9, 23, 22, 27, 25, 15, 50, 95, 60, 40, 29Which one of the following sequences of keys can be the result of an in-order traversal of the tree T? (GATE CS 2005)a) 9, 10, 15, 22, 23, 25, 27, 29, 40, 50, 60, 95b) 9, 10, 15, 22, 40, 50, 60, 95, 23, 25, 27, 29

Page 313: Data structures all in one

c) 29, 15, 9, 10, 25, 22, 23, 27, 40, 60, 50, 95d) 95, 50, 60, 40, 27, 23, 22, 25, 10, 9, 15, 29

Answer (a)Inorder traversal of a BST   always gives elements in increasing order. Among all four options, a) is the only increasing order sequence.

Output of C programs | Set 8November 18, 2009

Predict the output of below C programs. Question 1:

#include<stdio.h>

int main()

{

    int x = 5, p = 10;

    printf("%*d", x, p);

    getchar();

    return 0;

}

Output: 10

Explanation:Please see standard printf function definition

int printf ( const char * format, ... );

format: String that contains the text to be written to stdout. It can optionally contain embedded format tags that are substituted by the values specified in subsequent argument(s) and formatted as requested. The number of arguments following the format parameters should at least be as much as the number of format tags. The format tags follow this prototype:

Page 314: Data structures all in one

%[flags][width][.precision][length]specifier

You can see details of all above parts here http://www.cplusplus.com/reference/clibrary/cstdio/printf/.

The main thing to note is below the line about precision* (star): The precision is not specified in the format string, but as an additional integer value argument preceding the argument that has to be formatted.

So, in the above example 5 is precision and 10 is the actual value to be printed. (Thanks to Ajay Mishra for providing the solution)

Question 2

int main()

{

  char arr[]  = "geeksforgeeks";

  char *ptr  = arr;

  while(*ptr != '\0')

      ++*ptr++;

  printf("%s %s", arr, ptr);

  getchar();

  return 0;

}

Output:  hffltgpshfflt

Explanation:The crust of this question lies in expression ++*ptr++.

Page 315: Data structures all in one

If one knows the precedence and associativity of the operators then there is nothing much left. Below is the precedence of operators.

Postfixx ++ left-to-right Prefix ++ right-to-left Dereference * right-to-left

Therefore the expression ++*ptr++ has following effectValue of *ptr is incrementedValue of ptr is incremented

Question 3

int main()

{

  signed char i=0;

  for(; i >= 0; i++);

  printf("%d\n", i);

  getchar();

  return 0;

}

Output: -128

Explanation:Here, the first thing to be noticed is the semi-colon in the end of for loop. So basically, there’s no body for the for loop. And printf will print the value of i when control comes out of the for loop. Also, notice that the first statement i.e. initializer in the for loop is not present. But i has been initialized at the declaration time. Since i is a signed character, it can take value from -128 to 127. So in the for loop, i will keep incrementing and the condition is met till roll over happens. At the roll over, i will become -128 after 127, in that case condition is not met and control comes out of the for loop.

Page 316: Data structures all in one

Question 4

#include <stdio.h>

void fun(const char **p) { }

int main(int argc, char **argv)

{

   fun(argv);

   getchar();

   return 0;

}

Output: Compiler error.

Explanation:Parameter passed to fun() and parameter expected in definition are of incompatible types. fun() expects const char** while passed parameter is of type char **.

Now try following program, it will work.

void fun(const char **p) { }int main(int argc, char **argv){ const char **temp; fun(temp); getchar(); return 0;}A program to check if a binary tree is BST or notNovember 21, 2009

A binary search tree (BST) is a node based binary tree data structure which has the following properties.• The left subtree of a node contains only nodes with keys less than the node’s key.

Page 317: Data structures all in one

• The right subtree of a node contains only nodes with keys greater than the node’s key.• Both the left and right subtrees must also be binary search trees.

From the above properties it naturally follows that:• Each node (item in the tree) has a distinct key.

METHOD 1 (Simple but Wrong)Following is a simple program. For each node, check if left node of it is smaller than the node and right node of it is greater than the node.

int isBST(struct node* node)

{

  if (node == NULL)

    return 1;

  /* false if left is > than node */

  if (node->left != NULL && node->left->data > node->data)

    return 0;

  /* false if right is < than node */

  if (node->right != NULL && node->right->data < node->data)

    return 0;

  /* false if, recursively, the left or right is not a BST */

Page 318: Data structures all in one

  if (!isBST(node->left) || !isBST(node->right))

    return 0;

  /* passing all that, it's a BST */

  return 1;

}

This approach is wrong as this will return true for below binary tree (and below tree is not a BST because 4 is in left subtree of 3)

METHOD 2 (Correct but not efficient)For each node, check if max value in left subtree is smaller than the node and min value in right subtree greater than the node.

/* Returns true if a binary tree is a binary search tree */

int isBST(struct node* node)

{

  if (node == NULL)

    return(true);

  /* false if the max of the left is > than us */

  if (node->left!=NULL && maxValue(node->left) > node->data)

Page 319: Data structures all in one

    return(false);

  /* false if the min of the right is <= than us */

  if (node->right!=NULL && minValue(node->right) < node->data)

    return(false);

  /* false if, recursively, the left or right is not a BST */

  if (!isBST(node->left) || !isBST(node->right))

    return(false);

  /* passing all that, it's a BST */

  return(true);

}

It is assumed that you have helper functions minValue() and maxValue() that return the min or max int value from a non-empty tree

METHOD 3 (Correct and Efficient)Method 2 above runs slowly since it traverses over some parts of the tree many times. A better solution looks at each node only once. The trick is to write a utility helper function isBSTUtil(struct node* node, int min, int max) that traverses down the tree keeping track of the narrowing min and max allowed values as it goes, looking at each node only once. The initial values for min and max should be INT_MIN and INT_MAX — they narrow from there.

/* Returns true if the given tree is a binary search tree (efficient version). */ int isBST(struct node* node) { return(isBSTUtil(node, INT_MIN, INT_MAX)); }

Page 320: Data structures all in one

/* Returns true if the given tree is a BST and its values are >= min and <= max. */ int isBSTUtil(struct node* node, int min, int max)

Implementation:

#include <stdio.h>

#include <stdlib.h>

#include <limits.h>

/* A binary tree node has data, pointer to left child

   and a pointer to right child */

struct node

{

    int data;

    struct node* left;

    struct node* right;

};

int isBSTUtil(struct node* node, int min, int max);

/* Returns true if the given tree is a binary search tree

 (efficient version). */

int isBST(struct node* node)

{

  return(isBSTUtil(node, INT_MIN, INT_MAX));

}

/* Returns true if the given tree is a BST and its

Page 321: Data structures all in one

   values are >= min and <= max. */

int isBSTUtil(struct node* node, int min, int max)

{

  /* an empty tree is BST */

  if (node==NULL)

     return 1;

  /* false if this node violates the min/max constraint */

  if (node->data < min || node->data > max)

     return 0;

  /* otherwise check the subtrees recursively,

   tightening the min or max constraint */

  return

    isBSTUtil(node->left, min, node->data-1) &&  // Allow only distinct values

    isBSTUtil(node->right, node->data+1, max);  // Allow only distinct values

}

/* Helper function that allocates a new node with the

   given data and NULL left and right pointers. */

struct node* newNode(int data)

{

  struct node* node = (struct node*)

                       malloc(sizeof(struct node));

  node->data = data;

  node->left = NULL;

  node->right = NULL;

Page 322: Data structures all in one

  return(node);

}

/* Driver program to test above functions*/

int main()

{

  struct node *root = newNode(4);

  root->left        = newNode(2);

  root->right       = newNode(5);

  root->left->left  = newNode(1);

  root->left->right = newNode(3);

  if(isBST(root))

    printf("Is BST");

  else

    printf("Not a BST");

  getchar();

  return 0;

}

Time Complexity: O(n)Auxiliary Space : O(1) if Function Call Stack size is not considered, otherwise O(n)

METHOD 4(Using In-Order Traversal)Thanks to LJW489 for suggesting this method.1) Do In-Order Traversal of the given tree and store the result in a temp array.3) Check if the temp array is sorted in ascending order, if it is, then the tree is BST.

Page 323: Data structures all in one

Time Complexity: O(n)

We can avoid the use of Auxiliary Array. While doing In-Order traversal, we can keep track of previously visited node. If the value of the currently visited node is less than the previous value, then tree is not BST. Thanks to ygos for this space optimization.

bool isBST(struct node* root)

{

    static struct node *prev = NULL;

    // traverse the tree in inorder fashion and keep track of prev node

    if (root)

    {

        if (!isBST(root->left))

          return false;

        // Allows only distinct valued nodes

        if (prev != NULL && root->data <= prev->data)

          return false;

        prev = root;

        return isBST(root->right);

    }

    return true;

}

The use of static variable can also be avoided by using reference to prev node as a parameter (Similar to this post).

Page 324: Data structures all in one

Sources:http://en.wikipedia.org/wiki/Binary_search_treehttp://cslibrary.stanford.edu/110/BinaryTrees.html

Compute modulus division by a power-of-2-numberNovember 22, 2009

Compute n modulo d without division(/) and modulo(%) operators, where d is a power of 2 number.

Let ith bit from right is set in d. For getting n modulus d, we just need to return 0 to i-1 (from right) bits of n as they are and other bits as 0.

For example if n = 6 (00..110) and d = 4(00..100). Last set bit in d is at position 3 (from right side). So we need to return last two bits of n as they are and other bits as 0, i.e., 00..010.

Now doing it is so easy, guess it….

Yes, you have guessing it right. See the below program.

#include<stdio.h>

/* This function will return n % d.

   d must be one of: 1, 2, 4, 8, 16, 32, … */

unsigned int getModulo(unsigned int n, unsigned int d)

{

  return ( n & (d-1) );

}

/* Driver program to test above function */

int main()

{

  unsigned int n = 6;

  unsigned int d = 4; /*d must be a power of 2*/

Page 325: Data structures all in one

  printf("%u moduo %u is %u", n, d, getModulo(n, d));

  getchar();

  return 0;

}

References:http://graphics.stanford.edu/~seander/bithacks.html#ModulusDivisionEasy

Maximum sum such that no two elements are adjacentNovember 26, 2009

Question: Given an array of positive numbers, find the maximum sum of a subsequence with the constraint that no 2 numbers in the sequence should be adjacent in the array. So 3 2 7 10 should return 13 (sum of 3 and 10) or 3 2 5 10 7 should return 15 (sum of 3, 5 and 7).Answer the question in most efficient way.

Algorithm:Loop for all elements in arr[] and maintain two sums incl and excl where incl = Max sum including the previous element and excl = Max sum excluding the previous element.

Max sum excluding the current element will be max(incl, excl) and max sum including the current element will be excl + current element (Note that only excl is considered because elements cannot be adjacent).

At the end of the loop return max of incl and excl.

Example:

arr[] = {5, 5, 10, 40, 50, 35}

inc = 5 exc = 0

For i = 1 (current element is 5)

Page 326: Data structures all in one

incl = (excl + arr[i]) = 5 excl = max(5, 0) = 5

For i = 2 (current element is 10) incl = (excl + arr[i]) = 15 excl = max(5, 5) = 5

For i = 3 (current element is 40) incl = (excl + arr[i]) = 45 excl = max(5, 15) = 15

For i = 4 (current element is 50) incl = (excl + arr[i]) = 65 excl = max(45, 15) = 45

For i = 5 (current element is 35) incl = (excl + arr[i]) = 80 excl = max(5, 15) = 65

And 35 is the last element. So, answer is max(incl, excl) = 80

Thanks to Debanjan for providing code.

Implementation:

#include<stdio.h>

/*Function to return max sum such that no two elements

 are adjacent */

int FindMaxSum(int arr[], int n)

{

  int incl = arr[0];

  int excl = 0;

  int excl_new;

  int i;

Page 327: Data structures all in one

  for (i = 1; i < n; i++)

  {

     /* current max excluding i */

     excl_new = (incl > excl)? incl: excl;

     /* current max including i */

     incl = excl + arr[i];

     excl = excl_new;

  }

   /* return max of incl and excl */

   return ((incl > excl)? incl : excl);

}

/* Driver program to test above function */

int main()

{

  int arr[] = {5, 5, 10, 100, 10, 5};

  printf("%d \n", FindMaxSum(arr, 6));

  getchar();

  return 0;

}

Time Complexity: O(n)

Now try the same problem for array with negative numbers also.

Data Structures and Algorithms | Set 4November 30, 2009

Following questions have been asked in GATE CS exam.

Page 328: Data structures all in one

1. Consider the following C program segment

struct CellNode

{

  struct CelINode *leftchild;

  int element;

  struct CelINode *rightChild;

}

int Dosomething(struct CelINode *ptr)

{

    int value = 0;

    if (ptr != NULL)

    {

      if (ptr->leftChild != NULL)

        value = 1 + DoSomething(ptr->leftChild);

      if (ptr->rightChild != NULL)

        value = max(value, 1 + DoSomething(ptr->rightChild));

    }

    return (value);

}

The value returned by the function DoSomething when a pointer to the root of a non-empty tree is passed as argument is (GATE CS 2004)a) The number of leaf nodes in the treeb) The number of nodes in the treec) The number of internal nodes in the treed) The height of the tree

Answer: (d)Explanation: DoSomething() returns max(height of left child + 1, height of left child + 1). So given that pointer to root of tree is passed

Page 329: Data structures all in one

to DoSomething(), it will return height of the tree. Note that this implementation follows the convention where height of a single node is 0.

2. Suppose we run Dijkstra’s single source shortest-path algorithm on the following edge weighted directed graph with vertex P as the source. In what order do the nodes get included into the set of vertices for which the shortest path distances are finalized? (GATE CS 2004)

a) P, Q, R, S, T, Ub) P, Q, R, U, S, Tc) P, Q, R, U, T, Sd) P, Q, T, R, U, S

Answer (b)

3. Suppose each set is represented as a linked list with elements in arbitrary order. Which of the operations among union, intersection, membership, cardinality will be the slowest? (GATE CS 2004)a) union onlyb) intersection, membershipc) membership, cardinalityd) union, intersection

Answer (a)Cardinality and membership are definably not the slowest one. For cardinality, just count the number of nodes in a list. For membership, just traverse the list and look for a match

Page 330: Data structures all in one

For getting intersection of L1 and L2, search for each element of L1 in L2 and print the elements we find in L2.

There can be many ways for getting union of L1 and L2. One of them is as followsa) Print all the nodes of L1 and print only those which are not present in L2.b) Print nodes of L2.All of these methods will require more operations than intersection as we have to process intersection node plus other nodes.

4. The time complexity of the following C function is (assume n > 0 (GATE CS 2004)

int recursive (mt n)

{

   if (n == 1)

     return (1);

   else

     return (recursive (n-1) + recursive (n-1));

}

a) 0(n)b) 0(nlogn)c) 0(n^2)d) 0(2^n)

Answer(d)Explanation:Recursive expression for the above program will be.

T(n) = 2T(n-1) + c T(1) = c1.

Let us solve it.

T(n) = 2(2T(n-2) + c) + c = 4T(n-2) + 3c

Page 331: Data structures all in one

T(n) = 8T(n-3) + 6c + c = 8T(n-3) + 7c T(n) = 16T(n-4) + 14c + c = 16T(n-4) + 15c ............................................................ ............................................................. T(n) = (2^(n-1))T(1) + (2^(n-1) - 1)c

T(n) = O(2^n)C Language | Set 3December 4, 2009

Following questions have been asked in GATE CS exam.

1.Assume the following C variable declaration

int *A [10], B[10][10];

Of the following expressionsI A[2]II A[2][3]III B[1]IV B[2][3]which will not give compile-time errors if used as left hand sides of assignment statements in a C program (GATE CS 2003)?

a) I, II, and IV onlyb) II, III, and IV onlyc) II and IV onlyd) IV only

Answer (a)See below program

int main()

{

  int *A[10], B[10][10];

Page 332: Data structures all in one

  int C[] = {12, 11, 13, 14};

  /* No problem with below statement as A[2] is a pointer

     and we are assigning a value to pointer */

  A[2] = C;

  /* No problem with below statement also as array style indexing

      can be done with pointers*/

  A[2][3] = 15;

  /* Simple assignment to an element of a 2D array*/

  B[2][3]  = 15;

  printf("%d %d", A[2][0], A[2][3]);

  getchar();

}

2. Consider the following declaration of a ‘two-dimensional array in C:

char a[100][100];

Assuming that the main memory is byte-addressable and that the array is stored starting from memory address 0, the address of a[40][50] is (GATE CS 2002)a) 4040b) 4050c) 5040d) 5050

Answer(b)

Page 333: Data structures all in one

Address of a[40][50] = Base address + 40*100*element_size + 50*element_size 0 + 4000*1 + 50*1 4050

3. The C language is. (GATE CS 2002) a) A context free languageb) A context sensitive languagec) A regular languaged) Parsable fully only by a Turing machine

Answer (a)Most programming languages including C, C++, Java and Pascal can be approximated by context-free grammar and compilers for them have been developed based on properties of context-free languages.

References:http://acm.pku.edu.cn/JudgeOnline/problem?id=3220http://www.cs.odu.edu/~toida/nerzic/390teched/cfl/cfg.html

4 The most appropriate matching for the following pairs (GATE CS 2000)

X: m=malloc(5); m= NULL; 1: using dangling pointersY: free(n); n->value=5; 2: using uninitialized pointersZ: char *p; *p = ’a’; 3. lost memory is:

(a) X—1 Y—3 Z-2(b) X—2 Y—1 Z-3

Page 334: Data structures all in one

(C) X—3 Y—2 Z-1(d) X—3 Y—1 Z-2

Answer (d)X -> A pointer is assigned to NULL without freeing memory so a clear example of memory leakY -> Trying to retrieve value after freeing it so dangling pointer.Z -> Using uninitialized pointers

5. Consider the following C-program:

void foo(int n, int sum)

{

  int k = 0, j = 0;

  if (n == 0) return;

    k = n % 10;

  j = n / 10;

  sum = sum + k;

  foo (j, sum);

  printf ("%d,", k);

}

int main ()

{

  int a = 2048, sum = 0;

  foo (a, sum);

  printf ("%d\n", sum);

  getchar();

}

Page 335: Data structures all in one

What does the above program print? (GATE CS 2005)(a) 8, 4, 0, 2, 14(b) 8, 4, 0, 2, 0(C) 2, 0, 4, 8, 14(d) 2, 0, 4, 8, 0

Answer (d)sum has no use in foo(), it is there just to confuse. Function foo() just prints all digits of a number. In main, there is one more printf statement after foo(), so one more 0 is printed after all digits of n.

Data Structures and Algorithms | Set 5December 6, 2009

Following questions have been asked in GATE CS exam.

1. Consider the following C function.

float f(float x, int y)

{

  float p, s; int i;

  for (s=1, p=1, i=1; i < y; i ++)

  {

    p*= x/i;

    s+=p;

  }

  return s;

}

For large values of y, the return value of the function f best approximates (GATE CS 2003)

a) x^y

b) e^x

c) ln(1 + x)

d) x^x

Answer (b)

The function f() is implementation of Taylor’s Series to calculates e^x

Page 336: Data structures all in one

e^x = 1 + x + x^2/2! + x^3/3! + ---

More is the value of y more precise value of e^x will be returned by f()

References:

http://en.wikipedia.org/wiki/E_%28mathematical_constant%29

2. In the worst case, the number of comparisons needed to search a singly linked list of length

n for a given element is (GATE CS 2002)

a) log 2 n

b) n/2

c) log 2 n – 1

d) n

Answer(d)

In the worst case, the element to be searched has to be compared with all elements of linked list.

3. The elements 32, 15, 20, 30, 12, 25, 16 are inserted one by one in the given order into a Max

Heap. The resultant Max Heap is.

Answer (a)

4. Consider the following three claims

I (n + k)^m =  (n^m), where k and m are constants

II 2^(n + 1) = 0(2^n)

Page 337: Data structures all in one

III 2^(2n + 1) = 0(2^n)

Which of these claims are correct? (GATE CS 2003)

(a) I and II

(b) I and III

(c) II and III

(d) I, II and III

Answer(a)

(I) (n+m)^k = n^k + c1*n^(k-1) + ... k^m = (n^k)(II) 2^(n+1) = 2*2^n = O(2^n)

5. A single array A[1..MAXSIZE] is used to implement two stacks. The two stacks grow from

opposite ends of the array. Variables top1 and top2 (topl< top 2) point to the location of the

topmost element in each of the stacks. If the space is to be used efficiently, the condition for

“stack full” is (GATE CS 2004)

a) (top1 = MAXSIZE/2) and (top2 = MAXSIZE/2+1)

b) top1 + top2 = MAXSIZE

c) (top1= MAXSIZE/2) or (top2 = MAXSIZE)

d) top1= top2 -1

Answer(d)

If we are to use space efficiently then size of the any stack can be more than MAXSIZE/2.

Both stacks will grow from both ends and if any of the stack top reaches near to the other top then

stacks are full. So the condition will be top1 = top2 -1 (given that top1 < top2)

Output of C Programs | Set 9December 6, 2009

Predict the output of the below programs.

Question 1

int main()

{

 int c=5;

 printf("%d\n%d\n%d", c, c <<= 2, c >>= 2);

 getchar();

}

Page 338: Data structures all in one

Output: Compiler dependentEvaluation order of parameters is not defined by C standard and is dependent on compiler implementation. It is never safe to depend on the order of parameter evaluation. For example, a function call like above may very well behave differently from one compiler to another.

References:http://gcc.gnu.org/onlinedocs/gcc/Non_002dbugs.html

Question 2

int main()

{

    char arr[] = {1, 2, 3};

    char *p = arr;

    if(&p == &arr)

     printf("Same");

    else

     printf("Not same");

    getchar();

}

Output: Not Same&arr is an alias for &arr[0] and returns the address of the first element in array, but &p returns the address of pointer p.Now try below program

int main()

{

    char arr[] = {1, 2, 3};

    char *p = arr;

    if(p == &arr)

     printf("Same");

Page 339: Data structures all in one

    else

     printf("Not same");

    getchar();

}

Question 3

int main()

{

    char arr[] = {1, 2, 3};

    char *p = arr;

    printf(" %d ", sizeof(p));

    printf(" %d ", sizeof(arr));

    getchar();

}

Output 4 3sizeof(arr) returns the amount of memory used by all elements in arrayand sizeof(p) returns the amount of memory used by the pointer variable itself.

Question 4

int x = 0;

int f()

{

   return x;

}

Page 340: Data structures all in one

int g()

{

   int x = 1;

   return f();

}

int main()

{

  printf("%d", g());

  printf("\n");

  getchar();

}

Output: 0In C, variables are always statically (or lexically) scoped. Binding of x inside f() to global variable x is defined at compile time and not dependent on who is calling it. Hence, output for the above program will be 0.

On a side note, Perl supports both dynamic ans static scoping. Perl’s keyword “my” defines a statically scoped local variable, while the keyword “local” defines dynamically scoped local variable. So in Perl, similar (see below) program will print 1.

$x = 0;

sub f

{

   return $x;

}

sub g

{

   local $x = 1; return f();

}

Page 341: Data structures all in one

print g()."\n";

Reference:http://en.wikipedia.org/wiki/Scope_%28programming%29

Leaders in an arrayDecember 7, 2009

Write a program to print all the LEADERS in the array. An element is leader if it is greater than all the elements to its right side. And the rightmost element is always a leader. For example int the array {16, 17, 4, 3, 5, 2}, leaders are 17, 5 and 2.

Let the input array be arr[] and size of the array be size.

Method 1 (Simple)Use two loops. The outer loop runs from 0 to size – 1 and one by one picks all elements from left to right. The inner loop compares the picked element to all the elements to its right side. If the picked element is greater than all the elements to its right side, then the picked element is the leader.

/*Function to print leaders in an array */

void printLeaders(int arr[], int size)

{

  int i, j;

  for (i = 0; i < size; i++)

  {

    for (j = i+1; j < size; j++)

    {

        if(arr[i] <= arr[j])

          break;

    }

    if(j == size) // the loop didn't break

Page 342: Data structures all in one

    {

        printf("%d ", arr[i]);

    }

  }

}

/*Driver program to test above function*/

int main()

{

  int arr[] = {16, 17, 4, 3, 5, 2};

  printLeaders(arr, 6);

  getchar();

}

// Output:  17 5 2

Time Complexity: O(n*n)

Method 2 (Scan from right)Scan all the elements from right to left in array and keep track of maximum till now. When maximum changes it’s value, print it.

/*Function to print leaders in an array */

void printLeaders(int arr[], int size)

{

  int max_from_right =  arr[size-1];

  int i;

  /* Rightmost element is always leader */

  printf("%d ", max_from_right);

Page 343: Data structures all in one

  for(i = size-2; i >= 0; i--)

  {

    if(max_from_right < arr[i])

    {

       printf("%d ", arr[i]);

       max_from_right = arr[i];

    }

  }

}

/*Driver program to test above function*/

int main()

{

  int arr[] = {16, 17, 4, 3, 5, 2};

  printLeaders(arr, 6);

  getchar();

}

// Output:  2 5 17

Time Complexity: O(n)

Data Structures and Algorithms | Set 6December 9, 2009

Following questions have been asked in GATE CS exam.

1. The usual  (n^2) implementation of Insertion Sort to sort an array uses linear search to identify the position where an element is to be inserted into the already sorted part of the array. If, instead, we use binary search to identify the position, the worst case running time will (GATE CS 2003)(a) remain  (n^2)(b) become  (n(log n)^2)

Page 344: Data structures all in one

(c) become  (n log n)(d) become  (n)

Answer (a)If we use binary search then there will be   comparisons in the worst case, which is  (n log n) ( If you want to know how   can be equal to  (n log n), then see this for proof). But the algorithm as a whole will still have a running time of  (n^2) on average because of the series of swaps required for each insertion.

Reference:http://en.wikipedia.org/wiki/Insertion_sort

2. The tightest lower bound on the number of comparisons, in the worst case, for comparison-based sorting is of the order ofa) nb) n^2c) nlognd) n(log^2)n

Answer (c)The number of comparisons that a comparison sort algorithm requires increases in proportion to nlog(n), where n is the number of elements to sort. This bound is asymptotically tight:

Given a list of distinct numbers (we can assume this because this is a worst-case analysis), there are n factorial permutations exactly one of which is the list in sorted order. The sort algorithm must gain enough information from the comparisons to identify the correct permutations. If the algorithm always completes after at most f(n) steps, it cannot distinguish more than 2^f(n) cases because the keys are distinct and each comparison has only two possible outcomes. Therefore,

2^f(n)   n!, or equivalently f(n) [Tex]\log_2[/Tex](n!).

References:http://en.wikipedia.org/wiki/Comparison_sorthttp://www.cs.cmu.edu/afs/cs.cmu.edu/academic/class/15451-s07/www/lecture_notes/lect0130.pdf

Page 345: Data structures all in one

3. The problem 3-SAT and 2-SAT area) both in Pb) both NP completec) NP-complete and in P respectivelyd) undecidable and NP-complete respectively

Answer (c)The Boolean satisfiability problem (SAT) is a decision problem, whose instance is a Boolean expression written using only AND, OR, NOT, variables, and parentheses. The problem is: given the expression, is there some assignment of TRUE and FALSE values to the variables that will make the entire expression true? A formula of propositional logic is said to be satisfiable if logical values can be assigned to its variables in a way that makes the formula true.

3-SAT and 2-SAT are special cases of k-satisfiability (k-SAT) or simply satisfiability (SAT), when each clause contains exactly k = 3 and k = 2 literals respectively.

2-SAT is P while 3-SAT is NP Complete. (See this   for explanation)

References:

http://en.wikipedia.org/wiki/Boolean_satisfiability_problem

4. Consider the following graph 

Among the following sequencesI) a b e g h f

Page 346: Data structures all in one

II) a b f e h gIII) a b f h g eIV) a f g h b eWhich are depth first traversals of the above graph? (GATE CS 2003)a) I, II and IV onlyb) I and IV onlyc) II, III and IV onlyd) I, III and IV only

Answer (d)

Principle of programming languages | Set 1December 14, 2009

Following questions have been asked in GATE CS exam.

1.The most appropriate matching for the following pairs

X: Indirect addressing 1: LoopsY: Immediate addressing 2: PointersZ: Auto decrement addressing 3. Constants

is (GATE CS 2000)

(a) X—3 Y—2 Z—1

(b) X—1 Y—3 Z—2

(c) X—2 Y—3 Z—1

(d) X—3 Y—1 Z—2

Answer (c)

Reference:

http://en.wikipedia.org/wiki/Addressing_modehttp://www.cs.nmsu.edu/~pfeiffer/classes/273/notes/immdirext.html

2. Aliasing in the context of programming languages refers to (GATE CS 2000)

(a) multiple variables having the same memory location

(b) multiple variables having the same value

(c) multiple variables having the same identifier

(d) multiple uses of the same variable

Page 347: Data structures all in one

Answer (a)

Aliasing describes a situation in which a data location in memory can be accessed through different

symbolic names in the program.

Reference

http://en.wikipedia.org/wiki/Aliasing_%28computing%29

3. What is printed by the print statements in the program P1 assuming call by reference

parameter passing? (GATE CS 2001)

Program Pl()

{

  x=10;

  y=3;

  func1(y, x, x);

  print x;

  print y;

}

func1 (x, y, z)

{

   y = y + 4;

   z = x + y + z;

}

a) 10, 3

b) 31, 3

c) 27, 7

d) None of the above

Answer (b)

Note the order in which parameters are passed. Inside func1(), x will actually refer to y of main(); and

y and z will refer to x of main(). The Statement y = y + 4; will result in 14 and statement z = x + y + z

will make z = 3 + 14 + 14 = 31 (because y and z point to same variable x of main). Since z refers to x

of main(), main will print 31.

4. Consider the following program

Program P2

Page 348: Data structures all in one

    var n: int:

     procedure W(var x: int)

     begin

         x=x+1;

         print x;

     end

     procedure D

     begin

         var n: int;

         n=3;

         W(n);

     end

begin //beginP2

  n=10;

  D;

end

If the language has dynamic scoping and parameters are passed by reference, what will be

printed by the program? (GATE CS 2001)

a) 10

b) 11

c) 3

d) None of the above

Answer(d)

Program will print 4.

5. The- results returned by functions under value-result and reference parameter passing

conventions (GATE CS 2002)

a) Do not differ

b) Differ in the presence of loops

c) Differ in all cases

d) May differ in the presence of exceptions

Page 349: Data structures all in one

Answer(d)

In call-by-reference evaluation, a function receives an implicit reference to the argument, rather than a

copy of its value. This typically means that the function can modify the argument- something that will

be seen by its caller. Note that C doesn’t support call by reference but call-by-reference can be

implemented using pointers.

Call-by-value-result uses a combination of call-by-value and call-by-reference. Call-by-value-result

works by creating local versions of the parameters passed in. However, the values in these local

versions are copied back to the original arguments after the end of the procedure.

In case of exceptions, results may differ. Let us see below example in an arbitrary language

int addTwo(a, b) { a = a + b; b = a + b; return b; }

If call-by-value-result is used then calling addTwo(x, x) will return 3x (see below for explanation).

a = a + b; will result in a = x + x b = a + b; will result in b = 2x + x

If call-by-reference is used then addTwo(x, x) will return 4x (see below for explanation).

a = a + b; will result in a = x + x b = a + b; will result in b = 2x + 2x

References:

http://c2.com/cgi/wiki?CallByValueResulthttp://en.wikipedia.org/wiki/Evaluation_strategy

Write a recursive function to print reverse of a Linked ListDecember 19, 2009

Note that the question is only about printing the reverse. To reverse the list itself see this

Difficulty Level: Rookie

Algorithm

printReverse(head)

Page 350: Data structures all in one

1. call print reverse for hed->next 2. print head->data

Implementation:

#include<stdio.h>

#include<stdlib.h>

/* Link list node */

struct node

{

    int data;

    struct node* next;

};

/* Function to reverse the linked list */

void printReverse(struct node* head)

{

  // Base case

  if(head == NULL)

    return;

  // print the list after head node

  printReverse(head->next);

  // After everything else is printed, print head

  printf("%d  ", head->data);

}

/*UTILITY FUNCTIONS*/

/* Push a node to linked list. Note that this function

Page 351: Data structures all in one

  changes the head */

void push(struct node** head_ref, char new_data)

{

    /* allocate node */

    struct node* new_node =

            (struct node*) malloc(sizeof(struct node));

    /* put in the data  */

    new_node->data  = new_data;

    /* link the old list off the new node */

    new_node->next = (*head_ref);

    /* move the head to pochar to the new node */

    (*head_ref)    = new_node;

}

/* Drier program to test above function*/

int main()

{

  struct node* head = NULL;

  push(&head, 1);

  push(&head, 2);

  push(&head, 3);

  push(&head, 4);

  printReverse(head);

  getchar();

Page 352: Data structures all in one

}

Time Complexity: O(n)

Babylonian method for square rootDecember 20, 2009

Algorithm:This method can be derived from (but predates) Newton–Raphson method.

1 Start with an arbitrary positive start value x (the closer to the root, the better).2 Initialize y = 1.3. Do following until desired approximation is achieved. a) Get the next approximation for root using average of x and y b) Set y = n/x

Implementation:

/*Returns the square root of n. Note that the function */

float squareRoot(float n)

{

  /*We are using n itself as initial approximation

   This can definitely be improved */

  float x = n;

  float y = 1;

  float e = 0.000001; /* e decides the accuracy level*/

  while(x - y > e)

  {

    x = (x + y)/2;

    y = n/x;

Page 353: Data structures all in one

  }

  return x;

}

/* Driver program to test above function*/

int main()

{

  int n = 50;

  printf ("Square root of %d is %f", n, squareRoot(n));

  getchar();

}

Example:

n = 4 /*n itself is used for initial approximation*/Initialize x = 4, y = 1Next Approximation x = (x + y)/2 (= 2.500000), y = n/x (=1.600000)Next Approximation x = 2.050000,y = 1.951220Next Approximation x = 2.000610,y = 1.999390Next Approximation x = 2.000000, y = 2.000000Terminate as (x - y) > e now.

If we are sure that n is a perfect square, then we can use following method. The method can go in infinite loop for non-perfect-square numbers. For example, for 3 the below while loop will never terminate.

/*Returns the square root of n. Note that the function

  will not work for numbers which are not perfect squares*/

unsigned int squareRoot(int n)

{

Page 354: Data structures all in one

  int x = n;

  int y = 1;

  while(x > y)

  {

    x = (x + y)/2;

    y = n/x;

  }

  return x;

}

/* Driver program to test above function*/

int main()

{

  int n = 49;

  printf (" root of %d is %d", n, squareRoot(n));

  getchar();

}

References;http://en.wikipedia.org/wiki/Square_roothttp://en.wikipedia.org/wiki/Babylonian_method#Babylonian_method

Level order traversal in spiral formDecember 20, 2009

Write a function to print spiral order traversal of a tree. For below tree, function should print 1, 2, 3, 4,

5, 6, 7.

Page 355: Data structures all in one

Algorithm:

This problem is an extension of the level order traversal post.

To print the nodes in spiral order, nodes at different levels should be printed in alternating order. An

additional Boolean variable ltr is used to change printing order of levels. If ltr is 1 then

printGivenLevel() prints nodes from left to right else from right to left. Value of ltr is flipped in each

iteration to change the order.

Function to print level order traversal of tree

printLevelorder(tree) bool ltr = 0; for d = 1 to height(tree) printGivenLevel(tree, d, ltr); ltr ~= ltr /*flip ltr*/

Function to print all nodes at a given level

printGivenLevel(tree, level, ltr)if tree is NULL then return;if level is 1, then print(tree->data);else if level greater than 1, then if(rtl) printGivenLevel(tree->right, level-1, ltr); printGivenLevel(tree->left, level-1, ltr); else printGivenLevel(tree->left, level-1, ltr); printGivenLevel(tree->right, level-1, ltr);

Page 356: Data structures all in one

Implementation:

#include <stdio.h>

#include <stdlib.h>

#define bool int

/* A binary tree node has data, pointer to left child

   and a pointer to right child */

struct node

{

  int data;

  struct node* left;

  struct node* right;

};

/*Function protoypes*/

void printGivenLevel(struct node* root, int level, int ltr);

int height(struct node* node);

struct node* newNode(int data);

/* Function to print spiral traversal of a tree*/

void printLevelOrder(struct node* root)

{

  int h = height(root);

  int i;

  /*ltr -> Left to Right. If this variable is set,

    then the given level is traverseed from left to right. */

  bool ltr = 0;

  for(i=1; i<=h; i++)

Page 357: Data structures all in one

  {

    printGivenLevel(root, i, ltr);

    /*Revert ltr to traverse next level in oppposite order*/

    ltr = ~ltr;

  }

}

/* Print nodes at a given level */

void printGivenLevel(struct node* root, int level, int ltr)

{

  if(root == NULL)

    return;

  if(level == 1)

    printf("%d ", root->data);

  else if (level > 1)

  {

    if(ltr)

    {

      printGivenLevel(root->left, level-1, ltr);

      printGivenLevel(root->right, level-1, ltr);

    }

    else

    {

      printGivenLevel(root->right, level-1, ltr);

      printGivenLevel(root->left, level-1, ltr);

    }

  }

}

Page 358: Data structures all in one

/* Compute the "height" of a tree -- the number of

    nodes along the longest path from the root node

    down to the farthest leaf node.*/

int height(struct node* node)

{

   if (node==NULL)

       return 0;

   else

   {

     /* compute the height of each subtree */

     int lheight = height(node->left);

     int rheight = height(node->right);

     /* use the larger one */

     if (lheight > rheight)

         return(lheight+1);

     else return(rheight+1);

   }

}

/* Helper function that allocates a new node with the

   given data and NULL left and right pointers. */

struct node* newNode(int data)

{

  struct node* node = (struct node*)

                       malloc(sizeof(struct node));

  node->data = data;

  node->left = NULL;

Page 359: Data structures all in one

  node->right = NULL;

  return(node);

}

/* Driver program to test above functions*/

int main()

{

  struct node *root = newNode(1);

  root->left        = newNode(2);

  root->right       = newNode(3);

  root->left->left  = newNode(7);

  root->left->right = newNode(6);

  root->right->left  = newNode(5);

  root->right->right = newNode(4);

  printf("Level Order traversal of binary tree is \n");

  printLevelOrder(root);

  getchar();

  return 0;

}

Data Structures and Algorithms | Set 7December 25, 2009

Following questions have been asked in GATE CS 2006 exam.

1. In a binary max heap containing n numbers, the smallest element can be found in time

(GATE CS 2006)

(A) 0(n)

(B) O(logn)

(C) 0(loglogn)

(D) 0(1)

Page 360: Data structures all in one

Answer (A)

In a max heap, the smallest element is always present at a leaf node. So we need to check for all leaf

nodes for the minimum value. Worst case complexity will be O(n)

12 / \ / \ 8 7 / \ / \ / \ / \2 3 4 5

2. A scheme for storing binary trees in an array X is as follows. Indexing of X starts at 1

instead of 0. the root is stored at X[1]. For a node stored at X[i], the left child, if any, is stored

in X[2i] and the right child, if any, in X[2i+1]. To be able to store any binary tree on n vertices

the minimum size of X should be. (GATE CS 2006)

(A) log2n

(B) n

(C) 2n + 1

(D) 2^n — 1

Answer (D)

For a right skewed binary tree, number of nodes will be 2^n – 1. For example, in below binary tree,

node ‘A’ will be stored at index 1, ‘B’ at index 3, ‘C’ at index 7 and ‘D’ at index 15.

A \ \ B \ \ C \ \ D

3. Which one of the following in place sorting algorithms needs the minimum number of

swaps? (GATE CS 2006)

(A) Quick sort

(B) Insertion sort

(C) Selection sort

(D) Heap sort

Page 361: Data structures all in one

Answer (C)

For selection sort, number of swaps required is minimum (  (n) ).

4. An element in an array X is called a leader if it is greater than all elements to the right of it in

X. The best algorithm to find all leaders in an array (GATE CS 2006)

(A) Solves it in linear time using a left to right pass of the array

(B) Solves it in linear time using a right to left pass of the array

(C) Solves it using divide and conquer in time 8(nlogn)

(D) Solves it in time 8(n2)

Answer (B)

Please see this   post for explanation.

5. Consider a weighted complete graph G on the vertex set {v1,v2 ,v} such that the weight of

the edge (v,,v) is 2|i-j|. The weight of a minimum spanning tree of G is: (GATE CS 2006)

(A) n — 1

(B) 2n — 2

(C) nC2

(D) 2

Answer (B)

Minimum spanning tree of such a graph is

v1 \ v2 \ v3 \ v4 . . . vn

Weight of the minimum spanning tree

= 2|2 – 1| + 2|3 – 2| + 2|4 – 3| + 2|5 – 4| …. + 2| n – (n-1) |

= 2n – 2

For Versus WhileDecember 31, 2009

Question: Is there any example for which the following two loops will not work same way?

Page 362: Data structures all in one

/*Program 1 --> For loop*/

for (<init-stmnt>; <boolean-expr>; <incr-stmnt>)

{

   <body-statements>

}

/*Program 2 --> While loop*/

<init-stmnt>;

while (<boolean-expr>)

{

   <body-statements>

   <incr-stmnt>

}

Solution:

If the body-statements contains continue, then the two programs will work in different ways

See the below examples: Program 1 will print “loop” 3 times but Program 2 will go in an infinite loop.

Example for program 1

int main()

{

  int i = 0;

  for(i = 0; i < 3; i++)

  {

    printf("loop ");

    continue;

  }

  getchar();

  return 0;

}

Page 363: Data structures all in one

Example for program 2

int main()

{

  int i = 0;

  while(i < 3)

  {

    printf("loop"); /* printed infinite times */

    continue;

    i++; /*This statement is never executed*/

  }

  getchar();

  return 0;

}

Compiler Theory | Set 2January 2, 2010

Following questions have been asked in GATE CS exam.

1. Given the following expression grammar:E -> E * F | F+E | FF -> F-F | idwhich of the following is true? (GATE CS 2000)(a) * has higher precedence than +(b) – has higher precedence than *(c) + and — have same precedence(d) + has higher precedence than *

Answer(b)

Precedence in a grammar is enforced by making sure that a production rule with higher precedence operator will never produce an expression with operator with lower precedence.In the given grammar ‘-’ has higher precedence than ‘*’

Page 364: Data structures all in one

2. Consider a program P that consists of two source modules M1 and M2 contained in two different files. If M1 contains a reference to a function defined in M2 the reference will be resolved at (GATE CS 2004)a) Edit timeb) Compile timec) Link timed) Load time

Answer (c)Compiler transforms source code into the target language. The target language is generally in binary form known as object code. Typically, an object file can contain three kinds of symbols:

* defined symbols, which allow it to be called by other modules,* undefined symbols, which call the other modules where these symbols are defined, and* local symbols, used internally within the object file to facilitate relocation.

When a program comprises multiple object files, the linker combines these files into a unified executable program, resolving the symbols as it goes along.http://en.wikipedia.org/wiki/Compilerhttp://en.wikipedia.org/wiki/Linker_%28computing%29

3. Which of the following suffices to convert an arbitrary CFG to an LL(1) grammar? (GATE CS 2003)(a) Removing left recursion alone(b) Factoring the grammar alone(c) Removing left recursion and factoring the grammar(d) None of the above

Answer(d)Removing left recursion and factoring the grammar do not suffice to convert an arbitrary CFG to LL(1) grammar.http://pages.cpsc.ucalgary.ca/~robin/class/411/LL1.3.html

Page 365: Data structures all in one

4. Assume that the SLR parser for a grammar G has n1 states and the LALR parser for G has n2 states. The relationship between nl and n2 is (GATE CS 2003) (a) n1 is necessarily less than n2(b) n1 is necessarily equal to n2(c) n1 is necessarily greater than n2(d) none of the above

Answer (b)

http://parasol.tamu.edu/people/rwerger/Courses/434/lec10.pdfhttp://dragonbook.stanford.edu/lecture-notes/Stanford-CS143/11-LALR-Parsing.pdf

Data Structures and Algorithms | Set 8January 2, 2010

Following questions have been asked in GATE CS exam.

1. Consider the following functions

Which of the following is true? (GATE CS 2000)(a) h(n) is 0(f(n))(b) h(n) is 0(g(n))(c) g(n) is not 0(f(n))(d) f(n) is 0(g(n))

Answer (d)g(n) = 2^  = n^

f(n) and g(n) are of same asymptotic order and following statements are true.f(n) = O(g(n))g(n) = O(f(n)).

Page 366: Data structures all in one

(a) and (b) are false because n! is of asymptotically higher order than n^ .

2. Let G be an undirected connected graph with distinct edge weight. Let emax be the edge with maximum weight and emin the edge with minimum weight. Which of the following statements is false? (GATE CS 2000)(a) Every minimum spanning tree of G must contain emin(b) If emax is in a minimum spanning tree, then its removal must disconnect G(c) No minimum spanning tree contains emax(d) G has a unique minimum spanning tree

Answer (c)(a) and (b) are always true.(c) is false because (b) is true.(d) is true because all edge weights are distinct for G.

3. Let G be an undirected graph. Consider a depth-first traversal of G, and let T be the resulting depth-first search tree. Let u be a vertex in G and let v be the first new (unvisited) vertex visited after visiting u in the traversal. Which of the following statements is always true? (GATE CS 2000)(a) {u,v} must be an edge in G, and u is a descendant of v in T(b) {u,v} must be an edge in G, and v is a descendant of u in T(c) If {u,v} is not an edge in G then u is a leaf in T(d) If {u,v} is not an edge in G then u and v must have the same parent in T

Answer (c)

4. Consider an undirected unweighted graph G. Let a breadth-first traversal of G be done starting from a node r. Let d(r, u) and d(r, v) be the lengths of the shortest paths from r to u and v respectively, in G. lf u is visited before v during the breadth-first traversal, which of the following statements is correct? (GATE

Page 367: Data structures all in one

CS 2001) a) d(r, u) < d (r, v)b) d(r, u) > d(r, v)c) d(r, u) <= d (r, v)d) None of the above

Answer (c)d(r, u) and d(r, v) will be equal when u and v are at same level, otherwise d(r, u) will be less than d(r, v)

5. How many undirected graphs (not necessarily connected) can be constructed out of a given set V= {V 1, V 2,…V n} of n vertices ? (GATE CS 2001)a) n(n-l)/2b) 2^nc) n!d) 2^(n(n-1)/2)

Answer (d)In an undirected graph, there can be maximum n(n-1)/2 edges. We can choose to have (or not have) any of the n(n-1)/2 edges. So, total number of undirected graphs with n vertices is 2^(n(n-1)/2).

Sort elements by frequency | Set 1January 3, 2010

Asked By Binod

Question:Print the elements of an array in the decreasing frequency if 2 numbers have same frequency then print the one which came 1stE.g. 2 5 2 8 5 6 8 8 output: 8 8 8 2 2 5 5 6.

METHOD 1 (Use Sorting)

1) Use a sorting algorithm to sort the elements O(nlogn)

Page 368: Data structures all in one

2) Scan the sorted array and construct a 2D array of element and count O(n). 3) Sort the 2D array according to count O(nlogn).

Example:

Input 2 5 2 8 5 6 8 8

After sorting we get 2 2 5 5 6 8 8 8

Now construct the 2D array as 2, 2 5, 2 6, 1 8, 3

Sort by count 8, 3 2, 2 5, 2 6, 1

There is one issue with above approach (thanks to ankit for pointing this out). If we modify the input to 5 2 2 8 5 6 8 8, then we should get 8 8 8 5 5 2 2 6 and not 8 8 8 2 2 5 5 6 as will be the case.To handle this, we should use indexes in step 3, if two counts are same then we should first process(or print) the element with lower index. In step 1, we should store the indexes instead of elements.

Input 5 2 2 8 5 6 8 8

After sorting we get Element 2 2 5 5 6 8 8 8 Index 1 2 0 4 5 3 6 7

Now construct the 2D array as

Page 369: Data structures all in one

Index, Count 1, 2 0, 2 5, 1 3, 3

Sort by count (consider indexes in case of tie) 3, 3 0, 2 1, 2 5, 1 Print the elements using indexes in the above 2D array.

METHOD 2(Use BST and Sorting)1. Insert elements in BST one by one and if an element is already present then increment the count of the node. Node of the Binary Search Tree (used in this approach) will be as follows.

struct tree

{

  int element;

  int first_index /*To handle ties in counts*/

  int count;

}BST;

2.Store the first indexes and corresponding counts of BST in a 2D array.3 Sort the 2D array according to counts (and use indexes in case of tie).

Time Complexity: O(nlogn) if a Self Balancing Binary Search Tree is used.

Page 370: Data structures all in one

METHOD 3(Use Hashing and Sorting)Using a hashing mechanism, we can store the elements (also first index) and their counts in a hash. Finally, sort the hash elements according to their counts.

These are just our thoughts about solving the problem and may not be the optimal way of solving. We are open for better solutions.

Related Links

http://www.trunix.org/programlama/c/kandr2/krx604.html

http://drhanson.s3.amazonaws.com/storage/documents/common.pdf

http://www.cc.gatech.edu/classes/semantics/misc/pp2.pdf

Count Inversions in an arrayJanuary 5, 2010

Inversion Count for an array indicates – how far (or close) the array is from being sorted. If array is already sorted then inversion count is 0. If array is sorted in reverse order that inversion count is the maximum. Formally speaking, two elements a[i] and a[j] form an inversion if a[i] > a[j] and i < j

Example:The sequence 2, 4, 1, 3, 5 has three inversions (2, 1), (4, 1), (4, 3).

METHOD 1 (Simple)For each element, count number of elements which are on right side of it and are smaller than it.

int getInvCount(int arr[], int n)

Page 371: Data structures all in one

{

  int inv_count = 0;

  int i, j;

  for(i = 0; i < n - 1; i++)

    for(j = i+1; j < n; j++)

      if(arr[i] > arr[j])

        inv_count++;

  return inv_count;

}

/* Driver progra to test above functions */

int main(int argv, char** args)

{

  int arr[] = {1, 20, 6, 4, 5};

  printf(" Number of inversions are %d \n", getInvCount(arr, 5));

  getchar();

  return 0;

}

Time Complexity: O(n^2)

METHOD 2(Enhance Merge Sort)Suppose we know the number of inversions in the left half and right half of the array (let be inv1 and inv2), what kinds of inversions are not accounted for in Inv1 + Inv2? The answer is – the inversions we have to count during the merge step. Therefore, to get number of inversions, we need to add number of inversions in left subarray, right subarray and merge().

Page 372: Data structures all in one

How to get number of inversions in merge()?In merge process, let i is used for indexing left sub-array and j for right sub-array. At any step in merge(), if a[i] is greater than a[j], then there are (mid – i) inversions. because left and right subarrays are sorted, so all the remaining elements in left-subarray (a[i+1], a[i+2] … a[mid]) will be greater than a[j]

Page 373: Data structures all in one

The complete picture:

Implementation:

#include <stdio.h>

#include <stdlib.h>

int _mergeSort(int arr[], int temp[], int left, int right);

int merge(int arr[], int temp[], int left, int mid, int right);

/* This function sorts the input array and returns the

   number of inversions in the array */

int mergeSort(int arr[], int array_size)

{

    int *temp = (int *)malloc(sizeof(int)*array_size);

    return _mergeSort(arr, temp, 0, array_size - 1);

}

Page 374: Data structures all in one

/* An auxiliary recursive function that sorts the input array and

  returns the number of inversions in the array. */

int _mergeSort(int arr[], int temp[], int left, int right)

{

  int mid, inv_count = 0;

  if (right > left)

  {

    /* Divide the array into two parts and call _mergeSortAndCountInv()

       for each of the parts */

    mid = (right + left)/2;

    /* Inversion count will be sum of inversions in left-part, right-part

      and number of inversions in merging */

    inv_count  = _mergeSort(arr, temp, left, mid);

    inv_count += _mergeSort(arr, temp, mid+1, right);

    /*Merge the two parts*/

    inv_count += merge(arr, temp, left, mid+1, right);

  }

  return inv_count;

}

/* This funt merges two sorted arrays and returns inversion count in

   the arrays.*/

int merge(int arr[], int temp[], int left, int mid, int right)

{

  int i, j, k;

  int inv_count = 0;

  i = left; /* i is index for left subarray*/

Page 375: Data structures all in one

  j = mid;  /* i is index for right subarray*/

  k = left; /* i is index for resultant merged subarray*/

  while ((i <= mid - 1) && (j <= right))

  {

    if (arr[i] <= arr[j])

    {

      temp[k++] = arr[i++];

    }

    else

    {

      temp[k++] = arr[j++];

     /*this is tricky -- see above explanation/diagram for merge()*/

      inv_count = inv_count + (mid - i);

    }

  }

  /* Copy the remaining elements of left subarray

   (if there are any) to temp*/

  while (i <= mid - 1)

    temp[k++] = arr[i++];

  /* Copy the remaining elements of right subarray

   (if there are any) to temp*/

  while (j <= right)

    temp[k++] = arr[j++];

  /*Copy back the merged elements to original array*/

  for (i=left; i <= right; i++)

    arr[i] = temp[i];

Page 376: Data structures all in one

  return inv_count;

}

/* Driver progra to test above functions */

int main(int argv, char** args)

{

  int arr[] = {1, 20, 6, 4, 5};

  printf(" Number of inversions are %d \n", mergeSort(arr, 5));

  getchar();

  return 0;

}

Note that above code modifies (or sorts) the input array. If we want to count only inversions then we need to create a copy of original array and call mergeSort() on copy.

Time Complexity: O(nlogn)Algorithmic Paradigm: Divide and Conquer

References:http://www.cs.umd.edu/class/fall2009/cmsc451/lectures/Lec08-inversions.pdfhttp://www.cp.eng.chula.ac.th/~piak/teaching/algo/algo2008/count-inv.htm

Operating Systems | Set 4January 8, 2010

Following questions have been asked in GATE CS exam.

1. Using a larger block size in a fixed block size file system leads to (GATE CS 2003)a) better disk throughput but poorer disk space utilizationb) better disk throughput and better disk space utilization

Page 377: Data structures all in one

c) poorer disk throughput but better disk space utilizationd) poorer disk throughput and poorer disk space utilization

Answer (a)If block size is large then seek time is less (fewer blocks to seek) and disk performance is improved, but remember larger block size also causes waste of disk space.

2. Consider the following statements with respect to user-level threads and kernel supported threadsi. context switch is faster with kernel-supported threadsii. for user-level threads, a system call can block the entire processiii. Kernel supported threads can be scheduled independentlyiv. User level threads are transparent to the kernel

Which of the above statements are true? (GATE CS 2004)a) (ii), (iii) and (iv) onlyb) (ii) and (iii) onlyc) (i) and (iii) onlyd) (i) and (ii) only

Answer(a)

http://en.wikipedia.org/wiki/Thread_%28computer_science%29

3. The minimum number of page frames that must be allocated to a running process in a virtual memory environment is determined by (GATE CS 2004)a) the instruction set architectureb) page sizec) physical memory sized) number of processes in memory

Answer (a)Each process needs minimum number of pages based on instruction set architecture. Example IBM 370: 6 pages to handle MVC (storage to storage move) instructionInstruction is 6 bytes, might span 2 pages.

Page 378: Data structures all in one

2 pages to handle from.2 pages to handle to.

4. In a system with 32 bit virtual addresses and 1 KB page size, use of one-level page tables for virtual to physical address translation is not practical because of (GATE CS 2003)a) the large amount of internal fragmentationb) the large amount of external fragmentationc) the large memory overhead in maintaining page tablesd) the large computation overhead in the translation process

Answer (c)Since page size is too small it will make size of page tables huge.

Size of page table = (total number of page table entries) *(size of a page table entry)

Let us see how many entries are there in page table

Number of entries in page table = (virtual address space size)/(page size) = (2^32)/(2^10) = 2^22

Now, let us see how big each entry is.

If size of physical memory is 512 MB then number of bits required to address a byte in 512 MB is 29. So, there will be (512MB)/(1KB) = (2^29)/(2^10) page frames in physical memory. To address a page frame 19 bits are required. Therefore, each entry in page table is required to have 19 bits.

Note that page table entry also holds auxiliary information about the page such as a present bit, a dirty or modified bit, address space or process ID information, amongst others. So size of page table

Page 379: Data structures all in one

> (total number of page table entries) *(size of a page table entry) > (2^22 *19) bytes > 9.5 MB

And this much memory is required for each process because each process maintains its own page table. Also, size of page table will be more for physical memory more than 512MB. Therefore, it is advised to use multilevel page table for such scenarios.

References:http://barbara.stattenfield.org/ta/cs162/section-notes/sec8.txthttp://en.wikipedia.org/wiki/Page_table

Why C treats array parameters as pointers?January 10, 2010

In C, array parameters are treated as pointers. The following two definitions of foo() look different, but to the compiler they mean exactly the same thing. It’s preferable to use whichever syntax is more accurate for readability. If the pointer coming in really is the base address of a whole array, then we should use [ ].

void foo(int arr_param[])

{

  /* Silly but valid. Just changes the local pointer */

  arr_param = NULL;

}

void foo(int *arr_param)

{

  /* ditto */

  arr_param = NULL;

Page 380: Data structures all in one

}

Array parameters treated as pointers because of efficiency. It is inefficient to copy the array data in terms of both memory and time; and most of the times, when we pass an array our intention is to just tell the array we interested in, not to create a copy of the array.

Asked by Shobhit

References:http://cslibrary.stanford.edu/101/EssentialC.pdf

Two elements whose sum is closest to zeroJanuary 10, 2010

Question: An Array of integers is given, both +ve and -ve. You need to find the two elements such that their sum is closest to zero.

For the below array, program should print -80 and 85.

METHOD 1 (Simple) For each element, find the sum of it with every other element in the array and compare sums. Finally, return the minimum sum.

Implementation

# include <stdio.h>

# include <stdlib.h> /* for abs() */

# include <math.h>

void minAbsSumPair(int arr[], int arr_size)

{

  int inv_count = 0;

  int l, r, min_sum, sum, min_l, min_r;

  /* Array should have at least two elements*/

Page 381: Data structures all in one

  if(arr_size < 2)

  {

    printf("Invalid Input");

    return;

  }

  /* Initialization of values */

  min_l = 0;

  min_r = 1;

  min_sum = arr[0] + arr[1];

  for(l = 0; l < arr_size - 1; l++)

  {

    for(r = l+1; r < arr_size; r++)

    {

      sum = arr[l] + arr[r];

      if(abs(min_sum) > abs(sum))

      {

        min_sum = sum;

        min_l = l;

        min_r = r;

      }

    }

  }

  printf(" The two elements whose sum is minimum are %d and %d",

          arr[min_l], arr[min_r]);

}

Page 382: Data structures all in one

/* Driver program to test above function */

int main()

{

  int arr[] = {1, 60, -10, 70, -80, 85};

  minAbsSumPair(arr, 6);

  getchar();

  return 0;

}

Time complexity: O(n^2)

METHOD 2 (Use Sorting) Thanks to baskin for suggesting this approach. We recommend to read this post   for background of this approach.

Algorithm 1) Sort all the elements of the input array.2) Use two index variables l and r to traverse from left and right ends respectively. Initialize l as 0 and r as n-1.3) sum = a[l] + a[r]4) If sum is -ve, then l++5) If sum is +ve, then r–6) Keep track of abs min sum.7) Repeat steps 3, 4, 5 and 6 while l < r

Implementation

# include <stdio.h>

# include <math.h>

# include <limits.h>

void quickSort(int *, int, int);

Page 383: Data structures all in one

/* Function to print pair of elements having minimum sum */

void minAbsSumPair(int arr[], int n)

{

  // Variables to keep track of current sum and minimum sum

  int sum, min_sum = INT_MAX;

  // left and right index variables

  int l = 0, r = n-1;

  // variable to keep track of the left and right pair for min_sum

  int min_l = l, min_r = n-1;

  /* Array should have at least two elements*/

  if(n < 2)

  {

    printf("Invalid Input");

    return;

  }

  /* Sort the elements */

  quickSort(arr, l, r);

  while(l < r)

  {

    sum = arr[l] + arr[r];

    /*If abs(sum) is less then update the result items*/

    if(abs(sum) < abs(min_sum))

    {

Page 384: Data structures all in one

      min_sum = sum;

      min_l = l;

      min_r = r;

    }

    if(sum < 0)

      l++;

    else

      r--;

  }

  printf(" The two elements whose sum is minimum are %d and %d",

          arr[min_l], arr[min_r]);

}

/* Driver program to test above function */

int main()

{

  int arr[] = {1, 60, -10, 70, -80, 85};

  int n = sizeof(arr)/sizeof(arr[0]);

  minAbsSumPair(arr, n);

  getchar();

  return 0;

}

/* FOLLOWING FUNCTIONS ARE ONLY FOR SORTING

    PURPOSE */

void exchange(int *a, int *b)

{

  int temp;

Page 385: Data structures all in one

  temp = *a;

  *a   = *b;

  *b   = temp;

}

int partition(int arr[], int si, int ei)

{

  int x = arr[ei];

  int i = (si - 1);

  int j;

  for (j = si; j <= ei - 1; j++)

  {

    if(arr[j] <= x)

    {

      i++;

      exchange(&arr[i], &arr[j]);

    }

  }

  exchange (&arr[i + 1], &arr[ei]);

  return (i + 1);

}

/* Implementation of Quick Sort

arr[] --> Array to be sorted

si  --> Starting index

ei  --> Ending index

*/

Page 386: Data structures all in one

void quickSort(int arr[], int si, int ei)

{

  int pi;    /* Partitioning index */

  if(si < ei)

  {

    pi = partition(arr, si, ei);

    quickSort(arr, si, pi - 1);

    quickSort(arr, pi + 1, ei);

  }

}

Time Complexity: complexity to sort + complexity of finding the optimum pair = O(nlogn) + O(n) = O(nlogn)

C Language | Set 4January 11, 2010

Following questions have been asked in GATE CS exam.

1. In the C language (GATE CS 2002)

a) At most one activation record exists between the current activation record and the activation record

for the main

b) The number of activation records between the current activation record and the activation record

for the main depends on the actual function calling sequence.

c) The visibility of global variables depends on the actual function calling sequence.

d) Recursion requires the activation record for the recursive function to be saved on a different stack

before the recursive function can be called.

Answer(b)

a) –> There is no such restriction in C language

b) –> True

c) –> False. In C, variables are statically scoped, not dynamically.

c) –> False. The activation records are stored on the same stack.

2. Consider the C program shown below.

# include <stdio.h>

# define print(x)  printf ("%d", x)

Page 387: Data structures all in one

int x;

void Q(int z)

{

  z += x;

  print(z);

}

void P(int *y)

{

  int x = *y+2;

  Q(x);

  *y = x-1;

  print(x);

}

main(void)

{

  x=5;

  P(&x);

  print(x);

  getchar();

}

The output of this program is (GATE CS 2003)

a) 1276

b) 22 12 11

c) 14 6 6

d) 766

Answer (a)

Note that main() and Q() are accessing the global variable x. Inside P(), pointer variable y also holds

address of global variable x, but x in P() is its P’s own local variable.

Find the smallest and second smallest element in an arrayJanuary 11, 2010

Page 388: Data structures all in one

Asked by Vikas

Question: Write an efficient C program to find smallest and second smallest element in an array.

Difficulty Level: Rookie

Algorithm:

1) Initialize both first and second smallest as INT_MAX first = second = INT_MAX2) Loop through all the elements. a) If the current element is smaller than first, then update first and second. b) Else if the current element is smaller than second then update second

Implementation:

#include <stdio.h>

#include <limits.h> /* For INT_MAX */

/* Function to print first smallest and second smallest elements */

void print2Smallest(int arr[], int arr_size)

{

  int i, first, second;

  /* There should be atleast two elements*/

  if(arr_size < 2)

  {

    printf(" Invalid Input ");

    return;

Page 389: Data structures all in one

  }

  first = second = INT_MAX;

  for(i = 0; i < arr_size ; i ++)

  {

    /*If current element is smaller than first then update both

      first and second */

    if(arr[i] < first)

    {

      second = first;

      first = arr[i];

    }

    /* If arr[i] is in between first and second then update second  */

    else if (arr[i] < second)

    {

      second = arr[i];

    }

  }

  printf("The smallest element is %d and second Smallest element is %d",

         first, second);

}

/* Driver program to test above function */

int main()

{

  int arr[] = {12, 13, 15, 10, 35, 1};

  print2Smallest(arr, 6);

Page 390: Data structures all in one

  getchar();

  return 0;

}

The same approach can be used to find the largest and second largest elements in an array.

Time Complexity: O(n)

Data Structures and Algorithms | Set 9January 13, 2010

Follow questions have been asked in GATE CS exam.

1 In a heap with n elements with the smallest element at the root, the 7th smallest element can be found in time (GATE CS 2003)a)  (n log n)b)  (n)c)  (log n)d)  (1)

Answer(c)Given a Min-heap, to get the 7th smallest element, we need to call Extract-Min   7 times which means  (7logn)( =  (logn)) operations

2. Suppose the numbers 7, 5, 1, 8, 3, 6, 0, 9, 4, 2 are inserted in that order into an initially empty binary search tree. The binary search tree uses the usual ordering on natural numbers. What is the in-order traversal sequence of the resultant tree? (GATE CS 2003)a) 7 5 1 0 3 2 4 6 8 9b) 0 2 4 3 1 6 5 9 8 7c) 0 1 2 3 4 5 6 7 8 9d) 9 8 6 4 2 3 0 1 5 7

Answer (c)In-order traversal of a BST gives elements in increasing order. So answer c is correct without any doubt.

Page 391: Data structures all in one

3. Let S be a stack of size n >= 1. Starting with the empty stack, suppose we push the first n natural numbers in sequence, and then perform n pop operations. Assume that Push and Pop operation take X seconds each, and Y seconds elapse between the end of one such stack operation and the start of the next operation. For m >= 1, define the stack-life of m as the time elapsed from the end of Push(m) to the start of the pop operation that removes m from S. The average stack-life of an element of this stack is (GATE CS 2003)a) n(X+ Y)b) 3Y + 2Xc) n(X + Y)-Xd) Y + 2X

Answer(c)We can easily arrive at the result by taking few examples.

G-Fact 1January 31, 2010

In C language, sizeof( ) is an operator. Though it looks like a function, it is an unary operator.

G-Fact 2January 31, 2010

To know the IP address(es) of a URL/website, nslookup can be used at the shell/command prompt (cmd.exe). It works on both types of operating systems i.e. Linux/Windows. For example, to know the IP address of our website, type nslookup www.geeksforgeeks.org at the shell/command prompt.

G-Fact 3January 31, 2010

In ISO C, you can define main either to take no arguments, or to take two arguments that represent the command line arguments to the program, like this:

int main (int argc, char *argv[])

Page 392: Data structures all in one

Other platform-dependent formats are also allowed by the C and C++ standards; for example, Unix (though not POSIX.1) and Microsoft Visual C++ have a third argument giving the program’s environment, otherwise accessible through getenv in stdlib.h:

What all is inherited from parent class in C++?January 31, 2010

Following are the things which a derived class inherits from its parent.1) Every data member defined in the parent class (although such members may not always beaccessible in the derived class!)2) Every ordinary member function of the parent class (although such members may not always beaccessible in the derived class!)3) The same initial data layout as the base class.

Following are the things which a derived class doesn’t inherits from its parent :1) The base class’s constructors and destructor.2) The base class’s friends

Pointer vs Array in CJanuary 31, 2010

Most of the time, pointer and array accesses can be treated as acting the same, the major exceptions being:

1) the sizeof operatoro sizeof(array) returns the amount of memory used by all elements in arrayo sizeof(pointer) only returns the amount of memory used by the pointer variable itself2) the & operatoro &array is an alias for &array[0] and returns the address of the first element in arrayo &pointer returns the address of pointer3) a string literal initialization of a character array

Page 393: Data structures all in one

o char array[] = “abc” sets the first four elements in array to ‘a’, ‘b’, ‘c’, and ‘\0′o char *pointer = “abc” sets pointer to the address of the “abc” string (which may be stored in read-only memory and thus unchangeable)

References: http://icecube.wisc.edu/~dglo/c_class/array_ptr.html

G-Fact 4January 31, 2010

In C, function parameters are always passed by value. Pass-by-reference is simulated in C by explicitly passing pointer values.

Output of C Programs | Set 10January 31, 2010

Predict the output of the below programs.

Difficulty Level: Rookie

Question 1

#include<stdio.h>

int main()

{

   typedef int i;

   i a = 0;

   printf("%d", a);

   getchar();

   return 0;

}

Output: 0There is no problem with the program. It simply creates a user defined type i and creates a variable a of type i.

Page 394: Data structures all in one

Question 2

#include<stdio.h>

int main()

{

  typedef int *i;

  int j = 10;

  i *a = &j;

  printf("%d", **a);

  getchar();

  return 0;

}

Output: Compiler Error -> Initialization with incompatible pointer type.The line typedef int *i makes i as type int *. So, the declaration of a means a is pointer to a pointer. The Error message may be different on different compilers.

Question 3

#include<stdio.h>

int main()

{

  typedef static int *i;

  int j;

  i a = &j;

  printf("%d", *a);

  getchar();

  return 0;

Page 395: Data structures all in one

}

Output: Compiler Error -> Multiple Storage classes for a.In C, typedef is considered as a storage class. The Error message may be different on different compilers.

Please write comments if you find any of the answers/explanations incorrect, or you want to share more information about the topics discussed above.

References:http://www.itee.uq.edu.au/~comp2303/Leslie_C_ref/C/SYNTAX/typedef.htmlhttp://publib.boulder.ibm.com/infocenter/macxhelp/v6v81/index.jsp?topic=/com.ibm.vacpp6m.doc/language/ref/clrc03sc03.htmhttp://msdn.microsoft.com/en-us/library/4x7sfztk.aspx