scheme 学习:红黑树

这几天继续学习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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/402690.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Maven多模块,Dubbo分布式服务框架,SpringMVC,前后端分离项目,基础搭建,搭建过程出现的问题...

现互联网公司后端架构常用到SpringSpringMVCMyBatis&#xff0c;通过Maven来构建。通过学习&#xff0c;我已经掌握了基本的搭建过程&#xff0c;写下基础文章为而后的深入学习奠定基础。 首先说一下这篇文章的主要内容分为&#xff1a; 1、Maven多模块项目的创建&#xff1b; …

Maven的pom.xml文件结构之Build配置build

From: https://blog.csdn.net/taiyangdao/article/details/52374125 在Maven的pom.xml文件中&#xff0c;Build相关配置包含两个部分&#xff0c;一个是<build>&#xff0c;另一个是<reporting>&#xff0c;这里我们只介绍<build>。 1. 在Maven的pom.xml文件…

FineUI 将不再内置 ExtJS (严格遵守 ExtJS 的开源规则)

从下个版本起&#xff0c;FineUI 将不再内置 ExtJS &#xff0c;不过我会提供说明如何使用 ExtJS&#xff08;并单独提供精简版的 ExtJS 包供论坛用户下载&#xff09;&#xff0c;现有的程序升级到新版本将不受影响&#xff08;只需要将精简版的 extjs 文件夹拷贝到程序根目录…

Maven开发笔记(四)—— Maven中plugins和pluginManagement

From: https://www.jianshu.com/p/49acf1246eff 1.plugins和pluginManagement的区别概述 plugins 和 pluginManagement 的区别&#xff0c;和我们前面研究过的 dependencies 和 dependencyManagement 的区别是非常类似的。plugins 下的 plugin 是真实使用的&#xff0c;而 pl…

Html代码seo优化最佳布局实例讲解

搜索引擎对html代码是非常优化的&#xff0c;所以html的优化是做好推广的第一步。一个符合seo规则的代码大体如下界面所示。 1、<!–木庄网络博客–> 这个东西是些页面注释的&#xff0c;可以在这里加我的“木庄网络博客”&#xff0c;但过多关键字可能被搜索引擎惩罚&a…

基于struts2,hibernate的小javaweb项目

19:47:49 这是截图 闲话不说 就开始了 web-xml&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <web-app version"2.5" xmlns"http://java.sun.com/xml/ns/javaee"xmlns:xsi"http://www.w3.org/2001/XMLSchema-in…

YAML快速入门

From: https://www.jianshu.com/p/97222440cd08 我们学习Java&#xff0c;都是先介绍properties文件&#xff0c;使用properties文件配合Properties对象能够很方便的适用于应用配置上。然后在引入XML的时候&#xff0c;我们介绍properties格式在表现层级关系和结构关系的时候&…

MySql的用户权限

用户管理 MySQL数据库中的表与其他任何关系表没有区别&#xff0c;都可以通过典型的SQL命令修改其结构和数据。可以使用GRANT和REVOKE命令。通过这些命令&#xff0c;可以创建和禁用用户&#xff0c;可以在线授予和撤回用户访问权限。在5.0版本中增加了两个新命令&#xff1a;C…

.yaml 文件格式简介

From: https://www.cnblogs.com/wxmdevelop/p/7341292.html YAML 的意思其实是&#xff1a;"Yet Another Markup Language"&#xff08;仍是一种置标语言&#xff09;的缩写。 功能 YAML的语法和其他高阶语言类似&#xff0c;并且可以简单表达清单、散列表&#x…

jQuery与JS的区别,以及jQuery的基础语法

*在使用jQuery时&#xff0c;要在页面最上端加上 <script src"../jquery-1.11.2.min.js"></script> 看一下js与jQuery的区别&#xff1a; JS是这样使用的&#xff1a; <script type"text/javascript">根据ID取元素,取到的是具体的元素va…

sql语句中的时间查询

一般来说&#xff0c;我们在mysql数据库纪录数据时间时&#xff0c;都会选择datatime类型&#xff0c;这样时间可以精确到秒。但随之而来的一个问题是&#xff0c;当我们要取得某一段时间内的数据内容会有一些时间转换上的麻烦&#xff0c;例如我们要取得2002年3月2日到2003年7…

SnakeYaml快速入门

From: https://www.jianshu.com/p/d8136c913e52 在YAML快速入门[https://www.jianshu.com/p/97222440cd08]中&#xff0c;我们已经简单介绍了YAML的语法&#xff0c;本节中主要介绍YAML的配置读取。 目前有很多可以生成和解析YAML的第三方工具&#xff0c;常见的&#xff0c;…

CSS的一些零碎总结

1、CSS 伪元素用于向某些选择器设置特殊效果&#xff08;用来当作一个东西的&#xff0c;跟一个元素差不多&#xff0c;但不是元素&#xff09;。 ① :frist-line伪元素&#xff1a;用于向文本首行设置特殊样式&#xff0c;但是只能用于块级元素。 以下属性可应用于 “ frist-l…

有源代码的iphone项目

2019独角兽企业重金招聘Python工程师标准>>> http://blog.joomla.org.tw/iphone-ipad/104-iphone.html 學習和利用現成的資源是很重要的&#xff0c;以下列出有原始碼可下載的iPhone/iPod程式&#xff0c;這邊收集的是以已經放到App Store上的程式為主&#xff0c;…

匿名函数与闭包

<!DOCTYPE html><html lang"zh-CN"><head> <meta charset"UTF-8"> <title>闭包.html</title> <style> </style> <script src"jquery-1.7.2.min.js"></script> <script type&quo…

Content Security Policy 入门教程

From: http://www.ruanyifeng.com/blog/2016/09/csp.html 跨域脚本攻击 XSS 是最常见、危害最大的网页安全漏洞。 为了防止它们&#xff0c;要采取很多编程措施&#xff0c;非常麻烦。很多人提出&#xff0c;能不能根本上解决问题&#xff0c;浏览器自动禁止外部注入恶意脚本&…

windows编程基础

说明&#xff1a;只供学习交流&#xff0c;转载请注明出处 windows编程基础 &#xff08;1&#xff09;&#xff1a;API与SDK 我们在编写标准C程序的时候&#xff0c;经常会调用各种库函数来辅助完成某些功能&#xff1a;初学者使用得最多的库函数就是printf了&#xff0c;这些…

前端安全配置之Content-Security-Policy(csp)

From: https://www.cnblogs.com/heyuqing/p/6215761.html 什么是CSP CSP全称Content Security Policy ,可以直接翻译为内容安全策略,说白了,就是为了页面内容安全而制定的一系列防护策略. 通过CSP所约束的的规责指定可信的内容来源&#xff08;这里的内容可以指脚本、图片、i…

springboot跨域配置

From: https://www.cnblogs.com/nananana/p/8492185.html 前言&#xff1a; 当它请求的一个资源是从一个与它本身提供的第一个资源的不同的域名时&#xff0c;一个资源会发起一个跨域HTTP请求(Cross-site HTTP request)。 比如说&#xff0c;域名A ( http://domaina.example …

字符函数

getchar: 从stdio流中读字符 a getchar(); fputs:指定的文件写入一个字符串(不自动写入字符串结束标记符\0) fgets:从文件结构体指针stream中读取数据&#xff0c;每次读取一行。读取的数据保存在buf指向的字符数组中&#xff0c;每次最多读取 bufsize-1个字符…