<<
>>

4.7 Коды для красно-черных деревьев

typedef int T; /* type of item to be sorted */

#define compLT(a,b) (a < b)

#define compEQ(a,b) (a == b)

/* Red-Black tree description */

typedef enum { BLACK, RED } nodeColor;

typedef struct Node_ {

struct Node_ *left; /* left child */

struct Node_ *right; /* right child */

struct Node_ *parent; /* parent */

nodeColor color; /* node color (BLACK, RED) */

T data; /* data stoRED in node */

} Node;

#define NIL &sentinel /* all leafs are sentinels */

Node sentinel = { NIL, NIL, 0, BLACK, 0};

Node *root = NIL; /* root of Red-Black tree */

void rotateLeft(Node *x) {

/**************************

* rotate node x to left *

**************************/

Node *y = x->right;

/* establish x->right link */

x->right = y->left;

if (y->left != NIL) y->left->parent = x;

/* establish y->parent link */

if (y != NIL) y->parent = x->parent;

if (x->parent) {

if (x == x->parent->left)

x->parent->left = y;

else

x->parent->right = y;

} else {

root = y;

}

/* link x and y */

y->left = x;

if (x != NIL) x->parent = y;

}

void rotateRight(Node *x) {

/****************************

* rotate node x to right *

****************************/

Node *y = x->left;

/* establish x->left link */

x->left = y->right;

if (y->right != NIL) y->right->parent = x;

/* establish y->parent link */

if (y != NIL) y->parent = x->parent;

if (x->parent) {

if (x == x->parent->right)

x->parent->right = y;

else

x->parent->left = y;

} else {

root = y;

}

/* link x and y */

y->right = x;

if (x != NIL) x->parent = y;

}

void insertFixup(Node *x) {

/*************************************

* maintain Red-Black tree balance *

* after inserting node x *

*************************************/

/* check Red-Black properties */

while (x != root && x->parent->color == RED) {

/* we have a violation */

if (x->parent == x->parent->parent->left) {

Node *y = x->parent->parent->right;

if (y->color == RED) {

/* uncle is RED */

x->parent->color = BLACK;

y->color = BLACK;

x->parent->parent->color = RED;

x = x->parent->parent;

} else {

/* uncle is BLACK */

if (x == x->parent->right) {

/* make x a left child */

x = x->parent;

rotateLeft(x);

}

/* recolor and rotate */

x->parent->color = BLACK;

x->parent->parent->color = RED;

rotateRight(x->parent->parent);

}

} else {

/* mirror image of above code */

Node *y = x->parent->parent->left;

if (y->color == RED) {

/* uncle is RED */

x->parent->color = BLACK;

y->color = BLACK;

x->parent->parent->color = RED;

x = x->parent->parent;

} else {

/* uncle is BLACK */

if (x == x->parent->left) {

x = x->parent;

rotateRight(x);

}

x->parent->color = BLACK;

x->parent->parent->color = RED;

rotateLeft(x->parent->parent);

}

}

}

root->color = BLACK;

}

Node *insertNode(T data) {

Node *current, *parent, *x;

/***********************************************

* allocate node for data and insert in tree *

***********************************************/

/* find where node belongs */

current = root;

parent = 0;

while (current != NIL) {

if (compEQ(data, current->data)) return (current);

parent = current;

current = compLT(data, current->data) ?

current->left : current->right;

}

/* setup new node */

if ((x = malloc (sizeof(*x))) == 0) {

printf ("insufficient memory (insertNode)\n");

exit(1);

}

x->data = data;

x->parent = parent;

x->left = NIL;

x->right = NIL;

x->color = RED;

/* insert node in tree */

if(parent) {

if(compLT(data, parent->data))

parent->left = x;

else

parent->right = x;

} else {

root = x;

}

insertFixup(x);

return(x);

}

void deleteFixup(Node *x) {

/*************************************

* maintain Red-Black tree balance *

* after deleting node x *

*************************************/

while (x != root && x->color == BLACK) {

if (x == x->parent->left) {

Node *w = x->parent->right;

if (w->color == RED) {

w->color = BLACK;

x->parent->color = RED;

rotateLeft (x->parent);

w = x->parent->right;

}

if (w->left->color == BLACK && w->right->color == BLACK) {

w->color = RED;

x = x->parent;

} else {

if (w->right->color == BLACK) {

w->left->color = BLACK;

w->color = RED;

rotateRight (w);

w = x->parent->right;

}

w->color = x->parent->color;

x->parent->color = BLACK;

w->right->color = BLACK;

rotateLeft (x->parent);

x = root;

}

} else {

Node *w = x->parent->left;

if (w->color == RED) {

w->color = BLACK;

x->parent->color = RED;

rotateRight (x->parent);

w = x->parent->left;

}

if (w->right->color == BLACK && w->left->color == BLACK) {

w->color = RED;

x = x->parent;

} else {

if (w->left->color == BLACK) {

w->right->color = BLACK;

w->color = RED;

rotateLeft (w);

w = x->parent->left;

}

w->color = x->parent->color;

x->parent->color = BLACK;

w->left->color = BLACK;

rotateRight (x->parent);

x = root;

}

}

}

x->color = BLACK;

}

void deleteNode(Node *z) {

Node *x, *y;

/*****************************

* delete node z from tree *

*****************************/

if (!z || z == NIL) return;

if (z->left == NIL || z->right == NIL) {

/* y has a NIL node as a child */

y = z;

} else {

/* find tree successor with a NIL node as a child */

y = z->right;

while (y->left != NIL) y = y->left;

}

/* x is y's only child */

if (y->left != NIL)

x = y->left;

else

x = y->right;

/* remove y from the parent chain */

x->parent = y->parent;

if (y->parent)

if (y == y->parent->left)

y->parent->left = x;

else

y->parent->right = x;

else

root = x;

if (y != z) z->data = y->data;

if (y->color == BLACK)

deleteFixup (x);

free (y);

}

Node *findNode(T data) {

/*******************************

* find node containing data *

*******************************/

Node *current = root;

while(current != NIL)

if(compEQ(data, current->data))

return (current);

else

current = compLT (data, current->data) ?

current->left : current->right;

return(0);

}

<< | >>
Источник: Томас Ниман. Сортировка и поиск: Рецептурный справочник. 1995

Еще по теме 4.7 Коды для красно-черных деревьев:

  1. 4.6 Коды для бинарных деревьев
  2. 3.3 Красно-черные деревья
  3. Галай Ю.Г., Черных К.В.. Нищенство и бродяжничество в дореволюционной России : законодательные и практические проблемы: монография / Ю. Г. Ґалай, К. В. Черных. - Нижний Новгород : Нижегородская правовая академия,2012. -152 с., 2012
  4. 4.1 Коды для сортировки вставками
  5. 4.2 Коды для сортировки Шелла
  6. 4.5 Коды для хеш-таблиц
  7. 4.8 Коды для разделенных списков
  8. § 20. Незаконное пользование эмблемами и знаками Красного Креста и Красного Полумесяца
  9. Статья 445. Незаконное использование символики Красного Креста и Красного Полумесяца
  10. Статья 435. Незаконное использование символики Красного Креста и Красного Полумесяца и злоупотребление ими
  11. 4.3 Коды для быстрого поиска (функции Quicksort)
  12. 4.4 Коды для стандартной реализации быстрого поиска
  13. Красный плоский лишай на красной кайме губ
  14. Уничтожение критических местообитаний для организмов, занесенных в Красную книгу Российской Федерации
  15. Уничтожение критических местообитаний для организмов, занесенных в Красную книгу Российской Федерации (ст. 259 УК РФ)