Skip to content

Commit e9778e2

Browse files
committed
Add solution for exercise 3.23
1 parent 54edbd6 commit e9778e2

File tree

2 files changed

+115
-1
lines changed

2 files changed

+115
-1
lines changed

README.org

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
习题完成情况:
2626
- 章节一: 43/46
2727
- 章节二: 88/97
28-
- 章节三: 22/82
28+
- 章节三: 23/82
2929
- 章节四: TODO
3030
- 章节五: TODO
3131
* 运行

chapter3/exercise3-23.rkt

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
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

Comments
 (0)