Research - Scripts - cinema - lyrics - Sport - Poemes

هل تريد التفاعل مع هذه المساهمة؟ كل ما عليك هو إنشاء حساب جديد ببضع خطوات أو تسجيل الدخول للمتابعة.
Research - Scripts - cinema - lyrics - Sport - Poemes

عــلوم ، دين ـ قرآن ، حج ، بحوث ، دراسات أقســام علمية و ترفيهية .


    Le tri par fusion

    avatar
    GODOF
    Admin
    Admin


    عدد المساهمات : 10329
    نقــــاط التمـــيز : 61741
    تاريخ التسجيل : 08/04/2009
    العمر : 33

    Le tri par fusion Empty Le tri par fusion

    مُساهمة من طرف GODOF الأحد 30 أغسطس - 13:32

    Une autre procédure récursive pour faire le tri est le tri par fusion (ou par interclassement). La méthode provient du tri sur bande magnétique (périphérique autrefois fort utile des ordinateurs). C'est aussi un exemple de la méthode Divide and Conquer. On remarque d'abord qu'il est aisé de faire l'interclassement entre deux suites de nombres triés dans l'ordre croissant. En effet, soient á a1, a2, ... aM ñ et á b1, b2, ... bN ñ ces deux suites. Pour obtenir, la suite interclassée á c1, c2, ... cM+N ñ des ai et bj, il suffit de faire le programme suivant. (On suppose que l'on met deux sentinelles aM+1 = ¥ et bN+1 = ¥ pour ne pas compliquer la structure du programme.)

    int[] a = new int[M+1],
    b = new int[N+1],
    c = new int[M+N];

    int i = 0, j = 0;

    a[M+1] = b[N+1] = Integer.MAX_VALUE;

    for (int k = 0; k < M+N; ++k)
    if (a <= b[j]) {
    c[k] = a[i];
    ++i;
    } else {
    c[k] = b[j];
    ++j;
    }
    Successivement, [i]c
    k devient le minimum de ai et bj en décalant l'endroit où l'on se trouve dans la suite a ou b selon le cas choisi. L'interclassement de M et N éléments se fait donc en O(M+N) opérations. Pour faire le tri fusion, en appliquant Divide and Conquer, on trie les deux moitiés de la suite á a1, a2, ... aN ñ à trier, et on interclasse les deux moitiés triées. Il y a toutefois une difficulté car on doit copier dans un tableau annexe les 2 moitiés à trier, puisqu'on ne sait pas faire l'interclassement en place. Si g et d sont les bornes à gauche et à droite des indices du tableau à trier, le tri fusion est donc

    static void TriFusion(int g, int d) {

    int i, j, k, m;

    if (g < d) {
    m = (g + d) / 2;
    TriFusion (g, m);
    TriFusion (m + 1, d);
    for (i = m; i >= g; --i)
    b = a[i];
    for (j = m+1; j <= d; ++j)
    b[d+m+1-j] = a[j];
    i = g; j = d;
    for (k = g; k <= d; ++k)
    if (b[i] < b[j]) {
    a[k] = b[i]; ++i;
    } else {
    a[k] = b[j]; --j;
    }
    }
    }
    La recopie pour faire l'interclassement se fait dans un tableau b de même taille que a. Il y a une petite astuce en recopiant une des deux moitiés dans l'ordre inverse, ce qui permet de se passer de sentinelles pour l'interclassement, puisque chaque moitié sert de sentinelle pour l'autre moitié. Le tri par fusion a une très grande vertu. Son nombre d'opérations [i]C
    N est tel que CN = 2 N + 2 CN/2, et donc CN = O(N log N). Donc le tri fusion est un tri qui garantit un temps N log N, au prix d'un tableau annexe de N éléments. Ce temps est réalisé quelle que soit la distribution des données, à la différence de QuickSort. Plusieurs problèmes se posent immédiatement: peut on faire mieux? Faut-il utiliser ce tri plutôt que QuickSort?

    Nous répondrons plus tard ``non'' à la première question, voir section 1. Quant à la deuxième question, on peut remarquer que si ce tri garantit un bon temps, la constante petite devant N log N de QuickSort fait que ce dernier est souvent meilleur. Aussi, QuickSort utilise moins de mémoire annexe, puisque le tri fusion demande un tableau qui est aussi important que celui à trier. Enfin, on peut remarquer qu'il existe une version itérative du tri par fusion en commençant par trier des sous-suites de longueur 2, puis de longueur 4, 8, 16, ....


    2.7 Programmes en Caml

    (* Fibonaci, voir page X *)
    let rec fib n =
    if n <= 1 then 1
    else fib (n - 1) + fib ( n - 2);;
    (* Factorielle, voir page X *)
    let rec fact n =
    if n <= 1 then 1
    else n * fact (n - 1);;
    (* Triangle de Pascal, voir page X *)
    let rec C n p =
    if n = 0 || p = n then 1
    else C (n - 1) (p - 1) + C (n - 1) p;;
    (* Fibonaci itératif, voir page X *)
    let fib n =
    let u = ref 1 and v = ref 1 in
    for i = 2 to n do
    let u0 = !u and v0 = !v in
    u := u0 + v0;
    v := u0
    done;
    !u;;

    (* Le même en style fonctionnel *)
    let fib n =
    let rec fib_aux k u v =
    if k > n then u
    else fib_aux (k + 1) (u + v) u in
    fib_aux 2 1 1;;
    (* La fonction d'Ackermann, voir page X *)
    let rec ack m n =
    if m = 0 then n + 1 else
    if n = 0 then ack (m - 1) 1 else
    ack (m - 1) (ack m (n - 1));;
    (* La fonction 91, voir page X *)
    let rec f91 n =
    if n > 100 then n - 10
    else f91 (f91 (n + 11));;
    (* La fonction de Morris, voir page X *)
    let rec g m n =
    if m = 0 then 1
    else g (m - 1) (g m n);;
    (* Les tours de Hanoi, voir page X *)
    let rec hanoi n i j =
    if n > 0 then begin
    hanoi (n - 1) i (6 - (i + j));
    printf "%d -> %d\n" i j;
    hanoi (n - 1) (6 - (i + j)) j;
    end;;
    #open "graphics";;
    open_graph "";;

    let rec dragon n x y z t =
    if n = 1 then begin
    moveto x y;
    lineto z t
    end else begin
    let u = (x + z + t - y) / 2
    and v = (y + t - z + x) / 2 in
    dragon (n - 1) x y u v;
    dragon (n - 1) z t u v
    end;;
    (* La courbe du dragon, voir page X *)
    let rec dragon n x y z t =
    if n = 1 then begin
    moveto x y;
    lineto z t
    end else begin
    let u = (x + z + t - y) / 2
    and v = (y + t - z + x) / 2 in
    dragon (n - 1) x y u v;
    dragon_bis (n - 1) u v z t
    end

    and dragon_bis n x y z t =
    if n = 1 then begin
    moveto x y;
    lineto z t
    end else begin
    let u = (x + z - t + y) / 2
    and v = (y + t + z - x) / 2 in
    dragon (n - 1) x y u v;
    dragon_bis (n - 1) u v z t
    end;;

    clear_graph();;
    dragon 15 120 120 50 50;;
    (* Quicksort, voir page X *)

    let rec qsort g d =
    if g < d then begin
    let v = a.(g)
    and m = ref g in
    for i = g + 1 to d do
    if a.(i) < v then begin
    m := !m + 1;
    let x = a.(!m) in
    a.(!m) <- a.(i); a.(i) <- x
    end
    done;
    let x = a.(!m) in
    a.(!m) <- a.(g); a.(g) <- x;
    qsort g (!m - 1);
    qsort (!m + 1) d
    end;;
    (* Quicksort, voir page X *)
    let rec quicksort g d =
    if g < d then begin
    let v = a.(d)
    and t = ref 0
    and i = ref (g - 1)
    and j = ref d in
    while j > i do
    incr i;
    while a.(!i) < v do incr i done;
    decr j;
    while a.(!j) > v do decr j done;
    t := a.(!i);
    a.(!i) <- a.(!j);
    a.(!j) <- !t
    done;
    a.(!j) <- a.(!i);
    a.(!i) <- a.(d);
    a.(d) <- !t;
    quicksort g (!i - 1);
    quicksort (!i + 1) d
    end;;
    (* Tri fusion, voir page X *)

    let b = make_vect n 0;;

    let rec tri_fusion g d =
    if g < d then begin
    let m = (g + d) / 2 in
    tri_fusion g m;
    tri_fusion (m + 1) d;
    for i = m downto g do
    b.(i) <- a.(i) done;
    for i = m + 1 to d do
    b.(d + m + 1 - i) <- a.(i) done;
    let i = ref g and j = ref d in
    for k = g to d do
    if b.(!i) < b.(!j) then begin
    a.(k) <- b.(!i); incr i
    end else begin
    a.(k) <- b.(!j); decr j
    end
    done
    end;;

      الوقت/التاريخ الآن هو الجمعة 15 نوفمبر - 7:59