#define RBTREE_RED 0 #define RBTREE_BLACK 1 typedef int dataType; typedef struct treeNode{ dataType key; int color; //red:0.

Slides:



Advertisements
Similar presentations
商管群科科主任 盧錦春 年 3 月份初階建置、 4 月份進階建置、 5 月份試賣與對外營業。
Advertisements

第7章 樹與二元樹 (Trees and Binary Trees)
第6章 二叉树和树 前面的章节主要讨论的是线性结构,二叉树和树属于非线性的结构。遍历非线性结构比线性结构要麻烦。
“深入推进依法行政加快建设法治政府” -《法治政府建设实施纲要》解读
第三章 鏈結串列 Linked List.
计算机硕士专业基础—C语言 赵海英
第六节 可降阶的二阶微分方程 一、 型的微分方程 二、 型的微分方程 三、 型的微分方程.
C语言实现俄罗斯方块 邓友明( ) 胡文峰( ) 李乐( ) 李博( )
计算机软件技术基础 数据结构与算法(4).
第五章 树 东南大学计算机学院 方效林 本课件借鉴了清华大学殷人昆老师 和哈尔滨工业大学张岩老师的课件.
数据结构 第6章 树和二叉树 什么是树和二叉树?? 二叉树的遍历 数据结构.
前不久看到了这样一则报道:某个大学校园里,一个大学生出寝室要给室友留一张字条,告诉他钥匙放在哪里。可是“钥匙”两个字他不会写,就问了其他寝室的同学,问了好几个,谁也不会写,没办法,只好用“KEY”来代替了。 请大家就此事发表一下自己看法。
§4 Additional Binary Tree Operations
Chap4 Tree.
利用共同供應契約 辦理大量訂購流程說明.
Tree(樹) 什麼是「樹」? 「樹」的範例 「樹」的定義 「樹」的表示法.
Linked List Operations
Chapter 5 Tree & Binary Tree
單向鏈結串列 Singly Linked Lists.
第6章 佇列(Queues) 6-1 佇列的基礎 6-2 佇列的表示法 6-3 環狀佇列 6-4 雙佇列.
第二章 C# 基础知识.
第11章 查找 主要知识点 查找的基本概念 静态查找表 动态查找表 哈希表.
佇列 (Queue).
Chapter8 Binary and Other Trees
补充内容 结构体 概述 定义结构体类型和定义结构体变量 结构体变量的引用 结构体变量的初始化 指针与结构体 用typedef定义类型的别名.
数 据 结 构 Ch.6 树 计 算 机 学 院 肖明军
第七章 搜索结构 静态搜索结构 二叉搜索树 AVL树.
第12章 樹狀搜尋結構 (Search Trees)
授课老师:龚涛 信息科学与技术学院 2018年3月 教材: 《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
程序设计期末复习 黎金宁
第十一章 Heap 結構.
9.1-1 按照竞争树的办法求最小值需n-1次比较,然后在lgn个与最小值比较过的元素中求出最小值即为原来n个元素的次小值,需lgn-1次比较,所以共需n+lgn-2次比较 题目是要证明3n/2-2是最少的比较次数,而不是要构造出这样的算法。我们把某个元素与其它元素间的大小关系称作一条信息,那么最大元素包含n-1条信息(这个元素比其它n-1个元素都大),同样,最小元素也包含n-1条信息,同时求出最大和最小元素就需要获得2n-2条信息。未比较过的元素记为N,比较后较小的元素记为S,较大的元素记为
第2章 线性表 线性表抽象数据类型 顺序表 主要知识点 单链表 循环单链表 循环双向链表 静态链表 设计举例.
第十章 C高级程序应用—链表* 10.1链表的基本概念 10.2单向链表 10.3双向链表 10.4应用举例.
第5章 堆疊(Stacks) 5-1 堆疊的基礎 5-2 堆疊的表示法 5-3 堆疊的應用 - 運算式的計算與轉換
第5章 堆疊(Stacks) 5-1 堆疊的基礎 5-2 堆疊的表示法 5-3 堆疊的應用 - 運算式的計算與轉換
进程操作.
第六章 树和二叉树.
第7章 查找 北京师范大学 教育技术学院 杨开城.
五、链 表 1、单链表 2、双向链表 3、链表应用.
教 师:曾晓东 电 话: E_mail: 计算机软件技术基础 教 师:曾晓东 电 话: E_mail:
陈海明 副教授 信息学院 计算机系 电子信息类非计算机专业选修课 程序设计实践 陈海明 副教授 信息学院 计算机系
第11讲 树和二叉树(二).
親愛的老師您好 感謝您選用本書作為授課教材,博碩文化準備本書精選簡報檔,特別摘錄重點提供給您授課專用。 說明: 博碩文化:
数据结构 第9章 查找 什么是查找?? 静态查找 动态查找 哈希表 数据结构.
第六章 樹狀結構 T r e e 版權屬作者所有,非經作者 同意不得用於教學以外用途.
第5到第6章的勘误表 注意:这个 c 应改为 d 1、第 92 页 倒数第 7 行:
樹 2 Michael Tsai 2013/3/26.
陈海明 副教授 信息学院 计算机系 电子信息类非计算机专业选修课 程序设计实践 陈海明 副教授 信息学院 计算机系
7.1 广义表的概念 广义表是n(n≥0)个数据元素组成的序列,其中每个数据元素或是单个数据元素(简称原子),或仍然是一个广义表 。
Reference to FUNDAMENTALS OF DATA STRUCTURE IN C++
9.1 基本概念 9.2 线性表的查找 9.3 树表的查找 9.4 哈希表的查找 9.5 各种查找方法的比较
第7章 樹與二元樹(Trees and Binary Trees)
資料結構使用Java 第9章 樹(Tree).
Ch.9 查找 §9.1 基本概念 查找和排序是两个重要的运算
本教學投影片係屬教科書著作之延伸,亦受著作權法之保護。
<编程达人入门课程> 本节内容 为什么要使用变量? 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ:
第二章 Java语法基础.
树和二叉树(一).
兒童及少年保護、 家庭暴力及性侵害事件、 高風險家庭 宣導與通報
单片机原理及应用 实践部分 主讲人:刘 强 四川工商学院单片机教学团队 单片机原理及应用 实践部分 主讲人:刘 强
#include <iostream.h>
第二章 Java基本语法 讲师:复凡.
第1章 数据结构基础概论 本章主要介绍以下内容 数据结构研究的主要内容 数据结构中涉及的基本概念 算法的概念、描述方法以及评价标准.
第2章 Java语言基础.
第10章 二元搜尋樹 (Binary Search Tree)
本节内容 1.二叉排序树的定义 2.二叉排序树的查找操作 3.二叉排序树的插入操作 4.二叉排序树的删除操作 5.二叉排序树的总结
資料結構與C++程式設計進階 C++與資料結構 講師:林業峻 CSIE, NTU 7/ 5, 2010.
算法基础习题课2 助教:刘倩玉.
JAVA 程式設計與資料結構 第十七章 Tree.
Presentation transcript:

#define RBTREE_RED 0 #define RBTREE_BLACK 1 typedef int dataType; typedef struct treeNode{ dataType key; int color; //red:0 black:1 struct treeNode *left; struct treeNode *right; struct treeNode *parent; }RBTree, *PRBTree; static PRBTree RBT_Search(dataType key, PRBTree root, PRBTree* save) { PRBTree node = root, parent = NULL; while (node) parent = node; if (node->key > key) node = node->left; else if (node->key < key) node = node->right; else return node; } if (save) *save = parent; return NULL;

// 左旋函数 static PRBTree leftRotate(PRBTree x , PRBTree root) { // x 为旋转点 PRBTree y = x->right; // 令y为旋转点的右子节点 x->right = y->left; if(y->left) y->left->parent = x; // 别忘了设定父节点 y->parent = x->parent; // 令y完全顶替x的地位(必须将x对其父节点的关系完全接收过来) if(x == root) // x为根节点 root = y; else if(x == x->parent->left) // x为其父节点的左子节点 x->parent->left = y; else // x为其父节点的右子节点 x->parent->right = y; y->left = x; x->parent = y; return root; }

// 右旋函数 static PRBTree rightRotate(PRBTree x , PRBTree root) { // x 为旋转点 PRBTree y = x->left; // 令y为旋转点的左子节点 x->left = y->right; if(y->right) y->right->parent = x; // 别忘了设定父节点 y->parent = x->parent; // 令y完全顶替x的地位(必须将x对其父节点的关系完全接收过来) if(x == root) root = y; else if(x == x->parent->right) // x为其父节点的右子节点 x->parent->right = y; else // x为其父节点的左子节点 x->parent->left = y; y->right = x; x->parent = y; return root; }

//红黑树的插入结点 PRBTree RBInsert(dataType key, PRBTree root) { PRBTree parent = NULL, node; if ((node = RBT_Search(key, root, &parent))) //找到插入结点的地方 return root; node = (PRBTree)malloc(sizeof(RBTree)); //分配结点 node->parent = parent; node->left = node->right = NULL; node->color = RBTREE_RED; node->key = key; if (parent) if (parent->key > key) parent->left = node; else parent->right = node; } else root = node; return RBInsert_Rebalance(node, root); //插入结点后,修复红黑树的性质

static PRBTree RBInsert_Rebalance(PRBTree x, PRBTree root) { x->color = RBTREE_RED; //新节点必为红 while(x != root && x->parent->color == RBTREE_RED) // 父节点为红 if(x->parent == x->parent->parent->left) // 父节点为祖父节点之左子节点 PRBTree y = x->parent->parent->right; // 令y为伯父节点 if(y && y->color == RBTREE_RED) // 伯父节点存在,且为红 x->parent->color = RBTREE_BLACK; // 更改父节点为黑色 y->color = RBTREE_BLACK; // 更改伯父节点为黑色 x->parent->parent->color = RBTREE_RED; x = x->parent->parent; } else // 无伯父节点,或伯父节点为黑色 if(x == x->parent->right) // 新节点为父节点之右子节点 x = x->parent; root = leftRotate(x , root); // 左旋 x->parent->color = RBTREE_BLACK; // 改变颜色 root = rightRotate(x->parent->parent , root); // 右旋点

else // 父节点为祖父节点之右子节点 { PRBTree y = x->parent->parent->left; // 令y为伯父节点 if(y && y->color == RBTREE_RED) // 有伯父节点,且为红 x->parent->color = RBTREE_BLACK; // 父节点为黑色 y->color = RBTREE_BLACK; // 更改伯父节点为黑色 x->parent->parent->color = RBTREE_RED x = x->parent->parent; // 准备继续往上层检查 } else // 无伯父节点,或伯父节点为黑色 if(x == x->parent->left) //新节点为父节点之左子节点 x = x->parent; root = rightRotate(x , root); // 右旋点 x->parent->color = RBTREE_BLACK; // 改变颜色 x->parent->parent->color = RBTREE_RED; root = leftRotate(x->parent->parent , root); // 左旋点 }//while root->color = RBTREE_BLACK; // 根节点永远为黑色 return root;

PRBTree RBErase(dataType key, PRBTree root) //红黑树的删除结点 { PRBTree child, parent, old, left, node; int color; if (!(node = RBT_Search(key, root, NULL))) return root; //查找要删除的结点 old = node; if (node->left && node->right) {//要删除的结点有两个儿子 node = node->right; while ((left = node->left) != NULL) node = left;//找出后继结点 child = node->right; parent = node->parent; color = node->color; if (child) child->parent = parent;//后继结点的右儿子存在 if (parent) {//将node结点断链,node结点的父节点的左右儿子指针指向其右儿子 if (parent->left == node) //如果要删除的结点是父节点的左儿子 parent->left = child; else parent->right = child; //如果要删除的结点是父节点的左儿子 } else root = child; if (node->parent == old) parent = node; //将node结点取代old结点 node->parent = old->parent; node->color = old->color; node->right = old->right; node->left = old->left;

if (old->parent)//将old结点断链 { if (old->parent->left == old) old->parent->left = node; else old->parent->right = node; } else root = node; old->left->parent = node; if (old->right) old->right->parent = node; else{ //没有两个儿子 if (!node->left) child = node->right; else if (!node->right) child = node->left; parent = node->parent; color = node->color; if (child) child->parent = parent; if (parent) if (parent->left == node) parent->left = child; else parent->right = child else root = child; free(old); if(color == RBTREE_BLACK) root = RBErase_Rebalance(child, parent, root); //恢复红黑树 return root;

//红黑树修复删除的4种情况 PRBTree RBErase_Rebalance(PRBTree node, PRBTree parent, PRBTree root) { //x表示要删除的结点,other、w表示兄弟结点, PRBTree other, o_left, o_right; //x的兄弟other,兄弟左孩子o_left,o_right while ((!node || node->color == RBTREE_BLACK) && node != root) if (parent->left == node) { other = parent->right; if (other->color == RBTREE_RED) { //情况1:x的兄弟w是红色的 other->color = RBTREE_BLACK; parent->color = RBTREE_RED; //w->黑、p[x]->红。 root = leftRotate(parent, root); //再对p[x]做一次左旋 other = parent->right; //x的新兄弟new w 是旋转之前w的某个孩子。其实就是左旋后的效果。 } if ((!other->left || other->left->color == RBTREE_BLACK) && (!other->right || other->right->color == RBTREE_BLACK)) { //情况2:x的兄弟w是黑色,且w的俩个孩子也都是黑色的 other->color = RBTREE_RED; //于是,兄弟w变为红色。 node = parent; //p[x]为新结点x parent = node->parent; //x<-p[x] else { //情况3:x的兄弟w是黑色的,且w的左孩子是红色,右孩子为黑色。 if (!other->right || other->right->color == RBTREE_BLACK){ if ((o_left = other->left)) o_left->color = RBTREE_BLACK; //w和其左孩子,颜色交换。 other->color = RBTREE_RED; //w由黑->红 root = rightRotate(other, root); //再对w进行右旋,从而红黑性质恢复。 other = parent->right; //变化后的,父结点的右孩子,作为新的兄弟结点w。

//情况4:x的兄弟w是黑色的 other->color = parent->color; //把兄弟节点染成当前节点父节点的颜色。 parent->color = RBTREE_BLACK; //把当前节点父节点染成黑色 if (other->right) //且w的右孩子是红 other->right->color = RBTREE_BLACK; //兄弟节点w右孩子染成黑色 root = leftRotate(parent, root); //并再做一次左旋 node = root; //并把x置为根。 break; } else{//下述情况与上述情况,原理一致。 other = parent->left; if (other->color == RBTREE_RED) { other->color = RBTREE_BLACK; parent->color = RBTREE_RED; root = rightRotate(parent, root); if ((!other->left || other->left->color == RBTREE_BLACK) && (!other->right || other->right->color == RBTREE_BLACK)) { other->color = RBTREE_RED; node = parent; parent = node->parent;

else { if (!other->left || other->left->color == RBTREE_BLACK) if ((o_right = other->right)) o_right->color = RBTREE_BLACK; other->color = RBTREE_RED; root = leftRotate(other, root); other = parent->left; } other->color = parent->color; parent->color = RBTREE_BLACK; if (other->left) other->left->color = RBTREE_BLACK; root = rightRotate(parent, root); node = root; break; if (node) node->color = RBTREE_BLACK; //最后将node[上述步骤置为了根结点],改为黑色。 return root; //返回root