|
| 1 | +#lang racket |
| 2 | + |
| 3 | +(define (make-deque) |
| 4 | + (mcons '() '())) |
| 5 | +;;; 比对单链表的队列,为了实现可以在两端进行插入和删除操作,势必需要 |
| 6 | +;;; 两个指针,一个指向前节点,一个指向后节点 |
| 7 | +(define (make-node value prev next) |
| 8 | + (mcons value (mcons prev next))) |
| 9 | + |
| 10 | +(define (node-value node) (mcar node)) |
| 11 | +(define (node-prev node) (mcar (mcdr node))) |
| 12 | +(define (node-next node) (mcdr (mcdr node))) |
| 13 | +(define (set-node-prev! node prev) (set-mcar! (mcdr node) prev)) |
| 14 | +(define (set-node-next! node next) (set-mcdr! (mcdr node) next)) |
| 15 | + |
| 16 | +;;; 选择函数 |
| 17 | +(define (empty-deque? deque) |
| 18 | + (null? (mcar deque))) |
| 19 | + |
| 20 | +(define (front-deque deque) |
| 21 | + (if (empty-deque? deque) |
| 22 | + (error "FRONT called with an empty deque") |
| 23 | + (node-value (mcar deque)))) |
| 24 | + |
| 25 | +(define (rear-deque deque) |
| 26 | + (if (empty-deque? deque) |
| 27 | + (error "REAR called with an empty deque") |
| 28 | + (node-value (mcdr deque)))) |
| 29 | + |
| 30 | +;;; 插入操作 |
| 31 | +(define (front-insert-deque! deque value) |
| 32 | + (let ((new-node (make-node value '() (mcar deque)))) |
| 33 | + (cond ((empty-deque? deque) |
| 34 | + (set-mcar! deque new-node) |
| 35 | + (set-mcdr! deque new-node)) |
| 36 | + (else |
| 37 | + (set-node-prev! (mcar deque) new-node) |
| 38 | + (set-mcar! deque new-node)))) |
| 39 | + deque) |
| 40 | + |
| 41 | +(define (rear-insert-deque! deque value) |
| 42 | + (let ((new-node (make-node value (mcdr deque) '()))) |
| 43 | + (cond ((empty-deque? deque) |
| 44 | + (set-mcar! deque new-node) |
| 45 | + (set-mcdr! deque new-node)) |
| 46 | + (else |
| 47 | + (set-node-next! (mcdr deque) new-node) |
| 48 | + (set-mcdr! deque new-node)))) |
| 49 | + deque) |
| 50 | + |
| 51 | +;;; 删除操作 |
| 52 | +(define (front-delete-deque! deque) |
| 53 | + (cond ((empty-deque? deque) |
| 54 | + (error "FRONT-DELETE! called with an empty deque")) |
| 55 | + ;; 只有一个元素 |
| 56 | + ((null? (node-next (mcar deque))) |
| 57 | + (set-mcar! deque '()) |
| 58 | + (set-mcdr! deque '())) |
| 59 | + (else |
| 60 | + (set-mcar! deque (node-next (mcar deque))) |
| 61 | + (set-node-prev! (mcar deque) '()))) |
| 62 | + deque) |
| 63 | + |
| 64 | +(define (rear-delete-deque! deque) |
| 65 | + (cond ((empty-deque? deque) |
| 66 | + (error "REAR-DELETE! called with an empty deque")) |
| 67 | + ((null? (node-prev (mcdr deque))) |
| 68 | + (set-mcar! deque '()) |
| 69 | + (set-mcdr! deque '()) |
| 70 | + ) |
| 71 | + (else |
| 72 | + (set-mcdr! deque (node-prev (mcdr deque))) |
| 73 | + (set-node-next! (mcdr deque) '()))) |
| 74 | + deque) |
| 75 | + |
| 76 | +(define (print-deque deque) |
| 77 | + (define (iter node) |
| 78 | + (if (null? node) |
| 79 | + '() |
| 80 | + (mcons (node-value node) (iter (node-next node))))) |
| 81 | + (iter (mcar deque))) |
| 82 | + |
| 83 | +(module+ test |
| 84 | + (require rackunit) |
| 85 | + |
| 86 | + (test-case "Test for deque" |
| 87 | + (define dq (make-deque)) |
| 88 | + (check-true (empty-deque? dq)) |
| 89 | + |
| 90 | + (front-insert-deque! dq 'a) |
| 91 | + (check-equal? (front-deque dq) 'a) |
| 92 | + (check-equal? (rear-deque dq) 'a) |
| 93 | + |
| 94 | + (front-insert-deque! dq 'b) ;; b -> a |
| 95 | + (check-equal? (front-deque dq) 'b) |
| 96 | + (check-equal? (rear-deque dq) 'a) |
| 97 | + |
| 98 | + (rear-insert-deque! dq 'c) ;; b -> a -> c |
| 99 | + (check-equal? (front-deque dq) 'b) |
| 100 | + (check-equal? (rear-deque dq) 'c) |
| 101 | + |
| 102 | + (front-delete-deque! dq) ;; a -> c |
| 103 | + (check-equal? (front-deque dq) 'a) |
| 104 | + (check-equal? (rear-deque dq) 'c) |
| 105 | + |
| 106 | + (rear-delete-deque! dq) ;; a |
| 107 | + (check-equal? (front-deque dq) 'a) |
| 108 | + (check-equal? (rear-deque dq) 'a) |
| 109 | + (check-false (empty-deque? dq)) |
| 110 | + |
| 111 | + (rear-delete-deque! dq) |
| 112 | + (check-true (empty-deque? dq)) |
| 113 | + ) |
| 114 | + ) |
0 commit comments