Reverse A Linked List
November 12, 2019
We begin with a simple list:
(define xs '(1 2 3 4 5 6 7))
Scheme provides a built-in function to reverse a list; it returns a newly-allocated list and does not modify the original list:
> (reverse xs) (7 6 5 4 3 2 1) > xs (1 2 3 4 5 6 7)
We write a function rev
that does the same thing as Scheme’s reverse
:
(define (rev xs) (let loop ((xs xs) (zs (list))) (if (null? xs) zs (loop (cdr xs) (cons (car xs) zs)))))
> (rev xs) (7 6 5 4 3 2 1) > xs (1 2 3 4 5 6 7)
Sometimes you want to reverse a list in-place:
(define (rev! xs) (let loop ((prev (list)) (curr xs)) (if (null? curr) prev (let ((next (cdr curr))) (set-cdr! curr prev) (loop curr next)))))
> (set! xs (rev! xs)) > xs (7 6 5 4 3 2 1) > (set! xs (rev! xs)) > xs (1 2 3 4 5 6 7)
You can run the program at https://ideone.com/Vz2Qi7.
Here’s a solution in C.
Example:
Here’s a variation on Daniel’s solution, using some C++ features. The actual in-place list reverse is neatly expressed as an iterated rotation of list elements: