1. 程式人生 > >建立紅黑樹(左旋、右旋、插入、維護)程式碼+驗證

建立紅黑樹(左旋、右旋、插入、維護)程式碼+驗證

    關於紅黑樹的理論講解,網上有很多,大家可以自己找,這裡重點在於實現,程式碼供大家參考。程式碼如下:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#define RED     0
#define BLACK   1
#define NUM     9

typedef struct RBTNode
{
    int key;
    struct RBTNode *parent,*left,*right;
    int color;
}RBTNode,*RBTree;

RBTree nil,root;

void InitLeafNode()
{
    nil =(RBTree)malloc(sizeof(RBTree));
    root=(RBTree)malloc(sizeof(RBTree));
    nil->color      = BLACK;
    nil->left       = NULL;
    nil->right      = NULL;
    nil->key        = -1;
    root            = nil;
}

RBTree CreatNode(int key,int color)
{
    RBTree x;
    x=(RBTNode *)malloc(sizeof(RBTNode));
    x->color        = color;
    x->key          = key;
    x->left         = nil;
    x->right        = nil;
    x->parent       = NULL;
    return x;
}
void LeftRotate(RBTree z)                  //左旋
{
    RBTree y;
    y = z->right;
    z->right = y->left;             //set y
    if(y->left != nil)
        y->left->parent = z;
    y->parent = z->parent;

    if(z->parent == nil)
        root = y;
    else if(z == z->parent->left)
        z->parent->left 	= y;
    else
        z->parent->right	= y;
    //Put z on y's left.
    y->left     = z;
    z->parent   = y;
}
void RightRotate(RBTree z)      //右旋
{
    RBTree y;
    y = z->left;
    z->left = y->right;
    if(y->right != nil)
        y->right->parent = z;
    y->parent = z->parent;
    if(z->parent == nil)
        root = y;
    else if(z == z->parent->left)
        z->parent->left     = y;
    else
        z->parent->right    = y;
    y->right  = z;
    z->parent = y;
}
void TreeInsert(RBTree z)     //插入
{
    RBTree x,y;
    y = nil;
    x = root;
    while(x!=nil){         //Find the insertion position.
        y = x;
        if(z->key<x->key)
            x = x->left;
        else
            x = x->right;
    }
    z->parent = y;
    if(y == nil)
        root = z;
    else{
        if(z->key < y->key)
            y->left  = z;
        else
            y->right = z;
    }
}
void RBTreeInsertFixup(RBTree z)       //維護
{
    RBTree y;
    while(z->parent->color == RED){
        if(z->parent == z->parent->parent->left){
            y = z->parent->parent->right;
            if(y->color == RED){						//case 1.
                z->parent->color         = BLACK;
                z->parent->parent->color = RED;
                y->color                 = BLACK;
                z = z->parent->parent;
            }
            else{
                if(z == z->parent->right){					//case 2.
                    z = z->parent;
                    LeftRotate(z);
                }
                z->parent->color            = BLACK;		           	//case 3.
                z->parent->parent->color    = RED;
                z                           = z->parent->parent;
                RightRotate(z);
            }
        }
        else{                                //symmetry of (case 1,2,3)
            y = z->parent->parent->left;
            if(y->color == RED){
                z->parent->color         =BLACK;
                z->parent->parent->color =RED;
                y->color                 =BLACK;
                z = z->parent->parent;
            }
            else{
                if(z == z->parent->left){
                    z = z->parent;
                    RightRotate(z);
                }
                z->parent->color 		= BLACK;
                z->parent->parent->color 	= RED;
                z                           	= z->parent->parent;
                LeftRotate(z);
            }
        }
    }
    root->color = BLACK;
}
void RBTreeInsert(RBTree z)
{
    TreeInsert(z);
    z->left  = nil;
    z->right = nil;
    //z->color = RED;
    RBTreeInsertFixup(z);
}

int main(void)
{
    RBTree node[NUM];
    int key;
    int i;
    int A[NUM]={8,11,17,15,6,1,22,25,27};
    InitLeafNode();

    for(i=0;i<NUM;i++){
        key=A[i];
        node[i]=CreatNode(key,RED);
        RBTreeInsert(node[i]);
    }

    //驗證的時候就是列印每個節點的左孩子和右孩子的key,key為-1代表為葉子節點。 
    printf("The RBT is :\n");
    for(i=0;i<NUM;i++)
        printf("%d + %d\n",node[i]->left->key,node[i]->right->key);

    return 0;
}
vc6.0下驗證結果:



相關推薦

建立插入維護程式碼+驗證

    關於紅黑樹的理論講解,網上有很多,大家可以自己找,這裡重點在於實現,程式碼供大家參考。程式碼如下: #include <stdio.h> #include <stdlib.h> #include <time.h> #includ

和又

今天先來用java實現紅黑色左旋和右旋。後邊再把新增、刪除給補充上。 什麼是紅黑樹? 紅黑樹是一種近似平衡的二叉查詢樹,它能夠確保任何一個節點的左右子樹的高度差不會超過二者中較低那個的一陪。具體來說,紅黑樹是滿足如下條件的二叉查詢樹(binary search tree): 每個節

數據結構Java版之

如何 當前 鏈接 根節點 java版 -- 查找 變色 繼承   紅黑樹是一種自動平衡的二叉查找樹,因為存在紅黑規則,所以有效的防止了二叉樹退化成了鏈表,且查找和刪除的速度都很快,時間復雜度為log(n)。   什麽是紅黑規則?   1.根節點必須是黑色的。   2.節點顏

數據結構 - Red Black Tree插入詳解與實現Java

啟示 dpa con 技術分享 節點數 src 通知 一點 this   最終還是決定把紅黑樹的篇章一分為二,插入操作一篇,刪除操作一篇,因為合在一起寫篇幅實在太長了,寫起來都覺得累,何況是閱讀並理解的讀者。       紅黑樹刪除操作請參考 數據結構 - 紅黑樹(Red

數據結構 - Red Black Tree刪除詳解與實現Java

replace ati 轉載 之前 9.png one com 四種 簡單   本篇要講的就是紅黑樹的刪除操作       紅黑樹插入操作請參考 數據結構 - 紅黑樹(Red Black Tree)插入詳解與實現(Java)   紅黑樹的刪除是紅黑樹操作中比較麻煩且比較有意

2-3 /red-black tree

https ret html 技術分享 turn nfc font 進行 sre 2-3 tree 2-3樹節點: null節點,null節點到根節點的距離都是相同的,所以2-3數是平衡樹 2叉節點,有兩個分樹,節點中有一個元素,左樹元素更小,右樹元素節點更大 3叉節點

資料結構學習筆記------附c++程式碼

1、紅黑樹簡介 紅黑樹是二叉查詢樹的一種,其增刪改查的統計效能要優於AVL樹,查詢、插入、刪除演算法的複雜度都為O(log(n))。先附上紅黑樹這種資料結構的性質: 性質1、節點是紅色或黑色。 性質2、根節點是黑色。 性質3、每個葉節點(是指的空節點,nil節點)是黑色的。 性質4、

Red Black Tree刪除詳解與實現Java

  本篇要講的就是紅黑樹的刪除操作   紅黑樹的刪除是紅黑樹操作中比較麻煩且比較有意思的一部分。   在此之前,重申一遍紅黑樹的五個定義: 1. 紅黑樹的節點要不是黑色的要不是紅色的     2. 紅黑樹的根節點一定是黑色的     3. 紅黑樹的所有葉子節點都是黑色的(注意:紅黑樹的葉子節點指Nil節點

2-3 /red-black tree學習筆記

2-3 tree 2-3樹節點: null節點,null節點到根節點的距離都是相同的,所以2-3數是平衡樹 2叉節點,有兩個分樹,節點中有一個元素,左樹元素更小,右樹元素節點更大 3叉節點,有三個子樹,節點中有兩個元素,左樹元素更小,右樹元素更大,中間樹介於兩個父元素之間。 插入操作如下圖所示 紅

data_structure_and_algorithm -- :為什麼工程中都用這種二叉

今天主要看一下紅黑樹,主要參考:前谷歌工程師王爭的課程,感興趣可以通過下面方式微信掃碼購買: 樹、二叉樹、二叉查詢樹。二叉查詢樹是最常用的一種二叉樹,它支援快速插入、刪除、查詢操作,各個操作的時間複雜度跟樹的高度成正比,理想情況下,時間複雜度是 O(logn)。

從2-3-4

歡迎探討,如有錯誤敬請指正 相關部落格: 1. 2-3-4樹的定義 2-3-4樹是一種階為4的B樹。它是一種自平衡的資料結構,可以保證在O(lgn)的時間內完成查詢、插入和刪除操作。它主要滿足以下性質: (1)每個節點每個節點有1、2或3個key,分別稱為2(孩子)節點,3(孩子)節點,4(孩子)節點。

從2-3-4

歡迎探討,如有錯誤敬請指正 相關部落格: 1. 紅黑樹的定義 2-3-4樹和紅黑樹是完全等價的,由於絕大多數程式語言直接實現2-3-4樹會非常繁瑣,所以一般是通過實現紅黑樹來實現替代2-3-4樹,而紅黑樹本也同樣保證在O(lgn)的時間內完成查詢、插入和刪除操作。 紅黑樹是每個節點都帶有顏色屬性的平衡二

演算法導論 第13章 圖文詳細解說

1、二叉查詢樹的不足 二叉查詢樹的基本操作包括搜尋、插入、刪除、取最大和最小值等都能夠在O(h)(h為樹的高度)時間複雜度內實現,因此能在期望時間O(lgn)下實現,但是二叉查詢樹的平衡性在這些操作中並沒有得到維護,其高度可能會變得很高,當其高度較高時,二叉查詢樹的效能就未

一步一圖一程式碼,一定要讓你真正徹底明白平衡二叉

一步一圖一程式碼,一定要讓你真正徹底明白紅黑樹 作者:July   二零一一年一月九日 ----------------------------- 本文參考: I、  The Art of Computer Programming Volume I II、 I

2保持平衡的根本套路

有了解過的同學們應該都知道,紅黑樹為了保持平衡,有三個基本的操作:左旋、右旋和著色。(不知道的同學也沒關係 ,因為在此我只想告訴你們的是這三個操作都是為了什麼) 首先要有這樣一個意識:要棵紅黑樹在你插入新節點之前就是平衡的(不理解紅黑樹平衡的可看上一節),我們要做的是使

1真的只說原理

樹可以分為兩大類:平衡的樹和不平衡的樹。 那些都有自己大名的自然就是平衡的樹。我們使用樹這結構就是看中它插刪與搜尋擁有同等的高效 O(log n)。 平衡樹的特點就是每層都幾乎佈滿,不會出現某一分支特別長的情況。因為樹的查詢跟層數有關,層數越大越耗時間。如果有10個節點就

3殘疾版新增實現

為什麼說是殘疾版呢,因為標準的紅黑樹是是三個值在一層,也就是父節點的左右分支節點都可以是紅,但在此,我規定了只有左分支為紅,也就是規定了最多隻有兩個值在一層。這樣能減少很多修復平衡判斷條件。在此我以實現簡化版的treeMap 為例。 新增節點的第一步就是找出節點將要加入的位

【演算法】二叉概念與查詢

誒,演算法這個東西,其實沒那麼簡單,但是也沒那麼難。 紅黑樹,其實已經有很多大佬都整理過了,而且文章部落格都寫得超好,我寫這篇文章的目的是:自己整理一次,這些知識才是自己的,否則永遠是別人的~   該系列到現在暫只有3篇文章: 【演算法】紅黑樹(二叉樹)概念與查詢(一):h

Red-BlackBalancedSearchTree

1.什麼是紅黑樹   紅黑樹本質上是二叉搜尋樹的改良版,因此,對二叉搜尋樹不瞭解的,建議先去看一下二叉搜尋樹。   二叉搜尋樹有個嚴重的缺陷:樹本身並不平衡,很容易造成部分分支過長,而部分分支過短的情況,從而影響到了搜尋速度。   二叉搜尋樹的一個極端例子:      如果把一個遞增的陣列按順序放進

資料結構與演算法:Red Black Tree

一、簡介 紅黑樹(Red Black Tree)是一棵二叉查詢樹,在每個節點增加一個屬性表示節點顏色,值為紅色(Red)或者黑色(Black)。紅黑樹也是“平衡”樹中的一種,通過對任何一條從根到葉子的路徑上各個節點的顏色來進行約束,確保沒有一條路徑會比其他