Normalize the amount to , with ; negative then naturally denotes a right rotation. When , return without touching the elements. Otherwise the map has disjoint permutation cycles, each of length . Use representatives :The conditional calculation of
PROCEDURE RotateLeft(k: INTEGER);
VAR r, g, x, y, h, s, j, next: INTEGER; saved: T;
BEGIN
r := k MOD N;
IF r # 0 THEN
x := N; y := r;
WHILE y # 0 DO h := x MOD y; x := y; y := h END;
g := x; s := 0;
WHILE s < g DO
saved := a[s]; j := s;
IF j >= N-r THEN next := j-(N-r) ELSE next := j+r END;
WHILE next # s DO
a[j] := a[next]; j := next;
IF j >= N-r THEN next := j-(N-r) ELSE next := j+r END
END;
a[j] := saved; s := s+1
END
END
END RotateLeft;next implements addition modulo without first forming a possibly overflowing j+r. Oberon's MOD with positive divisor supplies the nonnegative remainder. The first loop is the Euclidean algorithm, with loop invariant and decreasing nonzero remainder.For the outer loop, cycles with representatives below
s are complete and every other cycle retains its original values. In one cycle, write . The inner loop invariant is saved = A[s], , and for , with the remaining sources still untouched. When the next index returns to s, the saved value closes the cycle. The cycle length is : writing and with , the least positive with is . Each residue class modulo is one cycle, justifying the chosen representatives.Every element is read once and written once: element accesses, compared with for repetitions of part (b). The zero rotation uses none. The running time is and auxiliary space is constant; the original array is proof notation, not a copy made by the program.
Articles by others on the same topic
There are currently no matching articles.