Programme1 2000/2001

Recherche du maximum dans un tableau trié décalé

Vous avez vu en cours le principe de la recherche d'un élément dans un tableau trié, faite de manière dichotomique. Une implémentation de la recherche dichotomique vous est proposée ci-dessous. Ce programme calcule en outre le nombre de comparaisons effectuées avec des éléments du tableau. On ne compte pas les comparaisons entre indices (telles que (droite>=gauche)), mais les comparaisons, soit entre x et un élément du tableau, soit entre deux éléments du tableau. L'idée étant que, même si dans le cas présent nous avons affaire à un tableau d'entiers, dans le cas général les éléments sont des objets complexes et la comparaison entre deux éléments est une opération coûteuse. Ce sont donc ces opérations que nous comptons.


#include <stdio.h>
#define N 1024
typedef enum {
  false,
  true
} boolean;
/** t[0..taille-1] est un tableau trie dans l'ordre croissant, valeur est l'element 
    a rechercher dans t; cette fonction retourne true ssi "valeur" est dans t,
    et dans ce cas elle modifie la valeur sur laquelle pointe nbcomp_ptr en lui 
    ajoutant le nombre de comparaisons effectuees avec des elements de t.**/
boolean RechercheDichotomique (int t[], int taille, int valeur, 
          int *resultat_ptr, int *nbcomp_ptr)
{ int gauche=0, droite=taille-1, milieu;
 boolean fini=false, succes;
  while (!fini)  
    { milieu=( gauche + droite)/2;
      (*nbcomp_ptr)++; 
      if (valeur == t[milieu]) 
        {fini=true; succes=true; *resultat_ptr=milieu;}
      else {(*nbcomp_ptr)++; 
            if ( valeur < t[milieu]) 
                droite = milieu-1;
            else 
                gauche = milieu+1;
            if (droite < gauche)
               {fini=true; succes=false;}
           }
    }
  return (succes);
}
main()
{ int t[N];  
  int i, taille, valeur, resultat, nbcomp=0;
  boolean trouve;
  /** Entree du programme pourcorrection automatique (aucun test d'erreur)**/  
  scanf("%d", &taille);
  for (i=0; i<taille; i++)
        scanf("%d", &t[i]); 
  scanf("%d", &valeur);
  /** Calcul **/
  trouve = RechercheDichotomique(t, taille, valeur, &resultat, &nbcomp);
  /** Affichage pour correction automatique **/
  if (trouve)     
    {printf("%d %d\n", resultat, nbcomp);}
  else
    {printf("%d n'est pas dans le tableau.\n",valeur);}    
}
Nous vous demandons de résoudre par une méthode similaire le problème suivant. Votre programme sera corrigé automatiquement, il est donc important de satisfaire aux spécifications ci-dessous.

Entrée. On se donne un tableau d'entiers t[0..n-1], qui représente le décalage circulaire d'un tableau trié : autrement dit, il existe une valeur k telle que

t[k+1 mod n] < t[k+2 mod n] < ... < t[k mod n].

Par exemple, le tableau 3,4,6,8,1,2 satisfait à cette condition avec k=3 et n=6. On ne connaît pas la valeur de k. Le format d'entrée consiste en un premier entier donnant n, suivi par une suite de n entiers qui sont les n éléments du tableau, t[0] t[1] ... t[n-1]. Par exemple voici une entrée possible : 5 30 40 10 20 30

Sortie. Le but de votre programme est de déterminer la valeur de l'élément maximum du tableau. Le programme doit également donner le nombre de comparaisons effectuées entre éléments du tableau.
Le format de sortie consiste en un premier entier donnant la valeur de l'élément maximum du tableau, suivi d'un deuxième entier donnant le nombre de comparaisons effectuées entre éléments du tableau. Par exemple: 40 2

Contrainte d'efficacité. L'algorithme de recherche dichotomique fait au plus log2(n) comparaisons avec des éléments du tableau. Votre solution pour le problème du maximum décalé doit également satisfaire à cette propriété.

Jeu de tests. Sur les données ci-dessous, le programme du corrigé donne les réponses suivantes.

Données d'entrée Sortie
1 5 5 0
10 10 20 30 40 50 60 70 80 90 100 100 4
10 20 30 40 50 60 70 80 90 100 10 100 4
10 30 40 50 60 70 80 90 100 10 20 100 3
10 40 50 60 70 80 90 100 10 20 30 100 3
10 50 60 70 80 90 100 10 20 30 40 100 3
10 60 70 80 90 100 10 20 30 40 50 100 4
10 70 80 90 100 10 20 30 40 50 60 100 4
10 80 90 100 10 20 30 40 50 60 70 100 3
10 90 100 10 20 30 40 50 60 70 80 100 3
10 100 10 20 30 40 50 60 70 80 90 100 3