Qizil-qora daraxt ma'lumotlar tuzilmasi
Qizil-qora daraxt (Red-Black Tree) — bu o'z-o'zini muvozanatlovchi (self-balancing) ikkilik qidiruv daraxti (Binary Search Tree) bo'lib, unda har bir tugun o'zining rangini (qizil yoki qora) bildiruvchi qo'shimcha bitga (atributga) ega bo'ladi.
Qizil-qora daraxt quyidagi 5 ta asosiy xususiyatga (qoidaga) javob beradi:
NIL yoki null) qora rangda hisoblanadi.Qizil-qora daraxtga misol:

Qizil-qora daraxt strukturasi
Har bir tugun quyidagi atributlarga ega:
color (rang: Qizil yoki Qora)key (kalit / qiymat)leftChild (chap farzand ko'rsatkichi)rightChild (o'ng farzand ko'rsatkichi)parent (ota tugun ko'rsatkichi)Tugunlarning qizil va qora ranglari daraxt muvozanatini saqlashga xizmat qiladi.
Yuqoridagi rang cheklovlari ildizdan barggacha bo'lgan har qanday oddiy yo'l boshqa ixtiyoriy shunday yo'ldan ko'pi bilan 2 barobardan ortiq uzun bo'lmasligini kafolatlaydi. Natijada daraxt balandligi har doim O(log n) bo'lib qoladi va qidiruv, qo'shish hamda o'chirish amallari kafolatlangan O(log n) vaqtda bajariladi.
Qo'shish yoki o'chirish amallari natijasida qizil-qora daraxt qoidalari buzilganda, daraxtni qayta muvozanatlash uchun burish (rotation) amallaridan foydalaniladi. Burish paytida qism-daraxt tugunlarining o'rni almashtiriladi, lekin ikkilik qidiruv daraxti tartibi buzilmaydi.
Asosiy burish turlari:
Chapga burish: Chapga burishda o'ng tarafdagi tugunlar chap tarafga o'tkaziladi.

Boshlang'ich holat
y ning chap qism-daraxti bo'lsa, x ni uning ota tuguni qilib belgilang:
y ning chap qism-daraxtini x ga bog'lash
x ning otasi NULL bo'lsa, y ni ildiz qiling. Aks holda x o'z otasi p ning chap farzandi bo'lsa y ni p ning chap farzandi, o'ng farzandi bo'lsa y ni o'ng farzandi qilib belgilang:
Ota ko'rsatkichini y ga o'tkazish
y ni x ning otasi qilib belgilang:
y ni x ning otasi qilib belgilash (Chapga burish tugallandi)
O'ngga burish: O'ngga burishda chap tarafdagi tugunlar o'ng tarafga o'tkaziladi.

Boshlang'ich holat
x ning o'ng qism-daraxti bo'lsa, y ni uning otasi qilib belgilang:
x ning o'ng qism-daraxtini y ga bog'lash
y ning ota ko'rsatkichini x ga o'tkazing:
Ota ko'rsatkichini x ga o'tkazish
x ni y ning otasi qilib belgilang:
x ni y ning otasi qilib belgilash (O'ngga burish tugallandi)
Chap-o'ng va o'ng-chap burishlar:
x-y ustida chapga burish, so'ngra y-z ustida o'ngga burish bajariladi:
1-qadam: x-y chapga burish

2-qadam: z-y o'ngga burish
x-y ustida o'ngga burish, so'ngra z-y ustida chapga burish bajariladi:
1-qadam: x-y o'ngga burish

2-qadam: z-y chapga burish
Batafsil kiritish va o'chirish amallari uchun quyidagi darslarga qarang:
package main
import "fmt"
type Color bool
const (
RED Color = true
BLACK Color = false
)
type Node struct {
data int
color Color
left *Node
right *Node
parent *Node
}
type RedBlackTree struct {
TNULL *Node
root *Node
}
func NewRedBlackTree() *RedBlackTree {
tnull := &Node{color: BLACK}
return &RedBlackTree{
TNULL: tnull,
root: tnull,
}
}
func (tree *RedBlackTree) leftRotate(x *Node) {
y := x.right
x.right = y.left
if y.left != tree.TNULL {
y.left.parent = x
}
y.parent = x.parent
if x.parent == nil {
tree.root = y
} else if x == x.parent.left {
x.parent.left = y
} else {
x.parent.right = y
}
y.left = x
x.parent = y
}
func (tree *RedBlackTree) rightRotate(x *Node) {
y := x.left
x.left = y.right
if y.right != tree.TNULL {
y.right.parent = x
}
y.parent = x.parent
if x.parent == nil {
tree.root = y
} else if x == x.parent.right {
x.parent.right = y
} else {
x.parent.left = y
}
y.right = x
x.parent = y
}
func (tree *RedBlackTree) insertFix(k *Node) {
for k.parent != nil && k.parent.color == RED {
if k.parent == k.parent.parent.right {
u := k.parent.parent.left // amaki (uncle)
if u.color == RED {
u.color = BLACK
k.parent.color = BLACK
k.parent.parent.color = RED
k = k.parent.parent
} else {
if k == k.parent.left {
k = k.parent
tree.rightRotate(k)
}
k.parent.color = BLACK
k.parent.parent.color = RED
tree.leftRotate(k.parent.parent)
}
} else {
u := k.parent.parent.right // amaki (uncle)
if u.color == RED {
u.color = BLACK
k.parent.color = BLACK
k.parent.parent.color = RED
k = k.parent.parent
} else {
if k == k.parent.right {
k = k.parent
tree.leftRotate(k)
}
k.parent.color = BLACK
k.parent.parent.color = RED
tree.rightRotate(k.parent.parent)
}
}
if k == tree.root {
break
}
}
tree.root.color = BLACK
}
func (tree *RedBlackTree) Insert(key int) {
node := &Node{
data: key,
color: RED,
left: tree.TNULL,
right: tree.TNULL,
parent: nil,
}
var y *Node = nil
x := tree.root
for x != tree.TNULL {
y = x
if node.data < x.data {
x = x.left
} else {
x = x.right
}
}
node.parent = y
if y == nil {
tree.root = node
} else if node.data < y.data {
y.left = node
} else {
y.right = node
}
if node.parent == nil {
node.color = BLACK
return
}
if node.parent.parent == nil {
return
}
tree.insertFix(node)
}
func (tree *RedBlackTree) printHelper(root *Node, indent string, last bool) {
if root != tree.TNULL {
fmt.Print(indent)
if last {
fmt.Print("R----")
indent += " "
} else {
fmt.Print("L----")
indent += "| "
}
sColor := "RED"
if root.color == BLACK {
sColor = "BLACK"
}
fmt.Printf("%d(%s)\n", root.data, sColor)
tree.printHelper(root.left, indent, false)
tree.printHelper(root.right, indent, true)
}
}
func (tree *RedBlackTree) PrintTree() {
tree.printHelper(tree.root, "", true)
}
func main() {
tree := NewRedBlackTree()
elements := []int{55, 40, 65, 60, 75, 57}
for _, e := range elements {
tree.Insert(e)
}
fmt.Println("Qizil-qora daraxt strukturasi:")
tree.PrintTree()
}java.util.TreeMap va java.util.TreeSet to'plamlarining asosi sifatida.std::set, std::map, std::multiset va std::multimap konteynerlarida.