Структуры данных (стеки, очереди, деревья...)

На этой странице размещены исходные коды различных структур данных. Написаны они различными авторами , в том числе и мной. Я благодарю авторов тех исходников, которые попали в эту копилку и по возможности буду указывать ссылку на их страницу.

 

Реализация стека с помощью динамического массива.

Описание: частный случай однонаправленного списка, где добавление и выборка значений происходит из одного конца. Принцип действия: "Последним вошел - первым вышел"

Type mType As Integer 

Type TStack
    iIndex As Integer
    iAll As Integer
    Dim IndexStack(Any) As mType
    Declare Sub init()
    Declare Sub free()
    Declare Sub push(As mType)
    Declare Function pop() As mType 
End Type

Sub TStack.init()
    Redim IndexStack(100) As mType
    iIndex = -1 : iAll = 100
End Sub

Sub TStack.free()
    Redim IndexStack(0) As mType
End Sub

Sub TStack.push( iValue As mType)
    
    If iIndex >= iAll Then
        iAll+=100
        Redim Preserve IndexStack(iAll) As mType
    Endif
    
    iIndex+=1
    IndexStack(iIndex) = iValue
    
End Sub

Function TStack.pop() As mType
    If iIndex > 0 Then
        Function = IndexStack(iIndex)
        iIndex -= 1
    Elseif iIndex = 0 Then  
        Function = IndexStack(iIndex)
        IndexStack(iIndex) = 0
        iIndex -= 1
        Redim IndexStack(100) As mType  
    Else
        Print "Stack empty!!!"
    Endif
End Function


'''''''''Test''''''''
Dim Shared stack As TStack

Stack.init()

For i As Integer  = 0 To 120
    Stack.push(i)
Next

For i As Integer  = 0 To 120
    ? Stack.pop
Next

Stack.free()
Sleep


Реализация очереди из 10 элементов

Описание для данной реализации: частный случай однонаправленного списка, где добавление значений происходит с конца, а выборка значений сначала. Принцип действия: "Первым вошел - первым вышел"

'\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
' Очередь из 10 элементов
'\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

' класс queue
Type queue
  v As Integer ' значение
  pNext As queue Ptr ' указатель на следующий элемент
  Declare Sub AddQueue( v As Integer) ' метод добавления
  Declare Sub DelQueue() ' метод полного удаления
  Declare Sub PrintQueue() ' вывод на консоль всех элементов
End Type

Dim Shared As queue Ptr pFirst, pEnd  ' указатели на начало и конец очереди
Dim Shared As Integer iIndex ' кол-во элементов в очереди

' метод добавления элемента в очередь
Sub queue.AddQueue( v As Integer)

  Dim pTemp As queue Ptr = New queue ' создаем новый элемент очереди
  pTemp->v = v ' присваиваем значение

  If iIndex<10 Then ' если очередь содержит меньше 10 элементов

   If iIndex = 0 Then ' если в очереди еще нет элементов
    pFirst = pTemp ' данный элемент становится первым в очереди
    pEnd = pTemp ' так же данный элемент является последним в очереди
    pEnd->pNext = 0 ' указатель на следующий элемент обнуляем
   Else
    pEnd->pNext = pTemp ' данный элемент ставим в очередь после последнего элемента
    pEnd = pTemp ' теперь этот элемент стал последним
    pTemp->pNext = 0 ' указатель на следующий элемент обнуляем
   Endif

   iIndex+=1 ' увеличиваем счетчик элементов

  Else

   Dim As queue Ptr pDel = pFirst ' запоминаем первый указатель для удаления
   pFirst = pFirst->pNext ' теперь второй элемент станет первым в очереди
   Delete pDel : pDel = 0 ' удаляем запомненный элемент и обнуляем

   pEnd->pNext = pTemp ' данный элемент ставим в очередь после последнего элемента
   pEnd = pTemp ' теперь этот элемент стал последним
   pTemp->pNext = 0 ' указатель на следующий элемент обнуляем
  Endif

End Sub

' метод удалениея всех элементов из очереди
Sub queue.DelQueue()

  ' временные указатели на элементы очереди,
  ' одному из них присваиваем первый элемент очереди
  Dim As queue Ptr pDel, pTemp =  pFirst

  While pTemp <> 0 ' пока указатель на элемент очереди существует

   pDel = pTemp ' присваиваем указатель на удаление
   pTemp = pTemp->pNext ' присваиваем указатель на следующий элемент
   Delete pDel ' удаляем элемент

  Wend

End Sub

' метод вывода на консоль всех элементов очереди
Sub queue.PrintQueue()
   
  ' временный указатель на элемент очереди,
  ' присваиваем ему указатель на первый элемент
  Dim As queue Ptr pTemp =  pFirst  
   
  While pTemp <> 0 ' пока указатель на элемент очереди существует

   Print pTemp->v & " "; ' выводим значение элемента очереди на консоль
   pTemp = pTemp->pNext ' присваиваем указатель на следующий элемент

  Wend  
  Print  
End Sub

'\\\\\\\\\\\\\\\\\\\\\\\\
' Тест работы класса
'\\\\\\\\\\\\\\\\\\\\\\\\

Dim pInitQueue As queue Ptr  = New queue ' инициализируем класс

' Цикл на 20 итераций (в очередь поступит 20 значений)
For i As Integer = 1 To 20  
  pInitQueue->AddQueue(i) ' добавляем элемент
  pInitQueue->PrintQueue() ' печатаем все элементы очереди
  Print ' пустая строка (разделитель)
  Print "Press any key!!!"
  Sleep
Next

pInitQueue->DelQueue() ' удаляем все элементы
Delete pInitQueue ' удаляем указатель инициализации класса
Print "End program, press any key"
Sleep

Битовые множества

Описание: позволяет экономно хранить ограниченный набор значений и отвечать на вопрос о принадлежности некоторого значения данному набору. Допустимое значение может входить во множество не более одного раза.

'тип - множество
Union TSet

    As Byte Data(32)
    As Long data_(8)

End Union

Dim Set As  TSet

' очищает множество
#MACRO ClearSet(set)
   Erase set.data_
#EndMacro

' включает элемент во множество
#MACRO IncludeSet(set,n)
    set.data( n Shr 3) Or= (1 Shl (n And 7))
#EndMacro

' возвращает не 0, если элемент есть во множестве
#MACRO InSet(set,n)
    set.data( n Shr 3 ) And (1 Shl ( n And 7))
#EndMacro

' Исключает элемент из множества
#MACRO UnSet(set,n)
    If InSet(set,n) Then
        set.data( n Shr 3) xor= (1 Shl (n And 7))
    Endif   
#EndMacro


'''''''''''''' Test '''''''''''''''''''

IncludeSet(set,11)
IncludeSet(set,12)
IncludeSet(set,13)

For i As Integer = 0 To 40
    ? i,InSet(Set,i)
Next

Print "Delete 12"
UnSet(Set,12)

For i As Integer = 0 To 40
    ? i,InSet(Set,i)
Next

ClearSet(set)

Sleep


Связанный список (однонаправленный)

Описание: чаще всего используется для больших , заранее неизвестных объемов входных данных. В отличие от массивов , элементы легко поддаются удалению, а список расширению\вставке. С другой стороны, доступ к элементам имеет линейную зависимость. Так же реализация сортировки заметно сложнее чем у массивов. Данный список является однонаправленным (односвязным), то есть содержит указатель только на следующий элемент и по нему связан. Для двухсвязного списка необходимо, чтобы в каждом узле списка содержался дополнительно указатель на предыдущий элемент и были организованы для него связи для каждого узла.

 

' Связанный список

Type myType As Integer

Type TList
    As myType Data
    As Integer iKey ' ключ для удаления и доступа к определенному элементу
    As TList Ptr p
End Type


Dim Shared As TList Ptr pFirst = 0 , pEnd = 0

' добавление в конец списка
Function addLast ( myData As myType) As Integer

    Dim As TList Ptr nw = Allocate(Sizeof(TList))

    If nw = 0 Then Return 0

    nw->Data = myData
    nw->p = 0

    If pFirst = 0 Then
        pFirst = nw
        pFirst->iKey = 1
        pEnd = pFirst
    Else
        nw->iKey = pEnd->iKey+1
        pEnd->p = nw
        pEnd = nw
    Endif

    Return 1

End Function

' добавление в начало списка
Function addBegin ( myData As myType) As Integer

    Dim As TList Ptr nw = Allocate(Sizeof(TList))

    If nw = 0 Then Return 0

    nw->Data = myData

    If pFirst = 0 Then
        pFirst = nw
        pFirst->iKey = 1
        pEnd = pFirst
    Else
        nw->p = pFirst
        pFirst = nw
        Dim As TList Ptr pTemp = pFirst
        Dim iKey As Integer = 1
        While pTemp
            pTemp->iKey = iKey
            pTemp = pTemp->p
            iKey += 1
        Wend
    Endif

    Return 1

End Function

' вставка элемента в любое место списка по индексу
Function insert ( iKey As Integer, myData As myType) As Integer
    
    Dim As TList Ptr nw = Allocate(Sizeof(TList))

    If nw = 0 Then Return 0
    
    nw->Data = myData   

    If pFirst = 0 Then
      Return addLast(myData)
    Elseif iKey = 1 Then
        Return addBegin(myData)     
    Elseif pEnd->iKey+1 <= iKey Then
        Return addLast(myData)
    Else
        Dim As TList Ptr pTemp = pFirst
        For i As Integer = 1 To iKey - 2
            pTemp = pTemp->p
        Next
        nw->p = pTemp->p
        pTemp->p = nw
        pTemp = pFirst
        Dim iKey As Integer = 1
        While pTemp
            pTemp->iKey = iKey
            pTemp = pTemp->p
            iKey += 1
        Wend    
        Return 1
    Endif
    
End Function

' удаление элемента из списка по заданному индексу
Function delElement ( iKey As Integer) As Integer

    Dim As TList Ptr pTemp = pFirst, pTempOld

    pTempOld = pTemp

    While pTemp

        If pTemp->iKey = iKey Then
            If pTemp->p <> 0 Then
                If pTemp = pFirst Then
                    pFirst = pTemp->p
                Else
                    pTempOld->p = pTemp->p
                Endif
            Else
                If pTemp = pFirst Then
                    pFirst = 0
                    pEnd = 0
                Else
                    pTempOld->p = 0
                    pEnd = pTempOld
                Endif
            Endif
            Deallocate(pTemp)
            pTemp = pFirst
            Dim iKey As Integer = 1
            While pTemp
                pTemp->iKey = iKey
                pTemp = pTemp->p
                iKey += 1
            Wend
            Return 1
        Endif

        pTempOld = pTemp
        pTemp = pTemp->p
    Wend

End Function

' получение значения элемента из списка по заданному индексу
Function getElement ( iKey As Integer) As myType
    Dim As TList Ptr pTemp = pFirst
    While pTemp
        If pTemp->iKey = iKey Then
            Return pTemp->Data
        Endif
        pTemp = pTemp->p
    Wend
End Function

' изменение значения для имеющегося элемента из списка по заданному индексу
Function setElement ( iKey As Integer, iData As myType ) As Integer
    Dim As TList Ptr pTemp = pFirst
    While pTemp
        If pTemp->iKey = iKey Then
            pTemp->Data = iData
            Return 1
        Endif
        pTemp = pTemp->p
    Wend
End Function

' печать всего списка
Sub PrintAll()
    Dim As TList Ptr pTemp = pFirst
    While pTemp
        Print "index = "; pTemp->iKey,"Value = ";pTemp->Data
        pTemp = pTemp->p
    Wend
End Sub

' удаление всего списка
Sub ClearList() 
    Dim As TList Ptr pTemp = pFirst, pDel
    While pTemp
        pDel = pTemp
        pTemp = pTemp->p
        Deallocate(pDel)
    Wend    
    pFirst = 0 : pEnd = 0
End Sub

''''''''''''' Тест ''''''''''''''''''''''

Randomize Timer

Print "---------Add Last-----------"
For i As Integer = 0 To 9
    addLast(Rnd*100)
Next
PrintAll()

Print "-----------Delete 10 element---------"
delElement(10)
PrintAll()

Print "----------Add Begin 3 elements----------"
For i As Integer = 0 To 2
    addBegin(i)
Next
PrintAll()

Print "---------Insert 2 element-----------"
insert(2,777)
PrintAll()

Print "--------get and set------------"
Print "Value for index 2 = "; getElement(2)
Print "Change Value for index 2" : setElement(2,999)
Print "Value for index 2 = "; getElement(2)
ClearList()
Sleep


 

Хеш-таблица

Описание: представляет из себя структуру данных, реализующую интерфейс ассоциативного массива. Если проще, то это некая структура (чаще всего массив) , каждая ячейка которого\й содержит указатель на отдельный список. Понятно, что если перебирать большой целый связанный список, то времени может уходить немало. Но hash функция обрабатывает значение перед вставкой в список\ки и определяет свою ячейку для своего связанного списка. При поиске значения , оно опять обрабатывается hash функцией и таким образом определяет в каком списке какой ячейки искать это значение. Скорость поиска значений с использованием hash таблиц в среднем значительно быстрее поиска в связанном списке. Ссылка на страницу автора исходного кода

 

'  This HashFunction basically converts the first several bytes
'  of a string into a machine dependent integer which is then
'  wrapped into the hash table. The string length cannot be smaller
'  than the sizeof(int).  

#INCLUDE "crt.bi"

#DEFINE  HTABLESIZE     10

Type Node
    As Node Ptr Next
    As Zstring Ptr Data 
End Type

Dim Shared As Node Ptr HashTable(HTABLESIZE)

Declare Sub HashTableCreate()
Declare Sub HashTableDestroy()
Declare Function HashTableInsert(data_ As Zstring Ptr) As Integer ' =-1 on failure, =0 if ok
Declare Function HashTableFind(data_ As Zstring Ptr) As node Ptr ' search return data node
Declare Function HashTableDelete(data_ As Zstring Ptr) As Integer ' =0 on ok, =-1 on fail
Declare Function  HashFunction(data_ As Zstring Ptr) As Integer
Declare Sub HashTablePrint()  ' Print all elements in table



''''''''''''''''''''''''''''
    Dim As Integer i
    HashTableCreate()

    For i = 1 To 99  ' Insert Keys "1key"-"99key"
        Dim As ZString*100 buf
        sprintf(buf,!"%dkey",i)
        HashTableInsert(buf)
    Next

    HashTablePrint()    ' Print out all of the Hash Table

    For i = 50 To 90  '  Remove keys "50key"-"90key"
        Dim As ZString*100 buf
        sprintf(buf,!"%dkey",i)
        HashTableDelete(buf)
    Next

    HashTablePrint()    ' Print out Hash table

    HashTableDestroy()  ' Destroy the Hash Table
Sleep

''''''''''''''''''''''''''''
Sub HashTableCreate()
    Dim As Integer i
    For i = 0 To HTABLESIZE - 1
        HashTable(i)=0
    Next    
End Sub

    


''''''''''''''''''''''''''''
Sub HashTableDestroy()
    Dim As Integer i
    For i = 0 To HTABLESIZE - 1
        Dim As Node Ptr p
        p = HashTable(i)
        While p <> 0
            Dim As Node Ptr tmp
            tmp = p
            p = p->Next
            free(tmp->Data)
            free(tmp)
        Wend
    Next    
End Sub

    


''''''''''''''''''''''''''''
Function HashTableInsert(data_ As Zstring Ptr) As Integer ' =-1 on failure, =0 if ok
    Dim As Integer ind
    Dim As Node Ptr nw
    nw = malloc(Sizeof(Node))
    If nw =0 Then Return -1
    nw->Data = malloc(1+Len(data_))
    If nw->Data = 0 Then
        free(nw)
        Return -1
    Endif
    strcpy(nw->Data,Data_)
    ind = HashFunction(data_)
    nw->Next = HashTable(ind)  
    HashTable(ind) = nw
    Return 0
End Function


''''''''''''''''''''''''''''
Function HashTableFind(data_ As Zstring Ptr) As node Ptr ' search return data node
    Dim As  Node Ptr p
    p = HashTable(HashFunction(data_))
    While p <> 0    
        If StrCmp(p->Data,data_) = 0  Then Return p
        p = p->Next
    Wend

    Return 0
End Function


''''''''''''''''''''''''''''
Function HashTableDelete(data_ As Zstring Ptr) As Integer ' =0 ok, =-1 on fail
    Dim As Integer ind
    Dim As Node Ptr p
    ind = HashFunction(data_)
    p = HashTable(ind)
    If p = 0 Then Return -1
    If StrCmp(p->Data,data_) = 0  Then
        HashTable(ind) = p->Next
        free(p->Data)
        free(p)
        Return 0
    Endif

    While p->Next <> 0 
        
        If StrCmp(p->Next->Data,data_) = 0 Then
            Dim As Node Ptr tmp
            tmp = p->Next
            p->Next = tmp->Next 
            free(tmp->Data)
            free(tmp)
            Return 0
        Endif   
        p = p->Next
    Wend

    Return -1
End Function


'''''''''''''''''''''''''''''''''
Function HashFunction(data_ As Zstring Ptr) As Integer ' convert the first several bytes into int
    Return *Cast(Integer Ptr,data_) Mod HTABLESIZE  
End Function




''''''''''''''''''''''''''''''
Sub HashTablePrint()  ' Print all elements in table
    Dim As Integer i
    For i = 0 To HTABLESIZE - 1
        Dim As Node Ptr p
        printf(!"Slot %d:",i)

        p = HashTable(i)

        While p <> 0
            printf(!" %s",p->Data)
            p = p->Next             
        Wend

        printf(!"\n")
    Next
    printf(!"\n")
End Sub


    

 

Бинарное дерево (рекурсивная реализация)

Описание: преимущества бинарного дерева по сравнению с другими структурами данных - это простая реализация и возможная эффективность при поиске значений, а так же сортировка значений. Это простейшая реализация , главной целю которой, было показать начинающим основы построения дерева. Реализация имела только методы добавления и обхода дерева. Я решил добавить функцию поиска. Само по себе бинарное дерево в данной реализации является несбалансированным, то есть при определенных условиях , поиск значения может показать не самые завидные результаты. Лучшим решением конечно являются самосбалансированные деревья (AVL или Красно-черное) , но они заметно сложнее в реализации. На данной странице (ниже) представлены примеры самосбалансированных деревьев. Ссылка на страницу автора исходного кода и описания.  

 

Type Node 'Звено дерева
    As Integer x 'То, что записываем в дерево
    As Node Ptr l,r 'Это указатели на новые звенья
End Type

Sub show(Byref Tree As Node Ptr ) 'Функция обхода
    If (Tree<>0) Then 'Пока не встретится пустое звено
        show(Tree->l) 'Рекурсивная функция для вывода левого поддерева
        Print Tree->x 'Отображаем корень дерева
        show(Tree->r) 'Рекурсивная функци для вывода правого поддерева
    Endif
End Sub

Sub add_node(x As Integer, Byref MyTree As Node Ptr) 'Фукция добавления звена в дерево

    If (MyTree = 0) Then  'То, о чем я в самом начале писал. Если дерева нет, то ложим семечко
        MyTree=new Node 'Выделяем память под звено дерева
        MyTree->x=x 'Записываем данные в звено
        MyTree->l=0 'Подзвенья инициализируем пустотой во избежание ошибок
        MyTree->r=0 'Подзвенья инициализируем пустотой во избежание ошибок
    Endif

    If (x<MyTree->x) Then   'Если нововведенный элемент x меньше чем элемент x из семечка дерева, уходим влево
        If (MyTree->l<>0) Then
            add_node(x,MyTree->l) 'При помощи рекурсии заталкиваем элемент на свободный участок
        Else 'Если элемент получил свой участок, то
            MyTree->l=new Node  'Выделяем память левому подзвену. Именно подзвену, а не просто звену
            MyTree->l->l=0 : MyTree->l->r=0 'У левого подзвена будут свои левое и правое подзвенья, инициализируем их пустотой
            MyTree->l->x=x 'Записываем в левое подзвено записываемый элемент
        Endif
    Endif

    If (x>MyTree->x) Then  'Если нововведенный элемент x больше чем элемент x из семечка дерева, уходим вправо
        If (MyTree->r<>0)Then
            add_node(x,MyTree->r) 'При помощи рекурсии заталкиваем элемент на свободный участок
        Else 'Если элемент получил свой участок, то
            MyTree->r=new Node  'Выделяем память правому подзвену. Именно подзвену, а не просто звену
            MyTree->r->l=0:MyTree->r->r=0 'У правого подзвена будут свои левое и правое подзвенья, инициализируем их пустотой
            MyTree->r->x=x 'Записываем в правое подзвено записываемый элемент
        Endif
    Endif

End Sub

' функция поиска значения
Function find_node(ikey As Integer, MyTree As Node Ptr) As Node Ptr
    
    ' если такого звена нет ИЛИ ключ найден, возвращаем указатель на него
    If MyTree = 0 OrElse MyTree->x = ikey Then Return MyTree

   If MyTree->x < ikey Then ' если ключ больше чем значение в данном звене
            Return find_node(iKey,MyTree->r) ' поехали искать по правому краю
   Else ' иначе
            Return find_node(iKey,MyTree->l)    ' поехали искать по левому краю
   Endif
   
End Function


Dim As Node Ptr Tree=0  'Создаю указатель, тип которого = звено дерева и инициализирую его пустотой

For  i As integer=5 To 1 Step -1
    add_node(i,Tree) 'Это я забивал 5-4-3-2-1, а вывод сами увидите
Next

show(Tree) 'Вывод на экран дерева. или просто обход дерева

Dim As Node Ptr fNode = find_node(3,Tree) 'ищем звено дерева для значения 3

If fNode <> 0 Then ' если звено найдено
    ? "Find:"; fNode->x ' печатаем что там находится
Else
    ? "not found" ' не найдено значение в дереве
Endif

Sleep

 

Бинарное дерево (итерационная реализация)

Описание: нерекурсивная реализация бинарного дерева может пригодится для программ обильно использующих стек, чтобы оградить себя от возможного переполнения стека. Ссылка на страницу автора исходного кода.

 

' BOX #1:  Right Threaded Tree.

Enum Direction
    UP
    DOWN
End Enum

Type Node
    As Integer Data_
    As Node Ptr Left_,Right_
    RightDirection As Direction  ' Should be a single bit
End Type

''''''''''''''''''''
Dim Shared As Node Ptr Root = 0
'''''''''''''''''''/

Declare Function InsertItem(data_ As Integer) As Integer '=0 on OK, =-1 on fail
Declare Function SearchItem(data_ As Integer) As Node Ptr '=0 on fail
Declare Sub DestroyTree(tree As node Ptr)  ' destroy tree
Declare Sub PrintTree()  ' Print the tree



Dim i As Integer
For i=0 To 10000  ' Insert Some Items into tree
    InsertItem(i)
Next

PrintTree()  ' Print Tree In-Order Traversal

DestroyTree(Root)
Sleep
''''''''''''''''''''
Sub DestroyTree(tree As node Ptr)
    If tree = 0 Then
        Exit Sub
    Endif
    DestroyTree(tree->Left_)
    If tree->RightDirection = DOWN  Then
        DestroyTree(tree->Right_)
    Endif
    Deallocate(tree)
End Sub

''''''''''''''''''''/
Function InsertItem(data_ As Integer) As Integer
    Dim As Node Ptr nw,p
    nw = Callocate(Sizeof(Node))
    If nw = 0 Then Return -1
    nw->Data_ = data_
    If Root = 0 Then
        nw->RightDirection = DOWN
        Root = nw
        Return 0
    Endif
    p = Root
    Do
        If data_<=p->Data_ Then
            If p->Left_ = 0 Then
                p->Left_ = nw
                nw->Right_ = p
                nw->RightDirection = UP
                Return 0
            Endif
            p=p->Left_
        Else
            If p->Right_ = 0 Or p->RightDirection = UP Then
                nw->Right_ = p->Right_
                p->Right_ = nw
                p->RightDirection = DOWN
                Return 0
            Endif
            p = p->Right_
        Endif
    Loop
End Function


''''''''''''''''''''
Sub PrintTree() ' Use Threading to print the whole tree
    Dim As  Node Ptr p
    Dim Dir_ As Direction
    p = Root
    Dir_ = DOWN
    While p<>0
        If dir_ = DOWN Then
            If p->Left_ <> 0 Then
                p = p->Left_
                Continue While
            Elseif p->Left_ = 0 Then
                dir_ = UP
                Continue While
            Endif
            Dir_ = p->RightDirection
            p = p->Right_
        Else
            ? p->Data_,
            dir_ = p->RightDirection
            p = p->Right_           
        Endif
    Wend
End Sub

 

AVL дерево

Описание: данное дерево является разновидностью бинарного дерева. В реализацию алгоритма заложено самосбалансирование узлов дерева, то есть для каждой его вершины высота её двух поддеревьев различается не более чем на единицу. Такое дерево дает очень эффективный поиск значений, а так же вставку значений. Ссылка на страницу автора исходного кода.

 

'   AVL Tree 
'   Insertion Time :  Best:Theta(n*lg(n))  Worst:Theta(n*lg(n))  Avg:Theta(n*lg(n))
'   Search Time    :  Best:Theta(1)        Worst:Theta(n*lg(n))  Avg:Theta(n*lg(n))
'   Deletion Time  :  Best:Theta(n*lg(n))  Worst:Theta(n*lg(n))  Avg:Theta(n*lg(n))

#INCLUDE "crt.bi"


'''''''''''''''''''''''
Type Node 
    
    As Integer Data  
    
    As Integer HeightDiff           ' Height Between Left and Right Subtree
    
    As Node Ptr Left,Right      
    
End Type

''''''''''''''''''''''''''''''
Function maxmin( i1 As Integer , i2 As Integer) As Integer
    
    Return Iif(i1 > i2, i1,i2)
    
End Function


'''''''''''''''''''
' Rotates around the current node 
Function LeftRotate(node As Node Ptr) As Integer  ' =1 if rotate works,=0 otherwise 
    
    Dim As Node Ptr nd
    Dim As Integer data_  , midheight , leftheight
    
    If node = 0 ORELSE node->Right = 0 Then Return 0    ' No Right Node!!

    nd = node->Right

    midheight = nd->HeightDiff
    
    leftheight = maxmin(nd->HeightDiff,0)+1+node->HeightDiff

    node->Right = nd->Right  ' Move Node
    
    nd->Right = nd->Left
    
    nd->Left = node->Left
    
    node->Left = nd

    data_ = node->Data
    
    node->Data = nd->Data
    
    nd->Data = Data_

    node->Left->HeightDiff = leftheight-midheight
    
    node->HeightDiff = 1 + maxmin(leftheight,midheight)

    Return 1
    
End Function


''''''''''''''''''/
' Rotate around current node
Function RightRotate(node As Node Ptr) As Integer ' =1 if rotate works, =0 otherwise
    
    Dim As Node Ptr nd
    Dim As Integer data_ , leftheight,rightheight
    
    If node = 0 ORELSE node->Left = 0 Then Return 0 

    nd = node->Left

    leftheight = nd->HeightDiff
    
    rightheight = maxmin(leftheight,0)+1-node->HeightDiff

    node->Left = nd->Left
    
    nd->Left = nd->Right
    
     nd->Right = node->Right
     
    node->Right = nd

    data_ = node->Data
    
     node->Data = nd->Data
     
      nd->Data = Data_

    node->Right->HeightDiff = 0 - rightheight
    
    node->HeightDiff = leftheight-(1 + maxmin(0,rightheight))
    
    Return 1
    
End Function



''''''''''''''''''/
Enum avlenum
    
    DONTADJUST
    
    ADJUST 
    
End Enum

Function InsertValue( root As Node Ptr Ptr , value As Integer) As avlenum ' =1 on success, =0 on fail

    If (*root) = 0 Then 
            
            Dim As Node Ptr nw
            
            nw = malloc(Sizeof( Node ))
            
            If nw = 0 Then Return DONTADJUST
            
            nw->Left = 0
            
            nw->Right = 0
            
            nw->Data = value
            
            nw->HeightDiff = 0
            
            (*root) = nw
            
            Return ADJUST
    
    Endif

    If value < (*root)->Data Then
        
        If InsertValue(@(*root)->Left,value) = DONTADJUST Then Return DONTADJUST

        '''''/ Increase Balance '''''''''/
        (*root)->HeightDiff += 1

        '''''' Tree has become Balanced ''''''''
        If (*root)->HeightDiff = 0 Then Return DONTADJUST

        '''''' Check For Rotation ''''''''''/
        If (*root)->HeightDiff = +2 Then ' Rotate + Stop

            ' Check if in Homogenous Config.
            If (*root)->Left->HeightDiff = +1 Then ' Homogenous. Conf.
                
                RightRotate(*root)
                
                Return DONTADJUST
                
            Endif
            '  Hetrogenous Conf
            LeftRotate((*root)->Left)
            
            RightRotate(*root)
            
            Return DONTADJUST
            
        Endif

        '''''/ Keep Going up the tree '''''''/
        Return ADJUST
        
    Elseif value > ((*root)->Data)  Then
        
        If InsertValue(@(*root)->Right,value) = DONTADJUST Then Return DONTADJUST

        '''''/ Decrease Balance '''''''''/
        (*root)->HeightDiff -= 1

        '''''' Tree has become Balanced ''''''''
        If (*root)->HeightDiff = 0 Then Return DONTADJUST

        '''''' Check For Rotation ''''''''''/
        If (*root)->HeightDiff = -2 Then ' Rotate + Stop
            
            ' Check if in Homogenous Config.
            If (*root)->Right->HeightDiff = -1 Then ' Homogenous. Conf.
            
                LeftRotate(*root)
                
                Return DONTADJUST
                
            Endif
            '  Hetrogenous Conf
            RightRotate((*root)->Right)
            
            LeftRotate(*root)
            
            Return DONTADJUST
        Endif

        '''''/ Keep Going up the tree '''''''/
        Return ADJUST
        
    Else
    
        printf(!"Item (%d) already exists in tree\n",value)
        
        Return DONTADJUST
        
    Endif
End Function


''''''''''''''''''''
Sub PrintTree(root As Node Ptr)
 
 ' Perform Inorder Traversal of tree
    If root = 0 Then Exit Sub
    
    PrintTree(root->Left)
    
    printf(!" %d(%d) ",root->Data,root->HeightDiff)
    
    PrintTree(root->Right)
    
End Sub


''''''''''''''''''''
Sub DeleteTree(root As Node Ptr)
    
    If root = 0 Then Exit Sub
    
    DeleteTree(root->Left)
    
    DeleteTree(root->Right)
    
    free(root)
    
End Sub


''''''''''''''''''''
Function Height(root As Node Ptr) As Integer

    If root = 0 Then Return 0
    
    Return 1 + maxmin(Height(root->Left),Height(root->Right))
    
End Function


''''''''' Check if Tree is an AVL Tree''''''''''/
Function DoubleCheck(root As Node Ptr) As Integer ' =0 if Check Fails,=1 if OK
    
    If root = 0 Then Return 1

    If DoubleCheck(root->Left) = 0 orelse DoubleCheck(root->Right) = 0 Then Return 0

    ' Check if Tree Is OK
    If Height(root->Left)-Height(root->Right) <> root->HeightDiff Then Return 0

    If root->HeightDiff < -1 orelse root->HeightDiff > +1 Then Return 0

    Return 1

End Function


''''''''''''''''''''''''''''''''
Function Count(root As Node Ptr) As Integer ' = return total count of nodes in tree

    If root = 0 Then Return 0
    
    Return 1+Count(root->Left)+Count(root->Right)

End Function


'''''''''''''''''''''''''''''''/
Function PrintStatus(root As Node Ptr) As Integer  ' =1 if Ok,=0 if not AVL tree
    
    printf(!"Status: Count: %d  ",Count(root))

    If DoubleCheck(root) = 0 Then
        
        printf(!"Tree is not an AVL Tree\n")
        
        Return 0
        
    Else
    
        printf(!"Tree is an AVL Tree\n")
        
        Return 1
        
    Endif

End Function

'''''''''''''''''''
Dim As Node Ptr root = 0

Dim As Integer i

    Randomize Timer 
    
    '''''/ Insert Some Values Into Tree ''''''''
    For i = 0 To 1000
        
        InsertValue(@root,Rnd*200) 
        
        If PrintStatus(root) = 0 Then Beep : End
        
    Next
    
    printf(!"Tree: ")
    
    PrintTree(root)
    
    printf(!"\n")

    DeleteTree(root)
    
    Sleep

 

Еще один пример (взят отсюда), но в нем реализовано больше методов (поиск, удаление и др.):

 

#INCLUDE "crt.bi"

Type node
      As Integer element
      As node Ptr Left
      As node Ptr Right
      As Integer height
End Type

Type bstree extends Object
      Declare Sub insert(As Integer,Byref As node Ptr)
      Declare Sub del(As Integer, Byref As node Ptr)
      Declare Function deletemin(Byref As node Ptr)As Integer
      Declare Sub find(As Integer,Byref As node Ptr)
      Declare Function findmin(Byref As node Ptr)As node Ptr
      Declare Function findmax(Byref As node Ptr)As node Ptr
      Declare Sub makeempty(Byref As node Ptr)
      Declare Sub copy(Byref As node Ptr,Byref As node Ptr)
      Declare Function nodecopy(Byref As node Ptr)As node Ptr
      Declare Sub preorder(As node Ptr)
      Declare Sub inorder(As node Ptr)
      Declare Sub postorder(As node Ptr)
      Declare Function bsheight(As node Ptr)As Integer
      Declare Function srl(Byref As node Ptr)As node Ptr
      Declare Function drl(Byref As node Ptr)As node Ptr
      Declare Function srr(Byref As node Ptr)As node Ptr
      Declare Function drr(Byref As node Ptr)As node Ptr
      Declare Function max(As Integer,As Integer)As Integer
      Declare Function nonodes(As node Ptr)As Integer
End Type

' Inserting a node
Sub bstree.insert(x As Integer,Byref p As node Ptr)
      If (p = NULL) Then
          p = New node
          p->element = x
          p->left=NULL
          p->Right = NULL
          p->height=0
          If (p=NULL) Then
              printf (!"Out of Space\n")
          Endif
      Else
          If (x<p->element) Then
              insert(x,p->Left)
              If ((bsheight(p->Left) - bsheight(p->Right))=2) Then
                  If (x < p->left->element) Then
                      p=srl(p)
                  Else
                      p = drl(p)
                  Endif
              Endif
          Elseif (x>p->element) Then
              insert(x,p->Right)
              If ((bsheight(p->Right) - bsheight(p->Left))=2) Then
                  If (x > p->right->element) Then
                      p=srr(p)
                  Else
                      p = drr(p)
                  Endif
              Endif
          Else
              printf(!"Элемет существует\n")
          Endif
      Endif
      Dim As Integer m,n,d
      m=bsheight(p->Left)
      n=bsheight(p->Right)
      d=max(m,n)
      p->height = d + 1
End Sub

' Finding the Smallest
Function bstree.findmin(Byref p As node Ptr) As node Ptr
      If (p=NULL) Then
          printf(!"В дереве нет элементов\n")
          Return p
      Else
          Dim pp As  node Ptr = p
          While (pp->Left<>NULL)
              pp=pp->Left
              'return p;
          Wend
          Return pp
      Endif
End Function

' Finding the Largest node
Function bstree.findmax(Byref  p As node Ptr) As node Ptr
      If (p=NULL) Then
          printf(!"В дереве нет элементов\n")
          Return p
      Else
          Dim pp As  node Ptr = p
          While(pp->Right <>NULL)
              pp=pp->Right
              'return p;
          Wend
          Return pp
      Endif
End Function

' Finding an element
Sub bstree.find(x As Integer,Byref p As node Ptr )
      If (p=NULL) Then
          printf(!"Простите, но такого элемента нет\n")
      Else
          If (x < p->element) Then
              find(x,p->Left)
          Else
              If (x>p->element) Then
                  find(x,p->Right)
              Else
                  printf(!"Элемент, который вы искали есть в дереве!\n")
              Endif
          Endif
      Endif
End Sub

' Copy a tree
Sub bstree.copy(Byref p As node Ptr,Byref p1 As node Ptr)
      makeempty(p1)
      p1 = nodecopy(p)
End Sub

' Make a tree empty
Sub bstree.makeempty(Byref p As node Ptr)
      If (p <> NULL) Then
          makeempty(p->Left)
          makeempty(p->Right)
          Delete p
          p=NULL
      Endif
End Sub

' Copy the nodes
Function bstree.nodecopy(Byref p As node Ptr) As node Ptr
      Dim As node Ptr temp
      If (p=NULL) Then
          Return p
      Else
          temp = New node
          temp->element = p->element
          temp->Left = nodecopy(p->Left)
          temp->Right = nodecopy(p->Right)
          Return temp
      Endif
End Function

' Deleting a node
Sub bstree.del(x As Integer ,Byref p As node Ptr)
      If (p=NULL) Then
          printf(!"Простите, но такого элемента нет\n")
      Elseif ( x < p->element) Then
          del(x,p->Left)
      Elseif (x > p->element) Then
          del(x,p->Right)
      Elseif ((p->Left = NULL) And (p->Right = NULL)) Then
          Delete p
          p=NULL
          printf(!"Элемент удален\n")
      Elseif (p->Left = NULL) Then
          p=p->Right
          Delete p
          p=NULL
          printf(!"Элемент удален\n")
      Elseif (p->Right = NULL) Then
          p=p->Left
          Delete p
          p=NULL
          printf(!"Элемент удален\n")
      Else
          p->element = deletemin(p->Right)
      Endif
End Sub

Function bstree.deletemin(Byref p As node Ptr)As Integer
      Dim As Integer c
      printf(!"Выбрано удаление минимального значения\n")
      If (p->Left = NULL) Then
          c=p->element
          p=p->Right
          Return c
      Else
          c=deletemin(p->Left)
          Return c
      Endif
End Function

Sub bstree.preorder(p As node Ptr)
      If (p<>NULL) Then
          Printf(p->element & !"\t")
          preorder(p->Left)
          preorder(p->Right)
      Endif
End Sub

' Inorder Printing
Sub bstree.inorder(p As node Ptr)
      If (p<>NULL) Then
          inorder(p->Left)
          Printf(p->element & !"\t")
          inorder(p->Right)
      Endif
End Sub

'PostOrder Printing
Sub bstree.postorder(p As node Ptr)
      If (p<>NULL) Then
          postorder(p->Left)
          postorder(p->Right)
          Printf(p->element & !"\t")
      Endif
End Sub

Function bstree.max(value1 As Integer, value2 As Integer) As Integer
      Return Iif(value1 > value2 , value1 , value2)
End Function

Function bstree.bsheight(p As node Ptr) As Integer
      Dim As Integer t
      If (p = NULL) Then
          Return -1
      Else
          t = p->height
          Return t
      Endif
End Function

Function bstree.srl(Byref p1 As node Ptr ) As node Ptr
      Dim As node Ptr p2
      p2 = p1->Left
      p1->Left = p2->Right
      p2->Right = p1
      p1->height = max(bsheight(p1->Left),bsheight(p1->Right)) + 1
      p2->height = max(bsheight(p2->Left),p1->height) + 1
      Return p2
End Function

Function  bstree.srr(Byref p1 As node Ptr) As node Ptr
      Dim As node Ptr p2
      p2 = p1->Right
      p1->Right = p2->Left
      p2->Left = p1
      p1->height = max(bsheight(p1->Left),bsheight(p1->Right)) + 1
      p2->height = max(p1->height,bsheight(p2->Right)) + 1
      Return p2
End Function

Function bstree.drl(Byref p1 As node Ptr) As node Ptr
      p1->left=srr(p1->Left)
      Return srl(p1)
End Function

Function bstree.drr(Byref p1 As node Ptr)As node Ptr
      p1->Right = srl(p1->Right)
      Return srr(p1)
End Function

Function bstree.nonodes(p As node Ptr) As Integer
      Dim As Integer count
      If (p<>NULL) Then
          nonodes(p->Left)
          nonodes(p->Right)
          count+=1
      Endif
      Return count
End Function

'clrscr();
Dim As node Ptr root,root1,min,max ',flag;
Dim As Integer a,choice,findele,delele_
Dim As bstree bst
'system("clear");
root = NULL
root1=NULL
Printf(!"\n\t\t\t\tАВЛ Дерево\n")
Printf(!"\t\t\t\t:::::::::::::::::::\n")

Do
      Printf(!"\t\t::::::::::::::::::::::::::::::::::::::::::::::::\n")
      Printf(!"\t\t::::1 Вставить новый узел::::::::::::::::\n")
      Printf(!"\t\t::::2 Найти минимальный элемент:::::::::::\n")
      Printf(!"\t\t::::3 Найти максимальный элемент:::::::::::::::\n")
      Printf(!"\t\t::::4 Поиск по значению:::::::::::::::::::\n")
      Printf(!"\t\t::::5 Удалить элемент:::::::::::::::::::\n")
      Printf(!"\t\t::::6 Вариант обхода1:::::::::::::::::\n")
      Printf(!"\t\t::::7 Вариант обхода2::::::::::::::::::\n")
      Printf(!"\t\t::::8 Вариант обхода3::::::::::::::::\n")
      Printf(!"\t\t::::9 Показать высоту дерева:::\n")
      Printf(!"\t\t::::10 Выход:::::::::::::::::::::::::::::\n")
      Printf(!"\t\t::::::::::::::::::::::::::::::::::::::::::::::::\n")

      Printf(!"\nВыберите нужное действие и нажмите Enter: ")
      Input "",choice

      Select Case choice
          Case 1
              Printf(!"\n\t\tДобавление нового узла")
              Printf(!"\t\t:::::::::::::\n")
              Printf(!"Введите элемент: ")
              Input "" ,a
              bst.insert(a,root)
              Printf(!"\nНовый элемент добавлен успешно\n")
          Case 2
              If (root <>NULL) Then
                  min=bst.findmin(root)
                  Printf(!"\nМинимальный элемент в дереве: " & min->element)
              Endif
          Case 3
              If (root <>NULL) Then
                  max=bst.findmax(root)
                  Printf(!"\nМаксимальный элемент в дереве: " & max->element)
              Endif
          Case 4
              Printf(!"\nВведите искомый элемент: ")
              Input "",findele
              If (root <> NULL) Then
                  bst.find(findele,root)
              Endif
          Case 5
              Printf(!"\nКакой узел удалять? : ")
              Input "", delele_
              bst.del(delele_,root)
              bst.inorder(root)
              Print
          Case 6
              Printf(!"\n\t\tВариант обхода1\n")
              bst.preorder(root)
              Print
          Case 7
              Printf(!"\n\t\tВариант обхода2\n")
              bst.inorder(root)
              Print
          Case 8
              Printf(!"\n\t\tВарант обхода3\n")
              bst.postorder(root)
              Print
          Case 9
              Printf(!"\n\t\tВЫСОТА\n")
              Printf(!"Дерево имеет высоту: " & bst.bsheight(root))
          Case 10
              Printf(!"\n\tБлагодарим вас за использование програмы\n")
          Case Else
              Printf(!"Sorry! wrong input\n")
      End Select
      Sleep
      Cls
Loop While(choice <> 10)

 

Красно - черное дерево

Описание: это дерево как и AVL является разновидностью бинарного. Для многих программистов данный алгоритм является более предпочтительным при хранении данных , для которых нужна сортировка и быстрый поиск. Стандартная библиотека С++ STL (map , set и пр.) построена именно на основе красно-черных деревьев. По большому счету, пример ниже уже можно использовать как словарь или множество. Я тестировал на больших объемах данных, скорость вставки и поиска очень высока. Ссылка на страницу автора исходного кода 

 

'/* red-black tree */

#INCLUDE "crt.bi"


Type T As Integer                 ' /* type of item to be stored */


'/* Red-Black tree description */
Enum nodeColor
    BLACK
    RED
End Enum

Type Node_
    As Node_  Ptr Left         '/* left child */
    As Node_  Ptr Right        '/* right child */
    As Node_ Ptr parent       '/* parent */
    As nodeColor Color            '/* node color (BLACK, RED) */
    As T Data                    '/* data stored in node */
End Type

Type  Node As Node_

#DEFINE NIL @sentinel           '/* all leafs are sentinels */
Dim Shared As Node sentinel = Type( NIL, NIL, 0, BLACK, 0)

Dim Shared As Node Ptr root = NIL               '/* root of Red-Black tree */

Sub rotateLeft(x As Node Ptr)

    '/**************************
    ' *  rotate node x to left *
    ' **************************/

    Dim As Node Ptr y = x->Right

    '/* establish x->right link */
    x->Right = y->Left
    If (y->Left <> NIL) Then y->Left->parent = x

    '/* establish y->parent link */
    If (y <> NIL) Then y->parent = x->parent

    If (x->parent) Then
        If (x = x->parent->Left) Then
            x->parent->Left = y
        Else
            x->parent->Right = y
        Endif
    Else
        root = y
    Endif

    '/* link x and y */
    y->Left = x
    If (x <> NIL) Then x->parent = y
End Sub

Sub rotateRight(x As Node Ptr)

    '/****************************
    ' *  rotate node x to right  *
    ' ****************************/

    Dim As Node Ptr y = x->Left

    '/* establish x->left link */
    x->Left = y->Right
    If (y->Right <> NIL) Then y->Right->parent = x

    '/* establish y->parent link */
    If (y <> NIL) Then y->parent = x->parent

    If (x->parent) Then

        If (x = x->parent->Right) Then

            x->parent->Right = y

        Else

            x->parent->Left = y

        Endif

    Else
        root = y
    Endif

    '/* link x and y */
    y->Right = x
    If (x <> NIL) Then x->parent = y
End Sub

Sub insertFixup(x As Node Ptr)

    '/*************************************
    ' *  maintain Red-Black tree balance  *
    ' *  after inserting node x           *
    ' *************************************/

    '/* check Red-Black properties */


    While x <> root AndAlso x->parent->Color = RED
        '/* we have a violation */

        If (x->parent = x->parent->parent->Left) Then
            Dim As Node Ptr y = x->parent->parent->Right
            If (y->Color = RED) Then

                '/* 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) Then
                    '/* make x a left child */
                    x = x->parent
                    rotateLeft(x)
                Endif

                '/* recolor and rotate */
                x->parent->Color = BLACK
                x->parent->parent->Color = RED
                rotateRight(x->parent->parent)
            Endif
        Else

            '/* mirror image of above code */
            Dim As Node Ptr y = x->parent->parent->Left
            If (y->Color = RED) Then

                '/* 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) Then
                    x = x->parent
                    rotateRight(x)
                Endif
                x->parent->Color = BLACK
                x->parent->parent->Color = RED
                rotateLeft(x->parent->parent)
            Endif
        Endif
    Wend

    root->Color = BLACK
End Sub

Function insertNode(data_ As T) As Node Ptr
    Dim As Node Ptr current, parent, x

    '/***********************************************
    ' *  allocate node for data and insert in tree  *
    ' ***********************************************/

    ' /* find where node belongs */
    current = root

    parent = 0

    While (current <> NIL)
        If data_ = current->Data  Then Return current
        parent = current
        current = Iif (data_ < current->Data , current->Left , current->Right)
    Wend

    '/* setup new node */
    x = malloc (Sizeof(Node))
    If x = 0 Then
        printf (!"insufficient memory (insertNode)\n")
        Sleep
        End
    Endif

    x->Data = data_
    x->parent = parent
    x->Left = NIL
    x->Right = NIL
    x->Color = RED

    '/* insert node in tree */
    If(parent) Then
        If data_ < parent->Data  Then
            parent->Left = x
        Else
            parent->Right = x
        Endif
    Else
        root = x
    Endif

    insertFixup(x)

    Return x
End Function

Sub deleteFixup( x As Node Ptr)

    '/*************************************
    ' *  maintain Red-Black tree balance  *
    ' *  after deleting node x            *
    ' *************************************/

    While x <> root AndAlso x->Color = BLACK
        If x = x->parent->Left Then
            Dim As Node Ptr w = x->parent->Right
            If (w->Color = RED) Then
                w->Color = BLACK
                x->parent->Color = RED
                rotateLeft (x->parent)
                w = x->parent->Right
            Endif
            If (w->Left->Color = BLACK AndAlso w->Right->Color = BLACK) Then
                w->Color = RED
                x = x->parent
            Else
                If (w->Right->Color = BLACK) Then
                    w->Left->Color = BLACK
                    w->Color = RED
                    rotateRight (w)
                    w = x->parent->Right
                Endif
                w->Color = x->parent->Color
                x->parent->Color = BLACK
                w->Right->Color = BLACK
                rotateLeft (x->parent)
                x = root
            Endif
        Else
            Dim As Node Ptr w = x->parent->Left
            If (w->Color = RED) Then
                w->Color = BLACK
                x->parent->Color = RED
                rotateRight (x->parent)
                w = x->parent->Left
            Endif
            If (w->Right->Color = BLACK Andalso w->Left->Color = BLACK) Then
                w->Color = RED
                x = x->parent
            Else
                If (w->Left->Color = BLACK) Then
                    w->Right->Color = BLACK
                    w->Color = RED
                    rotateLeft (w)
                    w = x->parent->Left
                Endif
                w->Color = x->parent->Color
                x->parent->Color = BLACK
                w->Left->Color = BLACK
                rotateRight (x->parent)
                x = root
            Endif
        Endif
    Wend
    x->Color = BLACK
End Sub

Sub deleteNode(z As Node Ptr)
    Dim As Node Ptr x, y

    '/*****************************
    ' *  delete node z from tree  *
    ' *****************************/

    If (z = 0 Or z = NIL) Then Exit Sub


    If (z->Left = NIL OrElse z->Right = NIL) Then
        '/* 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
        Wend
    Endif

    '/* x is y's only child */
    If (y->Left <> NIL) Then
        x = y->Left
    Else
        x = y->Right
    Endif

    '/* remove y from the parent chain */
    x->parent = y->parent
    If (y->parent) Then
        If (y = y->parent->Left) Then
            y->parent->Left = x
        Else
            y->parent->Right = x
        Endif
    Else
        root = x
    Endif

    If (y <> z) Then z->Data = y->Data


    If (y->Color = BLACK) Then deleteFixup (x)

    free (y)
End Sub

Function findNode(data_ As T) As Node Ptr

    '/*******************************
    ' *  find node containing data  *
    ' *******************************/

    Dim As Node Ptr current = root
    While(current <> NIL)
        If data_ = current->Data Then
            Return (current)
        Else
            current = Iif (data_ < current->Data , current->Left , current->Right)
        Endif
    Wend
    Return 0
End Function


Sub PrintTree(Tree As Node Ptr )
    '/*******************************
    ' *  Print all Tree                   *
    ' *******************************/

    If Tree <> NIL Then


        PrintTree(Tree->Left)
        Print Tree->Data,
        PrintTree(Tree->Right)


    Endif
End Sub

Sub DeleteTree(Tree As Node Ptr)
    '/*******************************
    ' *  Delete all Tree              *
    ' *******************************/
    If tree <> NIL Then
        DeleteTree(Tree->Left)
        DeleteTree(Tree->Right)
        free(Tree)
    Endif
End Sub

Dim As Integer a, maxnum, ct
Dim As  Node Ptr t_

maxnum = 100

For ct = 1 To maxnum
    a = ct
    t_ = findNode(a)

    If t_ <> NULL Then
        'deleteNode(t_)
    Else
        insertNode(a)
    Endif
Next

Var t = Timer
Dim As Node Ptr nP =  findNode(9)
? nP
If nP <> 0 Then ? nP->Data

? Timer -t

PrintTree(root)
DeleteTree(root)

Sleep