Mercurial > emacs
comparison lisp/emacs-lisp/avl-tree.el @ 83676:27d11c1d4e46
Merge from emacs--devo--0
Patches applied:
* emacs--devo--0 (patch 857-862)
- Update from CVS
- Merge from emacs--rel--22
- Update from CVS: lisp/emacs-lisp/avl-tree.el: New file.
* emacs--rel--22 (patch 97-100)
- Update from CVS
- Merge from gnus--rel--5.10
* gnus--rel--5.10 (patch 246-247)
- Update from CVS
Revision: emacs@sv.gnu.org/emacs--multi-tty--0--patch-38
author | Miles Bader <miles@gnu.org> |
---|---|
date | Mon, 27 Aug 2007 09:21:49 +0000 |
parents | 7224e10a56f5 |
children | 17a8beea7b8c |
comparison
equal
deleted
inserted
replaced
83675:67601f702028 | 83676:27d11c1d4e46 |
---|---|
1 ;;; avl-tree.el --- balanced binary trees, AVL-trees | |
2 | |
3 ;; Copyright (C) 1995, 2007 Free Software Foundation, Inc. | |
4 | |
5 ;; Author: Per Cederqvist <ceder@lysator.liu.se> | |
6 ;; Inge Wallin <inge@lysator.liu.se> | |
7 ;; Thomas Bellman <bellman@lysator.liu.se> | |
8 ;; Maintainer: FSF | |
9 ;; Created: 10 May 1991 | |
10 ;; Keywords: extensions, data structures | |
11 | |
12 ;; This file is part of GNU Emacs. | |
13 | |
14 ;; GNU Emacs is free software; you can redistribute it and/or modify | |
15 ;; it under the terms of the GNU General Public License as published by | |
16 ;; the Free Software Foundation; either version 3, or (at your option) | |
17 ;; any later version. | |
18 | |
19 ;; GNU Emacs is distributed in the hope that it will be useful, | |
20 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
21 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
22 ;; GNU General Public License for more details. | |
23 | |
24 ;; You should have received a copy of the GNU General Public License | |
25 ;; along with GNU Emacs; see the file COPYING. If not, write to the | |
26 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | |
27 ;; Boston, MA 02110-1301, USA. | |
28 | |
29 ;;; Commentary: | |
30 | |
31 ;; An AVL tree is a nearly-perfect balanced binary tree. A tree | |
32 ;; consists of two cons cells, the first one holding the tag | |
33 ;; 'AVL-TREE in the car cell, and the second one having the tree | |
34 ;; in the car and the compare function in the cdr cell. The tree has | |
35 ;; a dummy node as its root with the real tree in the left pointer. | |
36 ;; | |
37 ;; Each node of the tree consists of one data element, one left | |
38 ;; sub-tree and one right sub-tree. Each node also has a balance | |
39 ;; count, which is the difference in depth of the left and right | |
40 ;; sub-trees. | |
41 ;; | |
42 ;; The "public" functions (prefixed with "avl-tree") are: | |
43 ;; -create, -p, -compare-function, -empty, -enter, -delete, | |
44 ;; -member, -map, -first, -last, -copy, -flatten, -size, -clear. | |
45 | |
46 ;;; Code: | |
47 | |
48 ;;; ================================================================ | |
49 ;;; Functions and macros handling an AVL tree node. | |
50 | |
51 (defmacro avl-tree-node-create (left right data balance) | |
52 ;; Create and return an avl-tree node. | |
53 `(vector ,left ,right ,data ,balance)) | |
54 | |
55 (defmacro avl-tree-node-left (node) | |
56 ;; Return the left pointer of NODE. | |
57 `(aref ,node 0)) | |
58 | |
59 (defmacro avl-tree-node-right (node) | |
60 ;; Return the right pointer of NODE. | |
61 `(aref ,node 1)) | |
62 | |
63 (defmacro avl-tree-node-data (node) | |
64 ;; Return the data of NODE. | |
65 `(aref ,node 2)) | |
66 | |
67 (defmacro avl-tree-node-set-left (node newleft) | |
68 ;; Set the left pointer of NODE to NEWLEFT. | |
69 `(aset ,node 0 ,newleft)) | |
70 | |
71 (defmacro avl-tree-node-set-right (node newright) | |
72 ;; Set the right pointer of NODE to NEWRIGHT. | |
73 `(aset ,node 1 ,newright)) | |
74 | |
75 (defmacro avl-tree-node-set-data (node newdata) | |
76 ;; Set the data of NODE to NEWDATA. | |
77 `(aset ,node 2 ,newdata)) | |
78 | |
79 (defmacro avl-tree-node-branch (node branch) | |
80 "Get value of a branch of a node. | |
81 | |
82 NODE is the node, and BRANCH is the branch. | |
83 0 for left pointer, 1 for right pointer and 2 for the data.\"" | |
84 `(aref ,node ,branch)) | |
85 | |
86 (defmacro avl-tree-node-set-branch (node branch newval) | |
87 "Set value of a branch of a node. | |
88 | |
89 NODE is the node, and BRANCH is the branch. | |
90 0 for left pointer, 1 for the right pointer and 2 for the data. | |
91 NEWVAL is new value of the branch.\"" | |
92 `(aset ,node ,branch ,newval)) | |
93 | |
94 (defmacro avl-tree-node-balance (node) | |
95 ;; Return the balance field of a node. | |
96 `(aref ,node 3)) | |
97 | |
98 (defmacro avl-tree-node-set-balance (node newbal) | |
99 ;; Set the balance field of a node. | |
100 `(aset ,node 3 ,newbal)) | |
101 | |
102 | |
103 ;;; ================================================================ | |
104 ;;; Internal functions for use in the AVL tree package | |
105 | |
106 (defmacro avl-tree-root (tree) | |
107 ;; Return the root node for an avl-tree. INTERNAL USE ONLY. | |
108 `(avl-tree-node-left (car (cdr ,tree)))) | |
109 | |
110 (defmacro avl-tree-dummyroot (tree) | |
111 ;; Return the dummy node of an avl-tree. INTERNAL USE ONLY. | |
112 `(car (cdr ,tree))) | |
113 | |
114 (defmacro avl-tree-cmpfun (tree) | |
115 ;; Return the compare function of AVL tree TREE. INTERNAL USE ONLY. | |
116 `(cdr (cdr ,tree))) | |
117 | |
118 ;; ---------------------------------------------------------------- | |
119 ;; Deleting data | |
120 | |
121 (defun avl-tree-del-balance1 (node branch) | |
122 ;; Rebalance a tree and return t if the height of the tree has shrunk. | |
123 (let ((br (avl-tree-node-branch node branch)) | |
124 p1 b1 p2 b2 result) | |
125 (cond | |
126 ((< (avl-tree-node-balance br) 0) | |
127 (avl-tree-node-set-balance br 0) | |
128 t) | |
129 | |
130 ((= (avl-tree-node-balance br) 0) | |
131 (avl-tree-node-set-balance br +1) | |
132 nil) | |
133 | |
134 (t | |
135 ;; Rebalance. | |
136 (setq p1 (avl-tree-node-right br) | |
137 b1 (avl-tree-node-balance p1)) | |
138 (if (>= b1 0) | |
139 ;; Single RR rotation. | |
140 (progn | |
141 (avl-tree-node-set-right br (avl-tree-node-left p1)) | |
142 (avl-tree-node-set-left p1 br) | |
143 (if (= 0 b1) | |
144 (progn | |
145 (avl-tree-node-set-balance br +1) | |
146 (avl-tree-node-set-balance p1 -1) | |
147 (setq result nil)) | |
148 (avl-tree-node-set-balance br 0) | |
149 (avl-tree-node-set-balance p1 0) | |
150 (setq result t)) | |
151 (avl-tree-node-set-branch node branch p1) | |
152 result) | |
153 | |
154 ;; Double RL rotation. | |
155 (setq p2 (avl-tree-node-left p1) | |
156 b2 (avl-tree-node-balance p2)) | |
157 (avl-tree-node-set-left p1 (avl-tree-node-right p2)) | |
158 (avl-tree-node-set-right p2 p1) | |
159 (avl-tree-node-set-right br (avl-tree-node-left p2)) | |
160 (avl-tree-node-set-left p2 br) | |
161 (if (> b2 0) | |
162 (avl-tree-node-set-balance br -1) | |
163 (avl-tree-node-set-balance br 0)) | |
164 (if (< b2 0) | |
165 (avl-tree-node-set-balance p1 +1) | |
166 (avl-tree-node-set-balance p1 0)) | |
167 (avl-tree-node-set-branch node branch p2) | |
168 (avl-tree-node-set-balance p2 0) | |
169 t))))) | |
170 | |
171 (defun avl-tree-del-balance2 (node branch) | |
172 (let ((br (avl-tree-node-branch node branch)) | |
173 p1 b1 p2 b2 result) | |
174 (cond | |
175 ((> (avl-tree-node-balance br) 0) | |
176 (avl-tree-node-set-balance br 0) | |
177 t) | |
178 | |
179 ((= (avl-tree-node-balance br) 0) | |
180 (avl-tree-node-set-balance br -1) | |
181 nil) | |
182 | |
183 (t | |
184 ;; Rebalance. | |
185 (setq p1 (avl-tree-node-left br) | |
186 b1 (avl-tree-node-balance p1)) | |
187 (if (<= b1 0) | |
188 ;; Single LL rotation. | |
189 (progn | |
190 (avl-tree-node-set-left br (avl-tree-node-right p1)) | |
191 (avl-tree-node-set-right p1 br) | |
192 (if (= 0 b1) | |
193 (progn | |
194 (avl-tree-node-set-balance br -1) | |
195 (avl-tree-node-set-balance p1 +1) | |
196 (setq result nil)) | |
197 (avl-tree-node-set-balance br 0) | |
198 (avl-tree-node-set-balance p1 0) | |
199 (setq result t)) | |
200 (avl-tree-node-set-branch node branch p1) | |
201 result) | |
202 | |
203 ;; Double LR rotation. | |
204 (setq p2 (avl-tree-node-right p1) | |
205 b2 (avl-tree-node-balance p2)) | |
206 (avl-tree-node-set-right p1 (avl-tree-node-left p2)) | |
207 (avl-tree-node-set-left p2 p1) | |
208 (avl-tree-node-set-left br (avl-tree-node-right p2)) | |
209 (avl-tree-node-set-right p2 br) | |
210 (if (< b2 0) | |
211 (avl-tree-node-set-balance br +1) | |
212 (avl-tree-node-set-balance br 0)) | |
213 (if (> b2 0) | |
214 (avl-tree-node-set-balance p1 -1) | |
215 (avl-tree-node-set-balance p1 0)) | |
216 (avl-tree-node-set-branch node branch p2) | |
217 (avl-tree-node-set-balance p2 0) | |
218 t))))) | |
219 | |
220 (defun avl-tree-do-del-internal (node branch q) | |
221 (let ((br (avl-tree-node-branch node branch))) | |
222 (if (avl-tree-node-right br) | |
223 (if (avl-tree-do-del-internal br +1 q) | |
224 (avl-tree-del-balance2 node branch)) | |
225 (avl-tree-node-set-data q (avl-tree-node-data br)) | |
226 (avl-tree-node-set-branch node branch | |
227 (avl-tree-node-left br)) | |
228 t))) | |
229 | |
230 (defun avl-tree-do-delete (cmpfun root branch data) | |
231 ;; Return t if the height of the tree has shrunk. | |
232 (let ((br (avl-tree-node-branch root branch))) | |
233 (cond | |
234 ((null br) | |
235 nil) | |
236 | |
237 ((funcall cmpfun data (avl-tree-node-data br)) | |
238 (if (avl-tree-do-delete cmpfun br 0 data) | |
239 (avl-tree-del-balance1 root branch))) | |
240 | |
241 ((funcall cmpfun (avl-tree-node-data br) data) | |
242 (if (avl-tree-do-delete cmpfun br 1 data) | |
243 (avl-tree-del-balance2 root branch))) | |
244 | |
245 (t | |
246 ;; Found it. Let's delete it. | |
247 (cond | |
248 ((null (avl-tree-node-right br)) | |
249 (avl-tree-node-set-branch root branch (avl-tree-node-left br)) | |
250 t) | |
251 | |
252 ((null (avl-tree-node-left br)) | |
253 (avl-tree-node-set-branch root branch (avl-tree-node-right br)) | |
254 t) | |
255 | |
256 (t | |
257 (if (avl-tree-do-del-internal br 0 br) | |
258 (avl-tree-del-balance1 root branch)))))))) | |
259 | |
260 ;; ---------------------------------------------------------------- | |
261 ;; Entering data | |
262 | |
263 (defun avl-tree-enter-balance1 (node branch) | |
264 ;; Rebalance a tree and return t if the height of the tree has grown. | |
265 (let ((br (avl-tree-node-branch node branch)) | |
266 p1 p2 b2 result) | |
267 (cond | |
268 ((< (avl-tree-node-balance br) 0) | |
269 (avl-tree-node-set-balance br 0) | |
270 nil) | |
271 | |
272 ((= (avl-tree-node-balance br) 0) | |
273 (avl-tree-node-set-balance br +1) | |
274 t) | |
275 | |
276 (t | |
277 ;; Tree has grown => Rebalance. | |
278 (setq p1 (avl-tree-node-right br)) | |
279 (if (> (avl-tree-node-balance p1) 0) | |
280 ;; Single RR rotation. | |
281 (progn | |
282 (avl-tree-node-set-right br (avl-tree-node-left p1)) | |
283 (avl-tree-node-set-left p1 br) | |
284 (avl-tree-node-set-balance br 0) | |
285 (avl-tree-node-set-branch node branch p1)) | |
286 | |
287 ;; Double RL rotation. | |
288 (setq p2 (avl-tree-node-left p1) | |
289 b2 (avl-tree-node-balance p2)) | |
290 (avl-tree-node-set-left p1 (avl-tree-node-right p2)) | |
291 (avl-tree-node-set-right p2 p1) | |
292 (avl-tree-node-set-right br (avl-tree-node-left p2)) | |
293 (avl-tree-node-set-left p2 br) | |
294 (if (> b2 0) | |
295 (avl-tree-node-set-balance br -1) | |
296 (avl-tree-node-set-balance br 0)) | |
297 (if (< b2 0) | |
298 (avl-tree-node-set-balance p1 +1) | |
299 (avl-tree-node-set-balance p1 0)) | |
300 (avl-tree-node-set-branch node branch p2)) | |
301 (avl-tree-node-set-balance (avl-tree-node-branch node branch) 0) | |
302 nil)))) | |
303 | |
304 (defun avl-tree-enter-balance2 (node branch) | |
305 ;; Return t if the tree has grown. | |
306 (let ((br (avl-tree-node-branch node branch)) | |
307 p1 p2 b2) | |
308 (cond | |
309 ((> (avl-tree-node-balance br) 0) | |
310 (avl-tree-node-set-balance br 0) | |
311 nil) | |
312 | |
313 ((= (avl-tree-node-balance br) 0) | |
314 (avl-tree-node-set-balance br -1) | |
315 t) | |
316 | |
317 (t | |
318 ;; Balance was -1 => Rebalance. | |
319 (setq p1 (avl-tree-node-left br)) | |
320 (if (< (avl-tree-node-balance p1) 0) | |
321 ;; Single LL rotation. | |
322 (progn | |
323 (avl-tree-node-set-left br (avl-tree-node-right p1)) | |
324 (avl-tree-node-set-right p1 br) | |
325 (avl-tree-node-set-balance br 0) | |
326 (avl-tree-node-set-branch node branch p1)) | |
327 | |
328 ;; Double LR rotation. | |
329 (setq p2 (avl-tree-node-right p1) | |
330 b2 (avl-tree-node-balance p2)) | |
331 (avl-tree-node-set-right p1 (avl-tree-node-left p2)) | |
332 (avl-tree-node-set-left p2 p1) | |
333 (avl-tree-node-set-left br (avl-tree-node-right p2)) | |
334 (avl-tree-node-set-right p2 br) | |
335 (if (< b2 0) | |
336 (avl-tree-node-set-balance br +1) | |
337 (avl-tree-node-set-balance br 0)) | |
338 (if (> b2 0) | |
339 (avl-tree-node-set-balance p1 -1) | |
340 (avl-tree-node-set-balance p1 0)) | |
341 (avl-tree-node-set-branch node branch p2)) | |
342 (avl-tree-node-set-balance (avl-tree-node-branch node branch) 0) | |
343 nil)))) | |
344 | |
345 (defun avl-tree-do-enter (cmpfun root branch data) | |
346 ;; Return t if height of tree ROOT has grown. INTERNAL USE ONLY. | |
347 (let ((br (avl-tree-node-branch root branch))) | |
348 (cond | |
349 ((null br) | |
350 ;; Data not in tree, insert it. | |
351 (avl-tree-node-set-branch | |
352 root branch (avl-tree-node-create nil nil data 0)) | |
353 t) | |
354 | |
355 ((funcall cmpfun data (avl-tree-node-data br)) | |
356 (and (avl-tree-do-enter cmpfun br 0 data) | |
357 (avl-tree-enter-balance2 root branch))) | |
358 | |
359 ((funcall cmpfun (avl-tree-node-data br) data) | |
360 (and (avl-tree-do-enter cmpfun br 1 data) | |
361 (avl-tree-enter-balance1 root branch))) | |
362 | |
363 (t | |
364 (avl-tree-node-set-data br data) | |
365 nil)))) | |
366 | |
367 ;; ---------------------------------------------------------------- | |
368 | |
369 (defun avl-tree-mapc (map-function root) | |
370 ;; Apply MAP-FUNCTION to all nodes in the tree starting with ROOT. | |
371 ;; The function is applied in-order. | |
372 ;; | |
373 ;; Note: MAP-FUNCTION is applied to the node and not to the data itself. | |
374 ;; INTERNAL USE ONLY. | |
375 (let ((node root) | |
376 (stack nil) | |
377 (go-left t)) | |
378 (push nil stack) | |
379 (while node | |
380 (if (and go-left | |
381 (avl-tree-node-left node)) | |
382 ;; Do the left subtree first. | |
383 (progn | |
384 (push node stack) | |
385 (setq node (avl-tree-node-left node))) | |
386 ;; Apply the function... | |
387 (funcall map-function node) | |
388 ;; and do the right subtree. | |
389 (if (avl-tree-node-right node) | |
390 (setq node (avl-tree-node-right node) | |
391 go-left t) | |
392 (setq node (pop stack) | |
393 go-left nil)))))) | |
394 | |
395 (defun avl-tree-do-copy (root) | |
396 ;; Copy the avl tree with ROOT as root. | |
397 ;; Highly recursive. INTERNAL USE ONLY. | |
398 (if (null root) | |
399 nil | |
400 (avl-tree-node-create | |
401 (avl-tree-do-copy (avl-tree-node-left root)) | |
402 (avl-tree-do-copy (avl-tree-node-right root)) | |
403 (avl-tree-node-data root) | |
404 (avl-tree-node-balance root)))) | |
405 | |
406 | |
407 ;;; ================================================================ | |
408 ;;; The public functions which operate on AVL trees. | |
409 | |
410 (defun avl-tree-create (compare-function) | |
411 "Create a new empty avl tree and return it. | |
412 COMPARE-FUNCTION is a function which takes two arguments, A and B, | |
413 and returns non-nil if A is less than B, and nil otherwise." | |
414 (cons 'AVL-TREE | |
415 (cons (avl-tree-node-create nil nil nil 0) | |
416 compare-function))) | |
417 | |
418 (defun avl-tree-p (obj) | |
419 "Return t if OBJ is an avl tree, nil otherwise." | |
420 (eq (car-safe obj) 'AVL-TREE)) | |
421 | |
422 (defun avl-tree-compare-function (tree) | |
423 "Return the comparison function for the avl tree TREE." | |
424 (avl-tree-cmpfun tree)) | |
425 | |
426 (defun avl-tree-empty (tree) | |
427 "Return t if avl tree TREE is emtpy, otherwise return nil." | |
428 (null (avl-tree-root tree))) | |
429 | |
430 (defun avl-tree-enter (tree data) | |
431 "In the avl tree TREE insert DATA. | |
432 Return DATA." | |
433 (avl-tree-do-enter (avl-tree-cmpfun tree) | |
434 (avl-tree-dummyroot tree) | |
435 0 | |
436 data) | |
437 data) | |
438 | |
439 (defun avl-tree-delete (tree data) | |
440 "From the avl tree TREE, delete DATA. | |
441 Return the element in TREE which matched DATA, | |
442 nil if no element matched." | |
443 (avl-tree-do-delete (avl-tree-cmpfun tree) | |
444 (avl-tree-dummyroot tree) | |
445 0 | |
446 data)) | |
447 | |
448 (defun avl-tree-member (tree data) | |
449 "Return the element in the avl tree TREE which matches DATA. | |
450 Matching uses the compare function previously specified in | |
451 `avl-tree-create' when TREE was created. | |
452 | |
453 If there is no such element in the tree, the value is nil." | |
454 (let ((node (avl-tree-root tree)) | |
455 (compare-function (avl-tree-cmpfun tree)) | |
456 found) | |
457 (while (and node | |
458 (not found)) | |
459 (cond | |
460 ((funcall compare-function data (avl-tree-node-data node)) | |
461 (setq node (avl-tree-node-left node))) | |
462 ((funcall compare-function (avl-tree-node-data node) data) | |
463 (setq node (avl-tree-node-right node))) | |
464 (t | |
465 (setq found t)))) | |
466 (if node | |
467 (avl-tree-node-data node) | |
468 nil))) | |
469 | |
470 (defun avl-tree-map (__map-function__ tree) | |
471 "Apply __MAP-FUNCTION__ to all elements in the avl tree TREE." | |
472 (avl-tree-mapc | |
473 (function (lambda (node) | |
474 (avl-tree-node-set-data | |
475 node (funcall __map-function__ | |
476 (avl-tree-node-data node))))) | |
477 (avl-tree-root tree))) | |
478 | |
479 (defun avl-tree-first (tree) | |
480 "Return the first element in TREE, or nil if TREE is empty." | |
481 (let ((node (avl-tree-root tree))) | |
482 (if node | |
483 (progn | |
484 (while (avl-tree-node-left node) | |
485 (setq node (avl-tree-node-left node))) | |
486 (avl-tree-node-data node)) | |
487 nil))) | |
488 | |
489 (defun avl-tree-last (tree) | |
490 "Return the last element in TREE, or nil if TREE is empty." | |
491 (let ((node (avl-tree-root tree))) | |
492 (if node | |
493 (progn | |
494 (while (avl-tree-node-right node) | |
495 (setq node (avl-tree-node-right node))) | |
496 (avl-tree-node-data node)) | |
497 nil))) | |
498 | |
499 (defun avl-tree-copy (tree) | |
500 "Return a copy of the avl tree TREE." | |
501 (let ((new-tree (avl-tree-create (avl-tree-cmpfun tree)))) | |
502 (avl-tree-node-set-left (avl-tree-dummyroot new-tree) | |
503 (avl-tree-do-copy (avl-tree-root tree))) | |
504 new-tree)) | |
505 | |
506 (defun avl-tree-flatten (tree) | |
507 "Return a sorted list containing all elements of TREE." | |
508 (nreverse | |
509 (let ((treelist nil)) | |
510 (avl-tree-mapc | |
511 (function (lambda (node) | |
512 (setq treelist (cons (avl-tree-node-data node) | |
513 treelist)))) | |
514 (avl-tree-root tree)) | |
515 treelist))) | |
516 | |
517 (defun avl-tree-size (tree) | |
518 "Return the number of elements in TREE." | |
519 (let ((treesize 0)) | |
520 (avl-tree-mapc | |
521 (function (lambda (data) | |
522 (setq treesize (1+ treesize)) | |
523 data)) | |
524 (avl-tree-root tree)) | |
525 treesize)) | |
526 | |
527 (defun avl-tree-clear (tree) | |
528 "Clear the avl tree TREE." | |
529 (avl-tree-node-set-left (avl-tree-dummyroot tree) nil)) | |
530 | |
531 (provide 'avl-tree) | |
532 | |
533 ;; arch-tag: 47e26701-43c9-4222-bd79-739eac6357a9 | |
534 ;;; avl-tree.el ends here |