{
struct node *n = calloc(1, sizeof *n);
*n = (struct node) { value, 1, {nnil, nnil} };
return n;
}
int max(int a, int b) { return a > b ? a : b; }
inline void set_height(struct node *n) {
n->height = 1 + max(n->kid[0]->height, n->kid[1]->height);
}
inline int ballance(struct node *n) {
return n->kid[0]->height - n->kid[1]->height;
}
// rotate a subtree according to dir; if new root is nil, old root is freed
struct node * rotate(struct node **rootp, int dir)
{
struct node *old_r = *rootp, *new_r = old_r->kid[dir];
if (nnil == (*rootp = new_r))
free(old_r);
else {
old_r->kid[dir] = new_r->kid[!dir];
set_height(old_r);
new_r->kid[!dir] = old_r;
}
return new_r;
}
void adjust_balance(struct node **rootp)
{
struct node *root = *rootp;
int b = ballance(root)/2;
if (b) {
int dir = (1 - b)/2;
if (ballance(root->kid[dir]) == -b)
rotate(&root->kid[dir], !dir);
root = rotate(rootp, dir);
}
if (root != nnil) set_height(root);
}
// find the node that contains value as payload; or returns 0
struct node *query(struct node *root, int value)
{
return root == nnil
? 0
: root->payload == value
? root
: query(root->kid[value > root->payload], value);
}
void insert(struct node **rootp, int value)
{
struct node *root = *rootp;
if (root == nnil)
*rootp = new_node(value);
else if (value != root->payload) { // don't allow dup keys
insert(&root->kid[value > root->payload], value);
adjust_balance(rootp);
}
}
void delete(struct node **rootp, int value)
{
struct node *root = *rootp;
if (root == nnil) return; // not found
// if this is the node we want, rotate until off the tree
if (root->payload == value)
if (nnil == (root = rotate(rootp, ballance(root) < 0)))
return;
delete(&root->kid[value > root->payload], value);
adjust_balance(rootp);
}
// aux display and verification routines, helpful but not essential
struct trunk {
struct trunk *prev;
char * str;
};
void show_trunks(struct trunk *p)
{
if (!p) return;
show_trunks(p->prev);
printf("%s", p->str);
}
// this is very haphazzard
void show_tree(struct node *root, struct trunk *prev, int is_left)
{
if (root == nnil) return;
struct trunk this_disp = { prev, " " };
char *prev_str = this_disp.str;
show_tree(root->kid[0], &this_disp, 1);
if (!prev)
this_disp.str = "---";
else if (is_left) {
this_disp.str = ".--";
prev_str = " |";
} else {
this_disp.str = "`--";
prev->str = prev_str;
}
show_trunks(&this_disp);
printf("%d\n", root->payload);
if (prev) prev->str = prev_str;
this_disp.str = " |";
show_tree(root->kid[1], &this_disp, 0);
if (!prev) puts("");
}
int verify(struct node *p)
{
if (p == nnil) return 1;
int h0 = p->kid[0]->height, h1 = p->kid[1]->height;
int b = h0 - h1;
if (p->height != 1 + max(h0, h1) || b < -1 || b > 1) {
printf("node %d bad, balance %d\n", p->payload, b);
show_tree(p, 0, 0);
abort();
}
return verify(p->kid[0]) && verify(p->kid[1]);
}
#define MAX_VAL 32
int main(void)
{
int x;
struct node *root = nnil;
srand(time(0));
for (x = 0; x < 10 * MAX_VAL; x++) {
// random insertion and deletion
if (rand()&1) insert(&root, rand()%MAX_VAL);
else delete(&root, rand()%MAX_VAL);
verify(root);
}
puts("Tree is:");
show_tree(root, 0, 0);
puts("\nQuerying values:");
for (x = 0; x < MAX_VAL; x++) {
struct node *p = query(root, x);
if (p) printf("%2d found: %p %d\n", x, p, p->payload);
}
for (x = 0; x < MAX_VAL; x++) {
delete(&root, x);
verify(root);
}
puts("\nAfter deleting all values, tree is:");
show_tree(root, 0, 0);
return 0;
}
输出:
Tree is:
.--0
.--2
| `--4
| `--5
.--6
| | .--10
| `--12
| | .--13
| `--15
---17
| .--18
| .--19
| .--21
| | | .--24
| | `--25
`--26
`--27
`--30
Querying values:
0 found: 0x180a210 0
2 found: 0x180a1b0 2
4 found: 0x180a010 4
5 found: 0x180a0d0 5
6 found: 0x180a0f0 6
10 found: 0x180a190 10
12 found: 0x180a150 12
13 found: 0x180a250 13
15 found: 0x180a050 15
17 found: 0x180a270 17
18 found: 0x180a1d0 18
19 found: 0x180a170 19
21 found: 0x180a070 21
24 found: 0x180a030 24
25 found: 0x180a0b0 25
26 found: 0x180a130 26
27 found: 0x180a1f0 27
30 found: 0x180a110 30
After deleting all values, tree is:
#include
#include
/* AVL node */
template <class T>
class AVLnode {
public:
T key;
int balance;
AVLnode *left, *right, *parent;
AVLnode(T k, AVLnode *p) : key(k), balance(0), parent(p),
left(NULL), right(NULL) {}
~AVLnode() {
delete left;
delete right;
}
};
/* AVL tree */
template <class T>
class AVLtree {
public:
AVLtree(void);
~AVLtree(void);
bool insert(T key);
void deleteKey(const T key);
void printBalance();
private:
AVLnode<T> *root;
AVLnode<T>* rotateLeft ( AVLnode<T> *a );
AVLnode<T>* rotateRight ( AVLnode<T> *a );
AVLnode<T>* rotateLeftThenRight ( AVLnode<T> *n );
AVLnode<T>* rotateRightThenLeft ( AVLnode<T> *n );
void rebalance ( AVLnode<T> *n );
int height ( AVLnode<T> *n );
void setBalance ( AVLnode<T> *n );
void printBalance ( AVLnode<T> *n );
void clearNode ( AVLnode<T> *n );
};
/* AVL class definition */
template <class T>
void AVLtree<T>::rebalance(AVLnode<T> *n) {
setBalance(n);
if (n->balance == -2) {
if (height(n->left->left) >= height(n->left->right))
n = rotateRight(n);
else
n = rotateLeftThenRight(n);
}
else if (n->balance == 2) {
if (height(n->right->right) >= height(n->right->left))
n = rotateLeft(n);
else
n = rotateRightThenLeft(n);
}
if (n->parent != NULL) {
rebalance(n->parent);
}
else {
root = n;
}
}
template <class T>
AVLnode<T>* AVLtree<T>::rotateLeft(AVLnode<T> *a) {
AVLnode<T> *b = a->right;
b->parent = a->parent;
a->right = b->left;
if (a->right != NULL)
a->right->parent = a;
b->left = a;
a->parent = b;
if (b->parent != NULL) {
if (b->parent->right == a) {
b->parent->right = b;
}
else {
b->parent->left = b;
}
}
setBalance(a);
setBalance(b);
return b;
}
template <class T>
AVLnode<T>* AVLtree<T>::rotateRight(AVLnode<T> *a) {
AVLnode<T> *b = a->left;
b->parent = a->parent;
a->left = b->right;
if (a->left != NULL)
a->left->parent = a;
b->right = a;
a->parent = b;
if (b->parent != NULL) {
if (b->parent->right == a) {
b->parent->right = b;
}
else {
b->parent->left = b;
}
}
setBalance(a);
setBalance(b);
return b;
}
template <class T>
AVLnode<T>* AVLtree<T>::rotateLeftThenRight(AVLnode<T> *n) {
n->left = rotateLeft(n->left);
return rotateRight(n);
}
template <class T>
AVLnode<T>* AVLtree<T>::rotateRightThenLeft(AVLnode<T> *n) {
n->right = rotateRight(n->right);
return rotateLeft(n);
}
template <class T>
int AVLtree<T>::height(AVLnode<T> *n) {
if (n == NULL)
return -1;
return 1 + std::max(height(n->left), height(n->right));
}
template <class T>
void AVLtree<T>::setBalance(AVLnode<T> *n) {
n->balance = height(n->right) - height(n->left);
}
template <class T>
void AVLtree<T>::printBalance(AVLnode<T> *n) {
if (n != NULL) {
printBalance(n->left);
std::cout << n->balance << " ";
printBalance(n->right);
}
}
template <class T>
AVLtree<T>::AVLtree(void) : root(NULL) {}
template <class T>
AVLtree<T>::~AVLtree(void) {
delete root;
}
template <class T>
bool AVLtree<T>::insert(T key) {
if (root == NULL) {
root = new AVLnode<T>(key, NULL);
}
else {
AVLnode<T>
*n = root,
*parent;
while (true) {
if (n->key == key)
return false;
parent = n;
bool goLeft = n->key > key;
n = goLeft ? n->left : n->right;
if (n == NULL) {
if (goLeft) {
parent->left = new AVLnode<T>(key, parent);
}
else {
parent->right = new AVLnode<T>(key, parent);
}
rebalance(parent);
break;
}
}
}
return true;
}
template <class T>
void AVLtree<T>::deleteKey(const T delKey) {
if (root == NULL)
return;
AVLnode<T>
*n = root,
*parent = root,
*delNode = NULL,
*child = root;
while (child != NULL) {
parent = n;
n = child;
child = delKey >= n->key ? n->right : n->left;
if (delKey == n->key)
delNode = n;
}
if (delNode != NULL) {
delNode->key = n->key;
child = n->left != NULL ? n->left : n->right;
if (root->key == delKey) {
root = child;
}
else {
if (parent->left == n) {
parent->left = child;
}
else {
parent->right = child;
}
rebalance(parent);
}
}
}
template <class T>
void AVLtree<T>::printBalance() {
printBalance(root);
std::cout << std::endl;
}
int main(void)
{
AVLtree<int> t;
std::cout << "Inserting integer values 1 to 10" << std::endl;
for (int i = 1; i <= 10; ++i)
t.insert(i);
std::cout << "Printing balance: ";
t.printBalance();
}
输出:
Inserting integer values 1 to 10
Printing balance: 0 0 0 1 0 0 0 0 1 0
// Finite Ordered Sets - 4State - Balanced
using System;
using System.Collections.Generic;
public enum Direction { FromLeft, FromRight };
public enum State { Header, LeftHigh, Balanced, RightHigh };
public enum SetOperation
{
Union,
Intersection,
SymmetricDifference,
Difference,
Equality,
Inequality,
Subset,
Superset
}
public class Node
{
public Node Left;
public Node Right;
public Node Parent;
public State Balance;
public Node()
{
Left = this;
Right = this;
Parent = null;
Balance = State.Header;
}
public Node(Node p)
{
Left = null;
Right = null;
Parent = p;
Balance = State.Balanced;
}
public bool IsHeader
{ get { return Balance == State.Header; } }
}
public class SetNode<T> : Node
{
public T Data;
public SetNode() { }
public SetNode(T dataType, Node Parent) : base(Parent)
{
Data = dataType;
}
public override int GetHashCode()
{
return Data.GetHashCode();
}
}
class Utility // Nongeneric Tree Balancing
{
static void RotateLeft(ref Node Root)
{
Node Parent = Root.Parent;
Node x = Root.Right;
Root.Parent = x;
x.Parent = Parent;
if (x.Left != null) x.Left.Parent = Root;
Root.Right = x.Left;
x.Left = Root;
Root = x;
}
static void RotateRight(ref Node Root)
{
Node Parent = Root.Parent;
Node x = Root.Left;
Root.Parent = x;
x.Parent = Parent;
if (x.Right != null) x.Right.Parent = Root;
Root.Left = x.Right;
x.Right = Root;
Root = x;
}
static void BalanceLeft(ref Node Root)
{
Node Left = Root.Left;
switch (Left.Balance)
{
case State.LeftHigh:
Root.Balance = State.Balanced;
Left.Balance = State.Balanced;
RotateRight(ref Root);
break;
case State.RightHigh:
{
Node subRight = Left.Right;
switch (subRight.Balance)
{
case State.Balanced:
Root.Balance = State.Balanced;
Left.Balance = State.Balanced;
break;
case State.RightHigh:
Root.Balance = State.Balanced;
Left.Balance = State.LeftHigh;
break;
case State.LeftHigh:
Root.Balance = State.RightHigh;
Left.Balance = State.Balanced;
break;
}
subRight.Balance = State.Balanced;
RotateLeft(ref Left);
Root.Left = Left;
RotateRight(ref Root);
}
break;
case State.Balanced:
Root.Balance = State.LeftHigh;
Left.Balance = State.RightHigh;
RotateRight(ref Root);
break;
}
}
static void BalanceRight(ref Node Root)
{
Node Right = Root.Right;
switch (Right.Balance)
{
case State.RightHigh:
Root.Balance = State.Balanced;
Right.Balance = State.Balanced;
RotateLeft(ref Root);
break;
case State.LeftHigh:
{
Node subLeft = Right.Left; // Left Subtree of Right
switch (subLeft.Balance)
{
case State.Balanced:
Root.Balance = State.Balanced;
Right.Balance = State.Balanced;
break;
case State.LeftHigh:
Root.Balance = State.Balanced;
Right.Balance = State.RightHigh;
break;
case State.RightHigh:
Root.Balance = State.LeftHigh;
Right.Balance = State.Balanced;
break;
}
subLeft.Balance = State.Balanced;
RotateRight(ref Right);
Root.Right = Right;
RotateLeft(ref Root);
}
break;
case State.Balanced:
Root.Balance = State.RightHigh;
Right.Balance = State.LeftHigh;
RotateLeft(ref Root);
break;
}
}
public static void BalanceSet(Node Root, Direction From)
{
bool Taller = true;
while (Taller)
{
Node Parent = Root.Parent;
Direction NextFrom = (Parent.Left == Root) ? Direction.FromLeft : Direction.FromRight;
if (From == Direction.FromLeft)
{
switch (Root.Balance)
{
case State.LeftHigh:
if (Parent.IsHeader)
BalanceLeft(ref Parent.Parent);
else if (Parent.Left == Root)
BalanceLeft(ref Parent.Left);
else
BalanceLeft(ref Parent.Right);
Taller = false;
break;
case State.Balanced:
Root.Balance = State.LeftHigh;
Taller = true;
break;
case State.RightHigh:
Root.Balance = State.Balanced;
Taller = false;
break;
}
}
else
{
switch (Root.Balance)
{
case State.LeftHigh:
Root.Balance = State.Balanced;
Taller = false;
break;
case State.Balanced:
Root.Balance = State.RightHigh;
Taller = true;
break;
case State.RightHigh:
if (Parent.IsHeader)
BalanceRight(ref Parent.Parent);
else if (Parent.Left == Root)
BalanceRight(ref Parent.Left);
else
BalanceRight(ref Parent.Right);
Taller = false;
break;
}
}
if (Taller) // skip up a level
{
if (Parent.IsHeader)
Taller = false;
else
{
Root = Parent;
From = NextFrom;
}
}
}
}
public static void BalanceSetRemove(Node Root, Direction From)
{
if (Root.IsHeader) return;
bool Shorter = true;
while (Shorter)
{
Node Parent = Root.Parent;
Direction NextFrom = (Parent.Left == Root) ? Direction.FromLeft : Direction.FromRight;
if (From == Direction.FromLeft)
{
switch (Root.Balance)
{
case State.LeftHigh:
Root.Balance = State.Balanced;
Shorter = true;
break;
case State.Balanced:
Root.Balance = State.RightHigh;
Shorter = false;
break;
case State.RightHigh:
if (Root.Right.Balance == State.Balanced)
Shorter = false;
else
Shorter = true;
if (Parent.IsHeader)
BalanceRight(ref Parent.Parent);
else if (Parent.Left == Root)
BalanceRight(ref Parent.Left);
else
BalanceRight(ref Parent.Right);
break;
}
}
else
{
switch (Root.Balance)
{
case State.RightHigh:
Root.Balance = State.Balanced;
Shorter = true;
break;
case State.Balanced:
Root.Balance = State.LeftHigh;
Shorter = false;
break;
case State.LeftHigh:
if (Root.Left.Balance == State.Balanced)
Shorter = false;
else
Shorter = true;
if (Parent.IsHeader)
BalanceLeft(ref Parent.Parent);
else if (Parent.Left == Root)
BalanceLeft(ref Parent.Left);
else
BalanceLeft(ref Parent.Right);
break;
}
}
if (Shorter)
{
if (Parent.IsHeader)
Shorter = false;
else
{
From = NextFrom;
Root = Parent;
}
}
}
}
public static Node PreviousItem(Node Node)
{
if (Node.IsHeader) { return Node.Right; }
if (Node.Left != null)
{
Node = Node.Left;
while (Node.Right != null) Node = Node.Right;
}
else
{
Node y = Node.Parent;
if (y.IsHeader) return y;
while (Node == y.Left) { Node = y; y = y.Parent; }
Node = y;
}
return Node;
}
public static Node NextItem(Node Node)
{
if (Node.IsHeader) return Node.Left;
if (Node.Right != null)
{
Node = Node.Right;
while (Node.Left != null) Node = Node.Left;
}
else
{
Node y = Node.Parent;
if (y.IsHeader) return y;
while (Node == y.Right) { Node = y; y = y.Parent; }
Node = y;
}
return Node;
}
public static ulong Depth(Node Root)
{
if (Root != null)
{
ulong Left = Root.Left != null ? Depth(Root.Left) : 0;
ulong Right = Root.Right != null ? Depth(Root.Right) : 0;
return Left < Right ? Right + 1 : Left + 1;
}
else
return 0;
}
static void SwapNodeReference(ref Node First,
ref Node Second)
{ Node Temporary = First; First = Second; Second = Temporary; }
public static void SwapNodes(Node A, Node B)
{
if (B == A.Left)
{
if (B.Left != null) B.Left.Parent = A;
if (B.Right != null) B.Right.Parent = A;
if (A.Right != null) A.Right.Parent = B;
if (!A.Parent.IsHeader)
{
if (A.Parent.Left == A)
A.Parent.Left = B;
else
A.Parent.Right = B;
}
else A.Parent.Parent = B;
B.Parent = A.Parent;
A.Parent = B;
A.Left = B.Left;
B.Left = A;
SwapNodeReference(ref A.Right, ref B.Right);
}
else if (B == A.Right)
{
if (B.Right != null) B.Right.Parent = A;
if (B.Left != null) B.Left.Parent = A;
if (A.Left != null) A.Left.Parent = B;
if (!A.Parent.IsHeader)
{
if (A.Parent.Left == A)
A.Parent.Left = B;
else
A.Parent.Right = B;
}
else A.Parent.Parent = B;
B.Parent = A.Parent;
A.Parent = B;
A.Right = B.Right;
B.Right = A;
SwapNodeReference(ref A.Left, ref B.Left);
}
else if (A == B.Left)
{
if (A.Left != null) A.Left.Parent = B;
if (A.Right != null) A.Right.Parent = B;
if (B.Right != null) B.Right.Parent = A;
if (!B.Parent.IsHeader)
{
if (B.Parent.Left == B)
B.Parent.Left = A;
else
B.Parent.Right = A;
}
else B.Parent.Parent = A;
A.Parent = B.Parent;
B.Parent = A;
B.Left = A.Left;
A.Left = B;
SwapNodeReference(ref A.Right, ref B.Right);
}
else if (A == B.Right)
{
if (A.Right != null) A.Right.Parent = B;
if (A.Left != null) A.Left.Parent = B;
if (B.Left != null) B.Left.Parent = A;
if (!B.Parent.IsHeader)
{
if (B.Parent.Left == B)
B.Parent.Left = A;
else
B.Parent.Right = A;
}
else B.Parent.Parent = A;
A.Parent = B.Parent;
B.Parent = A;
B.Right = A.Right;
A.Right = B;
SwapNodeReference(ref A.Left, ref B.Left);
}
else
{
if (A.Parent == B.Parent)
SwapNodeReference(ref A.Parent.Left, ref A.Parent.Right);
else
{
if (!A.Parent.IsHeader)
{
if (A.Parent.Left == A)
A.Parent.Left = B;
else
A.Parent.Right = B;
}
else A.Parent.Parent = B;
if (!B.Parent.IsHeader)
{
if (B.Parent.Left == B)
B.Parent.Left = A;
else
B.Parent.Right = A;
}
else B.Parent.Parent = A;
}
if (B.Left != null) B.Left.Parent = A;
if (B.Right != null) B.Right.Parent = A;
if (A.Left != null) A.Left.Parent = B;
if (A.Right != null) A.Right.Parent = B;
SwapNodeReference(ref A.Left, ref B.Left);
SwapNodeReference(ref A.Right, ref B.Right);
SwapNodeReference(ref A.Parent, ref B.Parent);
}
State Balance = A.Balance;
A.Balance = B.Balance;
B.Balance = Balance;
}
}
public struct SetEntry<T> : IEnumerator<T>
{
public SetEntry(Node N) { _Node = N; }
public T Value
{
get
{
return ((SetNode<T>)_Node).Data;
}
}
public bool IsEnd { get { return _Node.IsHeader; } }
public bool MoveNext()
{
_Node = Utility.NextItem(_Node);
return _Node.IsHeader ? false : true;
}
public bool MovePrevious()
{
_Node = Utility.PreviousItem(_Node);
return _Node.IsHeader ? false : true;
}
public static SetEntry<T> operator ++(SetEntry<T> entry)
{
entry._Node = Utility.NextItem(entry._Node);
return entry;
}
public static SetEntry<T> operator --(SetEntry<T> entry)
{
entry._Node = Utility.PreviousItem(entry._Node);
return entry;
}
public void Reset()
{
while (!MoveNext()) ;
}
object System.Collections.IEnumerator.Current
{ get { return ((SetNode<T>)_Node).Data; } }
T IEnumerator<T>.Current
{ get { return ((SetNode<T>)_Node).Data; } }
public static bool operator ==(SetEntry<T> x, SetEntry<T> y) { return x._Node == y._Node; }
public static bool operator !=(SetEntry<T> x, SetEntry<T> y) { return x._Node != y._Node; }
public override bool Equals(object o) { return _Node == ((SetEntry<T>)o)._Node; }
public override int GetHashCode() { return _Node.GetHashCode(); }
public static SetEntry<T> operator +(SetEntry<T> C, ulong Increment)
{
SetEntry<T> Result = new SetEntry<T>(C._Node);
for (ulong i = 0; i < Increment; i++) ++Result;
return Result;
}
public static SetEntry<T> operator +(ulong Increment, SetEntry<T> C)
{
SetEntry<T> Result = new SetEntry<T>(C._Node);
for (ulong i = 0; i < Increment; i++) ++Result;
return Result;
}
public static SetEntry<T> operator -(SetEntry<T> C, ulong Decrement)
{
SetEntry<T> Result = new SetEntry<T>(C._Node);
for (ulong i = 0; i < Decrement; i++) --Result;
return Result;
}
public override string ToString()
{
return Value.ToString();
}
public void Dispose() { }
public Node _Node;
}
class Set<T> : IEnumerable<T>
{
IComparer<T> Comparer;
Node Header;
ulong Nodes;
//*** Constructors ***
public Set()
{
Comparer = Comparer<T>.Default;
Header = new Node();
Nodes = 0;
}
public Set(IComparer<T> c)
{
Comparer = c;
Header = new Node();
Nodes = 0;
}
//*** Properties ***
SetNode<T> Root
{
get { return (SetNode<T>)Header.Parent; }
set { Header.Parent = value; }
}
Node LeftMost
{
get { return Header.Left; }
set { Header.Left = value; }
}
Node RightMost
{
get { return Header.Right; }
set { Header.Right = value; }
}
public SetEntry<T> Begin
{ get { return new SetEntry<T>(Header.Left); } }
public SetEntry<T> End
{ get { return new SetEntry<T>(Header); } }
public ulong Length { get { return Nodes; } }
public ulong Depth { get { return Utility.Depth(Root); } }
//*** Operators ***
public bool this[T key] { get { return Search(key); } }
public static Set<T> operator +(Set<T> set, T t)
{
set.Add(t); return set;
}
public static Set<T> operator -(Set<T> set, T t)
{
set.Remove(t); return set;
}
public static Set<T> operator |(Set<T> A, Set<T> B)
{
Set<T> U = new Set<T>(A.Comparer);
CombineSets(A, B, U, SetOperation.Union);
return U;
}
public static Set<T> operator &(Set<T> A, Set<T> B)
{
Set<T> I = new Set<T>(A.Comparer);
CombineSets(A, B, I, SetOperation.Intersection);
return I;
}
public static Set<T> operator ^(Set<T> A, Set<T> B)
{
Set<T> S = new Set<T>(A.Comparer);
CombineSets(A, B, S, SetOperation.SymmetricDifference);
return S;
}
public static Set<T> operator -(Set<T> A, Set<T> B)
{
Set<T> S = new Set<T>(A.Comparer);
CombineSets(A, B, S, SetOperation.Difference);
return S;
}
public static bool operator ==(Set<T> A, Set<T> B)
{
return CheckSets(A, B, SetOperation.Equality);
}
public static bool operator !=(Set<T> A, Set<T> B)
{
return CheckSets(A, B, SetOperation.Inequality);
}
public override bool Equals(object o)
{
return CheckSets(this, (Set<T>)o, SetOperation.Equality);
}
//*** Methods ***
public void Add(T key)
{
if (Root == null)
{
Root = new SetNode<T>(key, Header);
LeftMost = RightMost = Root;
}
else
{
SetNode<T> Search = Root;
for (; ; )
{
int Compare = Comparer.Compare(key, Search.Data);
if (Compare == 0) // Item Exists
throw new EntryAlreadyExistsException();
else if (Compare < 0)
{
if (Search.Left != null)
Search = (SetNode<T>)Search.Left;
else
{
Search.Left = new SetNode<T>(key, Search);
if (LeftMost == Search) LeftMost = (SetNode<T>)Search.Left;
Utility.BalanceSet(Search, Direction.FromLeft);
Nodes++;
break;
}
}
else
{
if (Search.Right != null)
Search = (SetNode<T>)Search.Right;
else
{
Search.Right = new SetNode<T>(key, Search);
if (RightMost == Search) RightMost = (SetNode<T>)Search.Right;
Utility.BalanceSet(Search, Direction.FromRight);
Nodes++;
break;
}
}
}
}
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{ return new SetEntry<T>(Header); }
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{ return new SetEntry<T>(Header); }
public override int GetHashCode()
{
return GetHashCode((SetNode<T>)Header.Parent);
}
int GetHashCode(SetNode<T> Root)
{
if (Root != null)
{
int HashCode = Root.GetHashCode();
if (Root.Left != null)
HashCode += GetHashCode((SetNode<T>)Root.Left);
if (Root.Right != null)
HashCode += GetHashCode((SetNode<T>)Root.Right);
return HashCode;
}
return 0;
}
public void Remove(T key)
{
SetNode<T> root = Root;
for (; ; )
{
if (root == null)
throw new EntryNotFoundException();
int Compare = Comparer.Compare(key, root.Data);
if (Compare < 0)
root = (SetNode<T>)root.Left;
else if (Compare > 0)
root = (SetNode<T>)root.Right;
else // Item is found
{
if (root.Left != null && root.Right != null)
{
SetNode<T> replace = (SetNode<T>)root.Left;
while (replace.Right != null) replace = (SetNode<T>)replace.Right;
Utility.SwapNodes(root, replace);
}
SetNode<T> Parent = (SetNode<T>)root.Parent;
Direction From = (Parent.Left == root) ? Direction.FromLeft : Direction.FromRight;
if (LeftMost == root)
{
SetEntry<T> e = new SetEntry<T>(root); e.MoveNext();
if (e._Node.IsHeader)
{ LeftMost = Header; RightMost = Header; }
else
LeftMost = e._Node;
}
else if (RightMost == root)
{
SetEntry<T> e = new SetEntry<T>(root); e.MovePrevious();
if (e._Node.IsHeader)
{ LeftMost = Header; RightMost = Header; }
else
RightMost = e._Node;
}
if (root.Left == null)
{
if (Parent == Header)
Header.Parent = root.Right;
else if (Parent.Left == root)
Parent.Left = root.Right;
else
Parent.Right = root.Right;
if (root.Right != null) root.Right.Parent = Parent;
}
else
{
if (Parent == Header)
Header.Parent = root.Left;
else if (Parent.Left == root)
Parent.Left = root.Left;
else
Parent.Right = root.Left;
if (root.Left != null) root.Left.Parent = Parent;
}
Utility.BalanceSetRemove(Parent, From);
Nodes--;
break;
}
}
}
public bool Search(T key)
{
if (Root == null)
return false;
else
{
SetNode<T> Search = Root;
do
{
int Result = Comparer.Compare(key, Search.Data);
if (Result < 0) Search = (SetNode<T>)Search.Left;
else if (Result > 0) Search = (SetNode<T>)Search.Right;
else break;
} while (Search != null);
if (Search == null)
return false;
else
return true;
}
}
public override string ToString()
{
string StringOut = "{";
SetEntry<T> start = Begin;
SetEntry<T> end = End;
SetEntry<T> last = End - 1;
while (start != end)
{
string new_StringOut = start.Value.ToString();
if (start != last) new_StringOut = new_StringOut + ",";
StringOut = StringOut + new_StringOut;
++start;
}
StringOut = StringOut + "}";
return StringOut;
}
public void Validate()
{
if (Nodes == 0 || Root == null)
{
if (Nodes != 0) { throw new InvalidEmptyTreeException(); }
if (Root != null) { throw new InvalidEmptyTreeException(); }
if (LeftMost != Header) { throw new InvalidEndItemException(); }
if (RightMost != Header) { throw new InvalidEndItemException(); }
}
Validate(Root);
if (Root != null)
{
SetNode<T> x = Root;
while (x.Left != null) x = (SetNode<T>)x.Left;
if (LeftMost != x) throw new InvalidEndItemException();
SetNode<T> y = Root;
while (y.Right != null) y = (SetNode<T>)y.Right;
if (RightMost != y) throw new InvalidEndItemException();
}
}
void Validate(SetNode<T> root)
{
if (root == null) return;
if (root.Left != null)
{
SetNode<T> Left = (SetNode<T>)root.Left;
if (Comparer.Compare(Left.Data, root.Data) >= 0)
throw new OutOfKeyOrderException();
if (Left.Parent != root)
throw new TreeInvalidParentException();
Validate((SetNode<T>)root.Left);
}
if (root.Right != null)
{
SetNode<T> Right = (SetNode<T>)root.Right;
if (Comparer.Compare(Right.Data, root.Data) <= 0)
throw new OutOfKeyOrderException();
if (Right.Parent != root)
throw new TreeInvalidParentException();
Validate((SetNode<T>)root.Right);
}
ulong depth_Left = root.Left != null ? Utility.Depth(root.Left) : 0;
ulong depth_Right = root.Right != null ? Utility.Depth(root.Right) : 0;
if (depth_Left > depth_Right && depth_Left - depth_Right > 2)
throw new TreeOutOfBalanceException();
if (depth_Left < depth_Right && depth_Right - depth_Left > 2)
throw new TreeOutOfBalanceException();
}
public static void CombineSets(Set<T> A,
Set<T> B,
Set<T> R,
SetOperation operation)
{
IComparer<T> TComparer = R.Comparer;
SetEntry<T> First1 = A.Begin;
SetEntry<T> Last1 = A.End;
SetEntry<T> First2 = B.Begin;
SetEntry<T> Last2 = B.End;
switch (operation)
{
case SetOperation.Union:
while (First1 != Last1 && First2 != Last2)
{
int Order = TComparer.Compare(First1.Value, First2.Value);
if (Order < 0)
{
R.Add(First1.Value);
First1.MoveNext();
}
else if (Order > 0)
{
R.Add(First2.Value);
First2.MoveNext();
}
else
{
R.Add(First1.Value);
First1.MoveNext();
First2.MoveNext();
}
}
while (First1 != Last1)
{
R.Add(First1.Value);
First1.MoveNext();
}
while (First2 != Last2)
{
R.Add(First2.Value);
First2.MoveNext();
}
return;
case SetOperation.Intersection:
while (First1 != Last1 && First2 != Last2)
{
int Order = TComparer.Compare(First1.Value, First2.Value);
if (Order < 0)
First1.MoveNext();
else if (Order > 0)
First2.MoveNext();
else
{
R.Add(First1.Value);
First1.MoveNext();
First2.MoveNext();
}
}
return;
case SetOperation.SymmetricDifference:
while (First1 != Last1 && First2 != Last2)
{
int Order = TComparer.Compare(First1.Value, First2.Value);
if (Order < 0)
{
R.Add(First1.Value);
First1.MoveNext();
}
else if (Order > 0)
{
R.Add(First2.Value);
First2.MoveNext();
}
else
{ First1.MoveNext(); First2.MoveNext(); }
}
while (First1 != Last1)
{
R.Add(First1.Value);
First1.MoveNext();
}
while (First2 != Last2)
{
R.Add(First2.Value);
First2.MoveNext();
}
return;
case SetOperation.Difference:
while (First1 != Last1 && First2 != Last2)
{
int Order = TComparer.Compare(First1.Value, First2.Value);
if (Order < 0)
{
R.Add(First1.Value);
First1.MoveNext();
}
else if (Order > 0)
{
R.Add(First1.Value);
First1.MoveNext();
First2.MoveNext();
}
else
{ First1.MoveNext(); First2.MoveNext(); }
}
while (First1 != Last1)
{
R.Add(First1.Value);
First1.MoveNext();
}
return;
}
throw new InvalidSetOperationException();
}
public static bool CheckSets(Set<T> A,
Set<T> B,
SetOperation operation)
{
IComparer<T> TComparer = A.Comparer;
SetEntry<T> First1 = A.Begin;
SetEntry<T> Last1 = A.End;
SetEntry<T> First2 = B.Begin;
SetEntry<T> Last2 = B.End;
switch (operation)
{
case SetOperation.Equality:
case SetOperation.Inequality:
{
bool Equals = true;
while (First1 != Last1 && First2 != Last2)
{
if (TComparer.Compare(First1.Value, First2.Value) == 0)
{ First1.MoveNext(); First2.MoveNext(); }
else
{ Equals = false; break; }
}
if (Equals)
{
if (First1 != Last1) Equals = false;
if (First2 != Last2) Equals = false;
}
if (operation == SetOperation.Equality)
return Equals;
else
return !Equals;
}
case SetOperation.Subset:
case SetOperation.Superset:
{
bool Subset = true;
while (First1 != Last1 && First2 != Last2)
{
int Order = TComparer.Compare(First1.Value, First2.Value);
if (Order < 0)
{ Subset = false; break; }
else if (Order > 0)
First2.MoveNext();
else
{ First1.MoveNext(); First2.MoveNext(); }
}
if (Subset)
if (First1 != Last1) Subset = false;
if (operation == SetOperation.Subset)
return Subset;
else
return !Subset;
}
}
throw new InvalidSetOperationException();
}
}
public class EntryNotFoundException : Exception
{
static String message = "The requested entry could not be located in the specified collection.";
public EntryNotFoundException() : base(message) { }
}
public class EntryAlreadyExistsException : Exception
{
static String message = "The requested entry already resides in the collection.";
public EntryAlreadyExistsException() : base(message) { }
}
public class InvalidEndItemException : Exception
{
static String message = "The validation routines detected that the end item of a tree is invalid.";
public InvalidEndItemException() : base(message) { }
}
public class InvalidEmptyTreeException : Exception
{
static String message = "The validation routines detected that an empty tree is invalid.";
public InvalidEmptyTreeException() : base(message) { }
}
public class OutOfKeyOrderException : Exception
{
static String message = "A trees was found to be out of key order.";
public OutOfKeyOrderException() : base(message) { }
}
public class TreeInvalidParentException : Exception
{
static String message = "The validation routines detected that the Parent structure of a tree is invalid.";
public TreeInvalidParentException() : base(message) { }
}
public class TreeOutOfBalanceException : Exception
{
static String message = "The validation routines detected that the tree is out of State.";
public TreeOutOfBalanceException() : base(message) { }
}
public class InvalidSetOperationException : Exception
{
static String message = "An invalid set operation was requested.";
public InvalidSetOperationException() : base(message) { }
}
class Program
{
static void Main()
{
Set<string> s = new Set<string>() {"S0","S1","S2","S3","S4",
"S5","S6","S7","S8","S9"};
Console.WriteLine("Depth = {0}", s.Depth);
s.Validate();
for (int i = 0; i < 10; i += 2)
s.Remove("S" + i.ToString());
Console.WriteLine("Depth = {0}", s.Depth);
s.Validate();
Console.WriteLine("{0}", s);
Set<int> A = new Set<int>() { 1, 3, 5, 7 };
Set<int> B = new Set<int>() { 2, 4, 6, 8 };
Set<int> U = A | B;
Console.WriteLine("{0} | {1} == {2}", A, B, U);
}
}
package avl
// AVL tree adapted from Julienne Walker's presentation at
// http://eternallyconfuzzled.com/tuts/datastructures/jsw_tut_avl.aspx.
// This port uses similar indentifier names.
// The Key interface must be supported by data stored in the AVL tree.
type Key interface {
Less(Key) bool
Eq(Key) bool
}
// Node is a node in an AVL tree.
type Node struct {
Data Key // anything comparable with Less and Eq.
Balance int // balance factor
Link [2]*Node // children, indexed by "direction", 0 or 1.
}
// A little readability function for returning the opposite of a direction,
// where a direction is 0 or 1. Go inlines this.
// Where JW writes !dir, this code has opp(dir).
func opp(dir int) int {
return 1 - dir
}
// single rotation
func single(root *Node, dir int) *Node {
save := root.Link[opp(dir)]
root.Link[opp(dir)] = save.Link[dir]
save.Link[dir] = root
return save
}
// double rotation
func double(root *Node, dir int) *Node {
save := root.Link[opp(dir)].Link[dir]
root.Link[opp(dir)].Link[dir] = save.Link[opp(dir)]
save.Link[opp(dir)] = root.Link[opp(dir)]
root.Link[opp(dir)] = save
save = root.Link[opp(dir)]
root.Link[opp(dir)] = save.Link[dir]
save.Link[dir] = root
return save
}
// adjust valance factors after double rotation
func adjustBalance(root *Node, dir, bal int) {
n := root.Link[dir]
nn := n.Link[opp(dir)]
switch nn.Balance {
case 0:
root.Balance = 0
n.Balance = 0
case bal:
root.Balance = -bal
n.Balance = 0
default:
root.Balance = 0
n.Balance = bal
}
nn.Balance = 0
}
func insertBalance(root *Node, dir int) *Node {
n := root.Link[dir]
bal := 2*dir - 1
if n.Balance == bal {
root.Balance = 0
n.Balance = 0
return single(root, opp(dir))
}
adjustBalance(root, dir, bal)
return double(root, opp(dir))
}
func insertR(root *Node, data Key) (*Node, bool) {
if root == nil {
return &Node{Data: data}, false
}
dir := 0
if root.Data.Less(data) {
dir = 1
}
var done bool
root.Link[dir], done = insertR(root.Link[dir], data)
if done {
return root, true
}
root.Balance += 2*dir - 1
switch root.Balance {
case 0:
return root, true
case 1, -1:
return root, false
}
return insertBalance(root, dir), true
}
// Insert a node into the AVL tree.
// Data is inserted even if other data with the same key already exists.
func Insert(tree **Node, data Key) {
*tree, _ = insertR(*tree, data)
}
func removeBalance(root *Node, dir int) (*Node, bool) {
n := root.Link[opp(dir)]
bal := 2*dir - 1
switch n.Balance {
case -bal:
root.Balance = 0
n.Balance = 0
return single(root, dir), false
case bal:
adjustBalance(root, opp(dir), -bal)
return double(root, dir), false
}
root.Balance = -bal
n.Balance = bal
return single(root, dir), true
}
func removeR(root *Node, data Key) (*Node, bool) {
if root == nil {
return nil, false
}
if root.Data.Eq(data) {
switch {
case root.Link[0] == nil:
return root.Link[1], false
case root.Link[1] == nil:
return root.Link[0], false
}
heir := root.Link[0]
for heir.Link[1] != nil {
heir = heir.Link[1]
}
root.Data = heir.Data
data = heir.Data
}
dir := 0
if root.Data.Less(data) {
dir = 1
}
var done bool
root.Link[dir], done = removeR(root.Link[dir], data)
if done {
return root, true
}
root.Balance += 1 - 2*dir
switch root.Balance {
case 1, -1:
return root, true
case 0:
return root, false
}
return removeBalance(root, dir)
}
// Remove a single item from an AVL tree.
// If key does not exist, function has no effect.
func Remove(tree **Node, data Key) {
*tree, _ = removeR(*tree, data)
}
示例:
package main
import (
"encoding/json"
"fmt"
"log"
"avl"
)
type intKey int
// satisfy avl.Key
func (k intKey) Less(k2 avl.Key) bool { return k < k2.(intKey) }
func (k intKey) Eq(k2 avl.Key) bool { return k == k2.(intKey) }
// use json for cheap tree visualization
func dump(tree *avl.Node) {
b, err := json.MarshalIndent(tree, "", " ")
if err != nil {
log.Fatal(err)
}
fmt.Println(string(b))
}
func main() {
var tree *avl.Node
fmt.Println("Empty tree:")
dump(tree)
fmt.Println("\nInsert test:")
avl.Insert(&tree, intKey(3))
avl.Insert(&tree, intKey(1))
avl.Insert(&tree, intKey(4))
avl.Insert(&tree, intKey(1))
avl.Insert(&tree, intKey(5))
dump(tree)
fmt.Println("\nRemove test:")
avl.Remove(&tree, intKey(3))
avl.Remove(&tree, intKey(1))
dump(tree)
}
输出:
Empty tree:
null
Insert test:
{
"Data": 3,
"Balance": 0,
"Link": [
{
"Data": 1,
"Balance": -1,
"Link": [
{
"Data": 1,
"Balance": 0,
"Link": [
null,
null
]
},
null
]
},
{
"Data": 4,
"Balance": 1,
"Link": [
null,
{
"Data": 5,
"Balance": 0,
"Link": [
null,
null
]
}
]
}
]
}
Remove test:
{
"Data": 4,
"Balance": 0,
"Link": [
{
"Data": 1,
"Balance": 0,
"Link": [
null,
null
]
},
{
"Data": 5,
"Balance": 0,
"Link": [
null,
null
]
}
]
}
public class AVLtree {
private Node root;
private static class Node {
private int key;
private int balance;
private int height;
private Node left;
private Node right;
private Node parent;
Node(int key, Node parent) {
this.key = key;
this.parent = parent;
}
}
public boolean insert(int key) {
if (root == null) {
root = new Node(key, null);
return true;
}
Node n = root;
while (true) {
if (n.key == key)
return false;
Node parent = n;
boolean goLeft = n.key > key;
n = goLeft ? n.left : n.right;
if (n == null) {
if (goLeft) {
parent.left = new Node(key, parent);
} else {
parent.right = new Node(key, parent);
}
rebalance(parent);
break;
}
}
return true;
}
private void delete(Node node) {
if (node.left == null && node.right == null) {
if (node.parent == null) {
root = null;
} else {
Node parent = node.parent;
if (parent.left == node) {
parent.left = null;
} else {
parent.right = null;
}
rebalance(parent);
}
return;
}
if (node.left != null) {
Node child = node.left;
while (child.right != null) child = child.right;
node.key = child.key;
delete(child);
} else {
Node child = node.right;
while (child.left != null) child = child.left;
node.key = child.key;
delete(child);
}
}
public void delete(int delKey) {
if (root == null)
return;
Node child = root;
while (child != null) {
Node node = child;
child = delKey >= node.key ? node.right : node.left;
if (delKey == node.key) {
delete(node);
return;
}
}
}
private void rebalance(Node n) {
setBalance(n);
if (n.balance == -2) {
if (height(n.left.left) >= height(n.left.right))
n = rotateRight(n);
else
n = rotateLeftThenRight(n);
} else if (n.balance == 2) {
if (height(n.right.right) >= height(n.right.left))
n = rotateLeft(n);
else
n = rotateRightThenLeft(n);
}
if (n.parent != null) {
rebalance(n.parent);
} else {
root = n;
}
}
private Node rotateLeft(Node a) {
Node b = a.right;
b.parent = a.parent;
a.right = b.left;
if (a.right != null)
a.right.parent = a;
b.left = a;
a.parent = b;
if (b.parent != null) {
if (b.parent.right == a) {
b.parent.right = b;
} else {
b.parent.left = b;
}
}
setBalance(a, b);
return b;
}
private Node rotateRight(Node a) {
Node b = a.left;
b.parent = a.parent;
a.left = b.right;
if (a.left != null)
a.left.parent = a;
b.right = a;
a.parent = b;
if (b.parent != null) {
if (b.parent.right == a) {
b.parent.right = b;
} else {
b.parent.left = b;
}
}
setBalance(a, b);
return b;
}
private Node rotateLeftThenRight(Node n) {
n.left = rotateLeft(n.left);
return rotateRight(n);
}
private Node rotateRightThenLeft(Node n) {
n.right = rotateRight(n.right);
return rotateLeft(n);
}
private int height(Node n) {
if (n == null)
return -1;
return n.height;
}
private void setBalance(Node... nodes) {
for (Node n : nodes) {
reheight(n);
n.balance = height(n.right) - height(n.left);
}
}
public void printBalance() {
printBalance(root);
}
private void printBalance(Node n) {
if (n != null) {
printBalance(n.left);
System.out.printf("%s ", n.balance);
printBalance(n.right);
}
}
private void reheight(Node node) {
if (node != null) {
node.height = 1 + Math.max(height(node.left), height(node.right));
}
}
public static void main(String[] args) {
AVLtree tree = new AVLtree();
System.out.println("Inserting values 1 to 10");
for (int i = 1; i < 10; i++)
tree.insert(i);
System.out.print("Printing balance: ");
tree.printBalance();
}
}
class AvlTree {
private var root: Node? = null
private class Node(var key: Int, var parent: Node?) {
var balance: Int = 0
var left : Node? = null
var right: Node? = null
}
fun insert(key: Int): Boolean {
if (root == null)
root = Node(key, null)
else {
var n: Node? = root
var parent: Node
while (true) {
if (n!!.key == key) return false
parent = n
val goLeft = n.key > key
n = if (goLeft) n.left else n.right
if (n == null) {
if (goLeft)
parent.left = Node(key, parent)
else
parent.right = Node(key, parent)
rebalance(parent)
break
}
}
}
return true
}
fun delete(delKey: Int) {
if (root == null) return
var n: Node? = root
var parent: Node? = root
var delNode: Node? = null
var child: Node? = root
while (child != null) {
parent = n
n = child
child = if (delKey >= n.key) n.right else n.left
if (delKey == n.key) delNode = n
}
if (delNode != null) {
delNode.key = n!!.key
child = if (n.left != null) n.left else n.right
if (0 == root!!.key.compareTo(delKey)) {
root = child
if (null != root) {
root!!.parent = null
}
} else {
if (parent!!.left == n)
parent.left = child
else
parent.right = child
if (null != child) {
child.parent = parent
}
rebalance(parent)
}
}
private fun rebalance(n: Node) {
setBalance(n)
var nn = n
if (nn.balance == -2)
if (height(nn.left!!.left) >= height(nn.left!!.right))
nn = rotateRight(nn)
else
nn = rotateLeftThenRight(nn)
else if (nn.balance == 2)
if (height(nn.right!!.right) >= height(nn.right!!.left))
nn = rotateLeft(nn)
else
nn = rotateRightThenLeft(nn)
if (nn.parent != null) rebalance(nn.parent!!)
else root = nn
}
private fun rotateLeft(a: Node): Node {
val b: Node? = a.right
b!!.parent = a.parent
a.right = b.left
if (a.right != null) a.right!!.parent = a
b.left = a
a.parent = b
if (b.parent != null) {
if (b.parent!!.right == a)
b.parent!!.right = b
else
b.parent!!.left = b
}
setBalance(a, b)
return b
}
private fun rotateRight(a: Node): Node {
val b: Node? = a.left
b!!.parent = a.parent
a.left = b.right
if (a.left != null) a.left!!.parent = a
b.right = a
a.parent = b
if (b.parent != null) {
if (b.parent!!.right == a)
b.parent!!.right = b
else
b.parent!!.left = b
}
setBalance(a, b)
return b
}
private fun rotateLeftThenRight(n: Node): Node {
n.left = rotateLeft(n.left!!)
return rotateRight(n)
}
private fun rotateRightThenLeft(n: Node): Node {
n.right = rotateRight(n.right!!)
return rotateLeft(n)
}
private fun height(n: Node?): Int {
if (n == null) return -1
return 1 + Math.max(height(n.left), height(n.right))
}
private fun setBalance(vararg nodes: Node) {
for (n in nodes) n.balance = height(n.right) - height(n.left)
}
fun printKey() {
printKey(root)
println()
}
private fun printKey(n: Node?) {
if (n != null) {
printKey(n.left)
print("${n.key} ")
printKey(n.right)
}
}
fun printBalance() {
printBalance(root)
println()
}
private fun printBalance(n: Node?) {
if (n != null) {
printBalance(n.left)
print("${n.balance} ")
printBalance(n.right)
}
}
}
fun main(args: Array<String>) {
val tree = AvlTree()
println("Inserting values 1 to 10")
for (i in 1..10) tree.insert(i)
print("Printing key : ")
tree.printKey()
print("Printing balance : ")
tree.printBalance()
}
输出:
Inserting values 1 to 10
Printing key : 1 2 3 4 5 6 7 8 9 10
Printing balance : 0 0 0 1 0 0 0 0 1 0
class AVLNode(object):
"""A node in the AVL tree."""
def __init__(self, parent, k):
"""Creates a node.
Args:
parent: The node's parent.
k: key of the node.
"""
self.key = k
self.parent = parent
self.left = None
self.right = None
def _str(self):
"""Internal method for ASCII art."""
label = str(self.key)
if self.left is None:
left_lines, left_pos, left_width = [], 0, 0
else:
left_lines, left_pos, left_width = self.left._str()
if self.right is None:
right_lines, right_pos, right_width = [], 0, 0
else:
right_lines, right_pos, right_width = self.right._str()
middle = max(right_pos + left_width - left_pos + 1, len(label), 2)
pos = left_pos + middle // 2
width = left_pos + middle + right_width - right_pos
while len(left_lines) < len(right_lines):
left_lines.append(' ' * left_width)
while len(right_lines) < len(left_lines):
right_lines.append(' ' * right_width)
if (middle - len(label)) % 2 == 1 and self.parent is not None and \
self is self.parent.left and len(label) < middle:
label += '.'
label = label.center(middle, '.')
if label[0] == '.': label = ' ' + label[1:]
if label[-1] == '.': label = label[:-1] + ' '
lines = [' ' * left_pos + label + ' ' * (right_width - right_pos),
' ' * left_pos + '/' + ' ' * (middle-2) +
'\\' + ' ' * (right_width - right_pos)] + \
[left_line + ' ' * (width - left_width - right_width) + right_line
for left_line, right_line in zip(left_lines, right_lines)]
return lines, pos, width
def __str__(self):
return '\n'.join(self._str()[0])
def find(self, k):
"""Finds and returns the node with key k from the subtree rooted at this
node.
Args:
k: The key of the node we want to find.
Returns:
The node with key k.
"""
if k == self.key:
return self
elif k < self.key:
if self.left is None:
return None
else:
return self.left.find(k)
else:
if self.right is None:
return None
else:
return self.right.find(k)
def find_min(self):
"""Finds the node with the minimum key in the subtree rooted at this
node.
Returns:
The node with the minimum key.
"""
current = self
while current.left is not None:
current = current.left
return current
def next_larger(self):
"""Returns the node with the next larger key (the successor) in the BST.
"""
if self.right is not None:
return self.right.find_min()
current = self
while current.parent is not None and current is current.parent.right:
current = current.parent
return current.parent
def insert(self, node):
"""Inserts a node into the subtree rooted at this node.
Args:
node: The node to be inserted.
"""
if node is None:
return
if node.key < self.key:
if self.left is None:
node.parent = self
self.left = node
else:
self.left.insert(node)
else:
if self.right is None:
node.parent = self
self.right = node
else:
self.right.insert(node)
def delete(self):
"""Deletes and returns this node from the tree."""
if self.left is None or self.right is None:
if self is self.parent.left:
self.parent.left = self.left or self.right
if self.parent.left is not None:
self.parent.left.parent = self.parent
else:
self.parent.right = self.left or self.right
if self.parent.right is not None:
self.parent.right.parent = self.parent
return self
else:
s = self.next_larger()
self.key, s.key = s.key, self.key
return s.delete()
def height(node):
if node is None:
return -1
else:
return node.height
def update_height(node):
node.height = max(height(node.left), height(node.right)) + 1
class AVL(object):
"""
AVL binary search tree implementation.
"""
def __init__(self):
""" empty tree """
self.root = None
def __str__(self):
if self.root is None: return ''
return str(self.root)
def find(self, k):
"""Finds and returns the node with key k from the subtree rooted at this
node.
Args:
k: The key of the node we want to find.
Returns:
The node with key k or None if the tree is empty.
"""
return self.root and self.root.find(k)
def find_min(self):
"""Returns the minimum node of this BST."""
return self.root and self.root.find_min()
def next_larger(self, k):
"""Returns the node that contains the next larger (the successor) key in
the BST in relation to the node with key k.
Args:
k: The key of the node of which the successor is to be found.
Returns:
The successor node.
"""
node = self.find(k)
return node and node.next_larger()
def left_rotate(self, x):
y = x.right
y.parent = x.parent
if y.parent is None:
self.root = y
else:
if y.parent.left is x:
y.parent.left = y
elif y.parent.right is x:
y.parent.right = y
x.right = y.left
if x.right is not None:
x.right.parent = x
y.left = x
x.parent = y
update_height(x)
update_height(y)
def right_rotate(self, x):
y = x.left
y.parent = x.parent
if y.parent is None:
self.root = y
else:
if y.parent.left is x:
y.parent.left = y
elif y.parent.right is x:
y.parent.right = y
x.left = y.right
if x.left is not None:
x.left.parent = x
y.right = x
x.parent = y
update_height(x)
update_height(y)
def rebalance(self, node):
while node is not None:
update_height(node)
if height(node.left) >= 2 + height(node.right):
if height(node.left.left) >= height(node.left.right):
self.right_rotate(node)
else:
self.left_rotate(node.left)
self.right_rotate(node)
elif height(node.right) >= 2 + height(node.left):
if height(node.right.right) >= height(node.right.left):
self.left_rotate(node)
else:
self.right_rotate(node.right)
self.left_rotate(node)
node = node.parent
def insert(self, k):
"""Inserts a node with key k into the subtree rooted at this node.
This AVL version guarantees the balance property: h = O(lg n).
Args:
k: The key of the node to be inserted.
"""
node = AVLNode(None, k)
if self.root is None:
# The root's parent is None.
self.root = node
else:
self.root.insert(node)
self.rebalance(node)
def delete(self, k):
"""Deletes and returns a node with key k if it exists from the BST.
This AVL version guarantees the balance property: h = O(lg n).
Args:
k: The key of the node that we want to delete.
Returns:
The deleted node with key k.
"""
node = self.find(k)
if node is None:
return None
if node is self.root:
pseudoroot = AVLNode(None, 0)
pseudoroot.left = self.root
self.root.parent = pseudoroot
deleted = self.root.delete()
self.root = pseudoroot.left
if self.root is not None:
self.root.parent = None
else:
deleted = node.delete()
## node.parent is actually the old parent of the node,
## which is the first potentially out-of-balance node.
self.rebalance(deleted.parent)
def test(args=None):
import random, sys
if not args:
args = sys.argv[1:]
if not args:
print('usage: %s ' % \
sys.argv[0])
sys.exit()
elif len(args) == 1:
items = (random.randrange(100) for i in range(int(args[0])))
else:
items = [int(i) for i in args]
tree = AVL()
print(tree)
for item in items:
tree.insert(item)
print()
print(tree)
if __name__ == '__main__': test()
输出:
python avlrc.py 1 2 3 4 5 6 7 8 9 10
... only showing last tree ...
..4...
/ \
2 .8.
/ \ / \
1 3 6 9
/\ /\ / \ /\
5 7 10
/\ /\ /\