博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
scheme 学习:红黑树
阅读量:6252 次
发布时间:2019-06-22

本文共 16315 字,大约阅读时间需要 54 分钟。

这几天继续学习scheme,scheme中虽然有hashtable但没有类似C++中的map,于是把C版本中的红黑树移植到scheme(中间也发现了C版本中的一些问题,暂时懒得调整了^()^)

以作为后序set和表格驱动设计中表格的基础数据结构.

虽说这个红黑树在C版本中是调试好的了,但移植过来还是花费了我一天多的时间,中间出现各种小问题,苦于并不熟悉如何调试scheme程序,所以进度十分缓慢.

(注:代码中大量使用set-car!所以无法再racket中运行,当然也可以调整rbnode的表示形式,不使用list来表示各字段,只使用set!修改字段的内容以使得可以被

racket支持)

(begin    (define nil-node (list 0 0 'black '() '() '()))    ;红黑树节点的定义    ;节点结构如下    ;(key (val (color (parent (left (right nil))))))        (define (make-rb-node key val)        (list key val 'red '() '() '())    )            (define (get-key rbnode)        (car rbnode))        (define (get-val rbnode)        (cadr rbnode))        (define (set-val! rbnode val)        (set-car! (cdr rbnode) val))        (define (get-color rbnode)        (caddr rbnode))        (define (set-color! rbnode color)        (set-car! (cddr rbnode) color))            (define (get-parent rbnode)        (cadddr rbnode))            (define (set-parent! rbnode parent)        (if (not (equal? rbnode nil-node))        (set-car! (cdddr rbnode) parent)))            (define (get-left rbnode)        (car (cddddr rbnode)))        (define (set-left! rbnode left)        (if (not (equal? rbnode nil-node))        (set-car! (cddddr rbnode) left)))            (define (get-right rbnode)        (cadr (cddddr rbnode)))            (define (set-right! rbnode right)        (if (not (equal? rbnode nil-node))        (set-car! (cdr (cddddr rbnode)) right)))        (define (color-flip rbnode)        (if (and (not (null? (get-left rbnode)))                 (not (null? (get-right rbnode))))            (begin (set-color! rbnode 'red)                   (set-color! (get-left rbnode) 'black)                   (set-color! (get-right rbnode) 'black)                    #t)        #f)                )            ;红黑树定义    ;(root (size nil))    (define (make-rbtree comp-function)        ;(let ((rbtree (list nil 0 nil)))        (let ((root nil-node)(size 0)(cmp-function comp-function))                (define (rbtree-get-root) root)                (define (rbtree-set-root! new-root) (set! root new-root))                (define (rbtree-get-size) size)                            (define (rbtree-insert key val)            (define rbnode (make-rb-node key val))            (define child_link '())            (define parent nil-node)            (define cmp cmp-function)            (define (iter cur)                (if (equal? cur nil-node) #t                    (begin                        (set! parent cur)                        (let ((ret (cmp key (get-key cur))))                        (cond ((= 0 ret) #f)                              (else (if (< ret 0) (begin (set! child_link (cddddr cur))                                                         (set! cur (get-left cur)))                                                  (begin (set! child_link (cdr (cddddr cur)))                                                         (set! cur (get-right cur))))                                             (iter cur))))                    )))            (if (not (iter (rbtree-get-root))) #f                (begin                    (set-left! rbnode nil-node)                    (set-right! rbnode nil-node)                    (set-parent! rbnode parent)                    (if (not (null? child_link)) (set-car! child_link rbnode))                    (set! size (+ 1 size))                    (if (= 1 size)(rbtree-set-root! rbnode))                    (insert-fix-up rbnode)                    #t                ))        )                (define (rbtree-find-imp key)            (define (iter node)                (define cmp cmp-function)                (if (equal? node nil-node)'()                    (let ((ret (cmp key (get-key node))))                        (cond ((= 0 ret) node)                              ((= -1 ret) (iter (get-left node)))                              (else (iter (get-right node)))))))            (if (= 0 size) '()                (iter root))        )                (define (rbtree-find key)            (define ret (rbtree-find-imp key))            (if (null? ret) ret (get-val ret))        )                (define (rbtree-remove key)            (define rbnode (rbtree-find-imp key))            (if (null? rbnode)'()                (rbtree-delete rbnode))            rbnode            )                ;获取用于代替将被删除节点的节点        (define (get-replace-node rbnode)            (cond ((and (equal? (get-left rbnode) nil-node)                        (equal? (get-right rbnode) nil-node))rbnode)                  ((not (equal? (get-right rbnode) nil-node)) (minimum (get-right rbnode)))                          (else (maxmum (get-left rbnode))))        )                (define (rbtree-delete rbnode)            (define x (get-replace-node rbnode));用x替代rbnode的位置            (define rb-parent (get-parent rbnode));rbnode的父亲            (define x-parent (get-parent x));x的父亲            (define x-old-color (get-color x))            (define fix-node nil-node)            (if (equal? nil-node (get-left x))(set! fix-node (get-right x))                (set! fix-node (get-left x)))            (if (not (equal? x rbnode));如果x与rbnode不是同一个节点                (begin                    ;x的父亲不是rbnode,将x的孩子交给它的父亲                    (if (not (equal? x-parent rbnode))                        (let ((child (if (not (equal? nil-node (get-left x)))(get-left x)                                         (get-right x))))                             (set-parent! child x-parent)                                          (if (equal? x (get-left x-parent))                                  (set-left! x-parent child)                                     (set-right! x-parent child))))                                        (if (not (equal? nil-node rb-parent))                        ;如果rb-parent不为nil让x成为rb-parent的孩子                            (begin                            (if (equal? rbnode (get-left rb-parent))(set-left! rb-parent x)                                (set-right! rb-parent x))                            (set-parent! x rb-parent)                            )                        ;否则将x父亲设为nil                        (set-parent! x nil-node))                    ;将rbnode的孩子移交给x                    (let ((rb-left (get-left rbnode))(rb-right (get-right rbnode)))                        (if (not (equal? nil-node rb-left))                            (begin (set-left! x rb-left)(set-parent! rb-left x)))                        (if (not (equal? nil-node rb-right))                            (begin (set-right! x rb-right)(set-parent! rb-right x))))                                        ))            ;将rbnode的所有关系清除                (set-left! rbnode nil-node)(set-right! rbnode nil-node)(set-parent! rbnode nil-node)            (if (equal? root rbnode)                        (rbtree-set-root! x))            (set! size (- size 1))                (if (and (equal? nil-node fix-node) (eq? x-old-color 'black))                (delete-fix-up fix-node))                )                    (define (rotate-left rbnode)            (define parent (get-parent rbnode))            (define right (get-right rbnode))            (if (not (equal? nil-node right))                (begin                    (set-right! rbnode (get-left right))                    (set-parent! (get-left right) rbnode)                    (if (equal? root rbnode) (rbtree-set-root! right)                        (begin                            (if (equal? rbnode (get-left parent))(set-left! parent right)                                (set-right! parent right))))                    (set-parent! right parent)                    (set-parent! rbnode right)                    (set-left! right rbnode)                #t)            #f)        )                (define (rotate-right rbnode)            (define parent (get-parent rbnode))            (define left (get-left rbnode))            (if (not (equal? nil-node left))                (begin                    (set-left! rbnode (get-right left))                    (set-parent! (get-right left) rbnode)                    (if (equal? root rbnode) (rbtree-set-root! left)                        (begin                            (if (equal? rbnode (get-left parent))(set-left! parent left)                                (set-right! parent left))))                    (set-parent! left parent)                    (set-parent! rbnode left)                    (set-right! left rbnode)                #t)            #f)        )                (define (insert-fix-up rbnode)            (define (iter n)                (if (eq? (get-color (get-parent n)) 'black)                    (set-color! root 'black)                    (begin                        (let ((parent (get-parent n))(grand_parent (get-parent (get-parent n))))                        (if (equal? parent (get-left grand_parent))                            (begin                                (let ((ancle (get-right grand_parent)))                                (if (eq? (get-color ancle) 'red)                                    (begin (color-flip grand_parent) (set! n grand_parent))                                    (begin                                         (if (equal? n (get-right parent))                                            (begin (set! n parent)(rotate-left n)))                                     (set-color! (get-parent n) 'black)                                     (set-color! (get-parent (get-parent n)) 'red)                                     (rotate-right (get-parent (get-parent n))))))                                    )                            (begin                                (let ((ancle (get-left grand_parent)))                                (if (eq? (get-color ancle) 'red)                                    (begin (color-flip grand_parent) (set! n grand_parent))                                    (begin                                         (if (equal? n (get-left parent))                                            (begin (set! n parent)(rotate-right n)))                                     (set-color! (get-parent n) 'black)                                     (set-color! (get-parent (get-parent n)) 'red)                                     (rotate-left (get-parent (get-parent n))))))                                                        )))                         (iter n))))            (iter rbnode)        )        (define (delete-fix-up rbnode)            (define (iter n)                (if (not (and (not (equal? n root))                              (not (equal? (get-color n) 'red))))                    (set-color! n 'black)                    (begin                        (let ((parent (get-parent n)))                        (if (equal? n (get-left parent))                            (begin                                (let ((w (get-right parent)))                                (if (eq? 'red (get-color w))                                    (begin                                        (set-color! w 'black)                                        (set-color! parent 'red)                                        (rotate-left parent)                                        (set! w (get-right parent))))                                (if (and (eq? 'black (get-color (get-left w)))                                         (eq? 'black (get-color (get-right w))))                                    (begin (set-color! w 'red)(set! n parent))                                    (begin                                        (if (eq? (get-color (get-right w)) 'black)                                            (begin                                                (set-color! (get-left w) 'black)                                                (set-color! w 'red)                                                (rotate-right w)                                                (set! w (get-right parent))                                            ))                                        (set-color! w (get-color parent))                                        (set-color! parent 'black)                                        (set-color! (get-right w) 'black)                                        (rotate-left parent)                                        (set! n root)                                        ))))                            (begin                                (let ((w (get-left parent)))                                (if (eq? 'red (get-color w))                                    (begin                                        (set-color! w 'black)                                        (set-color! parent 'red)                                        (rotate-right parent)                                        (set! w (get-left parent))))                                (if (and (eq? 'black (get-color (get-left w)))                                         (eq? 'black (get-color (get-right w))))                                    (begin (set-color! w 'red)(set! n parent))                                    (begin                                        (if (eq? (get-color (get-left w)) 'black)                                            (begin                                                (set-color! (get-right w) 'black)                                                (set-color! w 'red)                                                (rotate-left w)                                                (set! w (get-left parent))                                            ))                                        (set-color! w (get-color parent))                                        (set-color! parent 'black)                                        (set-color! (get-left w) 'black)                                        (rotate-right parent)                                        (set! n root)                                        ))))))                                            (iter n))))            (iter rbnode)        )                (define (minimum rbnode)            (define (minimum-imp rbnode)                (if (equal? (get-left rbnode) nil-node)                    rbnode                    (minimum-imp (get-left rbnode))))            (minimum-imp rbnode))                    (define (maxmum rbnode)            (define (maxmum-imp rbnode)                (if (equal? (get-right rbnode) nil-node)                    rbnode                    (maxmum-imp (get-right rbnode))))            (maxmum-imp rbnode))                                (define (successor rbnode)            (define (iter parent node)                (if (and (not (equal? parent nil-node))                         (equal? (get-right parent) node))                    (iter (get-parent parent) parent)                    parent))            (if (not (equal? (get-right rbnode) nil-node))                (minimum (get-right rbnode))                (iter (get-parent rbnode) rbnode)))                            (define (node-next rbnode)            (display (get-key rbnode))(newline)            (if (null? rbnode) '()                (begin                    (let ((succ (successor rbnode)))                        (if (equal? succ nil-node) '() succ))                )))                            (define (rbtree->array)            (define (iter rbnode ret)                (if (null? rbnode) ret                    (iter (node-next rbnode) (cons (get-val rbnode) ret)))            )            (iter (minimum root) '())        )                                (lambda (op . arg)        (cond ((eq? op 'find) (rbtree-find  (car arg)))              ((eq? op 'remove) (rbtree-remove  (car arg)))              ((eq? op 'insert) (rbtree-insert (car arg) (cadr arg)))              ((eq? op 'size) size)              ((eq? op 'root) (get-key root))              ((eq? op 'tree->array-desc) (rbtree->array))              ((eq? op 'tree->array-asc) (reverse (rbtree->array)))              (else "bad op")))    ))    (define (default-cmp a b)        (cond ((= a b) 0)              ((< a b) -1)              (else 1)))                  (define r (make-rbtree default-cmp))    (r 'insert 1 1)    (r 'insert 4 4)    (r 'insert 5 5)    (r 'insert 11 11)    (r 'insert 15 15)    (r 'insert 8 8)    (r 'insert 2 2)    (r 'insert 3 3)    (r 'insert 6 6)    (r 'insert 7 7)    )

 

转载于:https://www.cnblogs.com/sniperHW/archive/2013/05/31/3110146.html

你可能感兴趣的文章
解决nim db_mysql could not load: libmysql.dll的问题
查看>>
JavaScript之再谈回调与闭包
查看>>
优化PHP代码的一些建议
查看>>
android学习网站
查看>>
TCP定时器详解
查看>>
if判断,switch语句
查看>>
postgresql中字段为空的查询
查看>>
Arduino入门之前
查看>>
JavaWeb学习----JSP简介及入门(含Eclipse for Java EE及Tomcat的配置)
查看>>
zoj 1904 Beavergnaw 计算圆柱和圆台的体积
查看>>
整理了一份招PHP高级工程师的面试题(转)
查看>>
Document对象中的一些重要的属性和方法(笔记)
查看>>
学习Raft算法的笔记
查看>>
[LeetCode]题解(python):053-Maximum Subarray
查看>>
SharePoint中的用户信息和检索的有关知识
查看>>
Linux系统在启动过程中grub引导文件丢失的解决方法
查看>>
day15-JavaScript条件语句和函数的定义
查看>>
使用acl网络通信库的 redis c++ 模块开发 redis 应用
查看>>
Geek的入门神器:micropython-能跑python的stm32开发板
查看>>
利用脚本获取mysql的tps,qps等状态信息
查看>>