Qt 4.8
Classes | Public Functions | Public Variables | Private Functions | Properties | List of all members
QRBTree< T > Struct Template Reference

Classes

struct  Node
 

Public Functions

void attachAfter (Node *parent, Node *child)
 
void attachBefore (Node *parent, Node *child)
 
Nodeback (Node *node) const
 
void clear ()
 
void deleteNode (Node *&node)
 
Nodefront (Node *node) const
 
NodenewNode ()
 
Nodenext (Node *node) const
 
int order (Node *left, Node *right)
 
Nodeprevious (Node *node) const
 
 QRBTree ()
 
bool validate () const
 
 ~QRBTree ()
 

Public Variables

Noderoot
 

Private Functions

void attachLeft (Node *parent, Node *child)
 
void attachRight (Node *parent, Node *child)
 
int blackDepth (Node *top) const
 
bool checkRedBlackProperty (Node *top) const
 
void detach (Node *node)
 
void rebalance (Node *node)
 
void rotateLeft (Node *node)
 
void rotateRight (Node *node)
 
void swapNodes (Node *n1, Node *n2)
 
void update (Node *node)
 

Properties

NodefreeList
 

Detailed Description

template<class T>
struct QRBTree< T >

Definition at line 595 of file qtriangulator.cpp.

Constructors and Destructors

◆ QRBTree()

template<class T>
QRBTree< T >::QRBTree ( )
inline

Definition at line 608 of file qtriangulator.cpp.

608 : root(0), freeList(0) { }
Node * root
Node * freeList

◆ ~QRBTree()

template<class T >
QRBTree< T >::~QRBTree ( )
inline

Definition at line 653 of file qtriangulator.cpp.

654 {
655  clear();
656  while (freeList) {
657  // Avoid recursively calling the destructor, as this list may become large.
658  Node *next = freeList->right;
659  freeList->right = 0;
660  delete freeList;
661  freeList = next;
662  }
663 }
void clear()
Node * next(Node *node) const
Node * freeList

Functions

◆ attachAfter()

template<class T >
void QRBTree< T >::attachAfter ( Node parent,
Node child 
)

Definition at line 820 of file qtriangulator.cpp.

821 {
822  if (!root)
823  update(root = child);
824  else if (!parent)
825  attachLeft(front(root), child);
826  else if (parent->right)
827  attachLeft(front(parent->right), child);
828  else
829  attachRight(parent, child);
830 }
void attachLeft(Node *parent, Node *child)
Node * root
void attachRight(Node *parent, Node *child)
void update(Node *node)
Node * front(Node *node) const

◆ attachBefore()

template<class T >
void QRBTree< T >::attachBefore ( Node parent,
Node child 
)

Definition at line 807 of file qtriangulator.cpp.

808 {
809  if (!root)
810  update(root = child);
811  else if (!parent)
812  attachRight(back(root), child);
813  else if (parent->left)
814  attachRight(back(parent->left), child);
815  else
816  attachLeft(parent, child);
817 }
void attachLeft(Node *parent, Node *child)
Node * root
void attachRight(Node *parent, Node *child)
void update(Node *node)
Node * back(Node *node) const

◆ attachLeft()

template<class T >
void QRBTree< T >::attachLeft ( Node parent,
Node child 
)
inlineprivate

Definition at line 789 of file qtriangulator.cpp.

790 {
791  Q_ASSERT(!parent->left);
792  parent->left = child;
793  child->parent = parent;
794  update(child);
795 }
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
void update(Node *node)

◆ attachRight()

template<class T >
void QRBTree< T >::attachRight ( Node parent,
Node child 
)
inlineprivate

Definition at line 798 of file qtriangulator.cpp.

799 {
800  Q_ASSERT(!parent->right);
801  parent->right = child;
802  child->parent = parent;
803  update(child);
804 }
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
void update(Node *node)

◆ back()

template<class T >
QRBTree< T >::Node * QRBTree< T >::back ( Node node) const
inline

Definition at line 986 of file qtriangulator.cpp.

987 {
988  while (node->right)
989  node = node->right;
990  return node;
991 }

◆ blackDepth()

template<class T >
int QRBTree< T >::blackDepth ( Node top) const
private

Definition at line 1014 of file qtriangulator.cpp.

1015 {
1016  if (!top)
1017  return 0;
1018  int leftDepth = blackDepth(top->left);
1019  int rightDepth = blackDepth(top->right);
1020  if (leftDepth != rightDepth)
1021  return -1;
1022  if (!top->red)
1023  ++leftDepth;
1024  return leftDepth;
1025 }
int blackDepth(Node *top) const

◆ checkRedBlackProperty()

template<class T >
bool QRBTree< T >::checkRedBlackProperty ( Node top) const
private

Definition at line 1028 of file qtriangulator.cpp.

1029 {
1030  if (!top)
1031  return true;
1032  if (top->left && !checkRedBlackProperty(top->left))
1033  return false;
1034  if (top->right && !checkRedBlackProperty(top->right))
1035  return false;
1036  return !(top->red && ((top->left && top->left->red) || (top->right && top->right->red)));
1037 }
bool checkRedBlackProperty(Node *top) const

◆ clear()

template<class T >
void QRBTree< T >::clear ( )
inline

Definition at line 666 of file qtriangulator.cpp.

667 {
668  if (root)
669  delete root;
670  root = 0;
671 }
Node * root

◆ deleteNode()

template<class T >
void QRBTree< T >::deleteNode ( Node *&  node)
inline

Definition at line 1046 of file qtriangulator.cpp.

1047 {
1048  Q_ASSERT(node);
1049  detach(node);
1050  node->right = freeList;
1051  freeList = node;
1052  node = 0;
1053 }
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
void detach(Node *node)
Node * freeList

◆ detach()

template<class T >
void QRBTree< T >::detach ( Node node)
private

Definition at line 880 of file qtriangulator.cpp.

881 {
882  if (node->right)
883  swapNodes(node, front(node->right));
884 
885  Node *child = (node->left ? node->left : node->right);
886 
887  if (!node->red) {
888  if (child && child->red)
889  child->red = false;
890  else
891  rebalance(node);
892  }
893 
894  Node *&ref = (node->parent ? (node == node->parent->left ? node->parent->left : node->parent->right) : root);
895  ref = child;
896  if (child)
897  child->parent = node->parent;
898  node->left = node->right = node->parent = 0;
899 }
Node * root
void swapNodes(Node *n1, Node *n2)
Node * front(Node *node) const
void rebalance(Node *node)

◆ front()

template<class T >
QRBTree< T >::Node * QRBTree< T >::front ( Node node) const
inline

Definition at line 978 of file qtriangulator.cpp.

Referenced by QTriangulator< T >::ComplexToSimple::Event::operator<().

979 {
980  while (node->left)
981  node = node->left;
982  return node;
983 }

◆ newNode()

template<class T >
QRBTree< T >::Node * QRBTree< T >::newNode ( )
inline

Definition at line 1056 of file qtriangulator.cpp.

Referenced by QTriangulator< T >::ComplexToSimple::calculateIntersections(), QTriangulator< T >::SimpleToMonotone::monotoneDecomposition(), and QTriangulator< T >::ComplexToSimple::removeUnwantedEdgesAndConnect().

1057 {
1058  if (freeList) {
1059  Node *node = freeList;
1060  freeList = freeList->right;
1061  node->parent = node->left = node->right = 0;
1062  node->red = true;
1063  return node;
1064  }
1065  return new Node;
1066 }
Node * freeList

◆ next()

template<class T >
QRBTree< T >::Node * QRBTree< T >::next ( Node node) const

Definition at line 994 of file qtriangulator.cpp.

Referenced by QTriangulator< T >::ComplexToSimple::Event::operator<(), QTriangulator< T >::ComplexToSimple::removeUnwantedEdgesAndConnect(), QTriangulator< T >::ComplexToSimple::reorderEdgeListRange(), QTriangulator< T >::ComplexToSimple::searchEdgeLeftOf(), QTriangulator< T >::ComplexToSimple::sortEdgeList(), and QTriangulator< T >::ComplexToSimple::splitEdgeListRange().

995 {
996  if (node->right)
997  return front(node->right);
998  while (node->parent && node == node->parent->right)
999  node = node->parent;
1000  return node->parent;
1001 }
Node * front(Node *node) const

◆ order()

template<class T >
int QRBTree< T >::order ( Node left,
Node right 
)

Definition at line 1071 of file qtriangulator.cpp.

1072 {
1073  Q_ASSERT(left && right);
1074  if (left == right)
1075  return 0;
1076 
1077  QVector<Node *> leftAncestors;
1078  QVector<Node *> rightAncestors;
1079  while (left) {
1080  leftAncestors.push_back(left);
1081  left = left->parent;
1082  }
1083  while (right) {
1084  rightAncestors.push_back(right);
1085  right = right->parent;
1086  }
1087  Q_ASSERT(leftAncestors.back() == root && rightAncestors.back() == root);
1088 
1089  while (!leftAncestors.empty() && !rightAncestors.empty() && leftAncestors.back() == rightAncestors.back()) {
1090  leftAncestors.pop_back();
1091  rightAncestors.pop_back();
1092  }
1093 
1094  if (!leftAncestors.empty())
1095  return (leftAncestors.back() == leftAncestors.back()->parent->left ? -1 : 1);
1096 
1097  if (!rightAncestors.empty())
1098  return (rightAncestors.back() == rightAncestors.back()->parent->right ? -1 : 1);
1099 
1100  // The code should never reach this point.
1101  Q_ASSERT(!leftAncestors.empty() || !rightAncestors.empty());
1102  return 0;
1103 }
Node * root
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
The QVector class is a template class that provides a dynamic array.
Definition: qdatastream.h:64
bool empty() const
This function is provided for STL compatibility.
Definition: qvector.h:285
void pop_back()
This function is provided for STL compatibility.
Definition: qvector.h:283
reference back()
This function is provided for STL compatibility.
Definition: qvector.h:289
void push_back(const T &t)
This function is provided for STL compatibility.
Definition: qvector.h:281

◆ previous()

template<class T >
QRBTree< T >::Node * QRBTree< T >::previous ( Node node) const

Definition at line 1004 of file qtriangulator.cpp.

Referenced by QTriangulator< T >::ComplexToSimple::removeUnwantedEdgesAndConnect(), QTriangulator< T >::ComplexToSimple::reorderEdgeListRange(), and QTriangulator< T >::ComplexToSimple::sortEdgeList().

1005 {
1006  if (node->left)
1007  return back(node->left);
1008  while (node->parent && node == node->parent->left)
1009  node = node->parent;
1010  return node->parent;
1011 }
Node * back(Node *node) const

◆ rebalance()

template<class T >
void QRBTree< T >::rebalance ( Node node)
private

Definition at line 903 of file qtriangulator.cpp.

904 {
905  Q_ASSERT(!node->red);
906  for (;;) {
907  if (!node->parent)
908  return;
909 
910  // at this point, node is not a parent, it is black, thus it must have a sibling.
911  Node *sibling = (node == node->parent->left ? node->parent->right : node->parent->left);
912  Q_ASSERT(sibling);
913 
914  if (sibling->red) {
915  sibling->red = false;
916  node->parent->red = true;
917  if (node == node->parent->left)
918  rotateLeft(node->parent);
919  else
920  rotateRight(node->parent);
921  sibling = (node == node->parent->left ? node->parent->right : node->parent->left);
922  Q_ASSERT(sibling);
923  }
924 
925  // at this point, the sibling is black.
926  Q_ASSERT(!sibling->red);
927 
928  if ((!sibling->left || !sibling->left->red) && (!sibling->right || !sibling->right->red)) {
929  bool parentWasRed = node->parent->red;
930  sibling->red = true;
931  node->parent->red = false;
932  if (parentWasRed)
933  return;
934  node = node->parent;
935  continue;
936  }
937 
938  // at this point, at least one of the sibling's children is red.
939 
940  if (node == node->parent->left) {
941  if (!sibling->right || !sibling->right->red) {
942  Q_ASSERT(sibling->left);
943  sibling->red = true;
944  sibling->left->red = false;
945  rotateRight(sibling);
946 
947  sibling = sibling->parent;
948  Q_ASSERT(sibling);
949  }
950  sibling->red = node->parent->red;
951  node->parent->red = false;
952 
953  Q_ASSERT(sibling->right->red);
954  sibling->right->red = false;
955  rotateLeft(node->parent);
956  } else {
957  if (!sibling->left || !sibling->left->red) {
958  Q_ASSERT(sibling->right);
959  sibling->red = true;
960  sibling->right->red = false;
961  rotateLeft(sibling);
962 
963  sibling = sibling->parent;
964  Q_ASSERT(sibling);
965  }
966  sibling->red = node->parent->red;
967  node->parent->red = false;
968 
969  Q_ASSERT(sibling->left->red);
970  sibling->left->red = false;
971  rotateRight(node->parent);
972  }
973  return;
974  }
975 }
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
void rotateLeft(Node *node)
void rotateRight(Node *node)

◆ rotateLeft()

template<class T >
void QRBTree< T >::rotateLeft ( Node node)
private

Definition at line 674 of file qtriangulator.cpp.

675 {
676  // | | //
677  // N B //
678  // / \ / \ //
679  // A B ---> N D //
680  // / \ / \ //
681  // C D A C //
682 
683  Node *&ref = (node->parent ? (node == node->parent->left ? node->parent->left : node->parent->right) : root);
684  ref = node->right;
685  node->right->parent = node->parent;
686 
687  // : //
688  // N //
689  // / :| //
690  // A B //
691  // / \ //
692  // C D //
693 
694  node->right = ref->left;
695  if (ref->left)
696  ref->left->parent = node;
697 
698  // : | //
699  // N B //
700  // / \ : \ //
701  // A C D //
702 
703  ref->left = node;
704  node->parent = ref;
705 
706  // | //
707  // B //
708  // / \ //
709  // N D //
710  // / \ //
711  // A C //
712 }
Node * root

◆ rotateRight()

template<class T >
void QRBTree< T >::rotateRight ( Node node)
private

Definition at line 715 of file qtriangulator.cpp.

716 {
717  // | | //
718  // N A //
719  // / \ / \ //
720  // A B ---> C N //
721  // / \ / \ //
722  // C D D B //
723 
724  Node *&ref = (node->parent ? (node == node->parent->left ? node->parent->left : node->parent->right) : root);
725  ref = node->left;
726  node->left->parent = node->parent;
727 
728  node->left = ref->right;
729  if (ref->right)
730  ref->right->parent = node;
731 
732  ref->right = node;
733  node->parent = ref;
734 }
Node * root

◆ swapNodes()

template<class T >
void QRBTree< T >::swapNodes ( Node n1,
Node n2 
)
private

Definition at line 833 of file qtriangulator.cpp.

834 {
835  // Since iterators must not be invalidated, it is not sufficient to only swap the data.
836  if (n1->parent == n2) {
837  n1->parent = n2->parent;
838  n2->parent = n1;
839  } else if (n2->parent == n1) {
840  n2->parent = n1->parent;
841  n1->parent = n2;
842  } else {
843  qSwap(n1->parent, n2->parent);
844  }
845 
846  qSwap(n1->left, n2->left);
847  qSwap(n1->right, n2->right);
848  qSwap(n1->red, n2->red);
849 
850  if (n1->parent) {
851  if (n1->parent->left == n2)
852  n1->parent->left = n1;
853  else
854  n1->parent->right = n1;
855  } else {
856  root = n1;
857  }
858 
859  if (n2->parent) {
860  if (n2->parent->left == n1)
861  n2->parent->left = n2;
862  else
863  n2->parent->right = n2;
864  } else {
865  root = n2;
866  }
867 
868  if (n1->left)
869  n1->left->parent = n1;
870  if (n1->right)
871  n1->right->parent = n1;
872 
873  if (n2->left)
874  n2->left->parent = n2;
875  if (n2->right)
876  n2->right->parent = n2;
877 }
Node * root
void qSwap(T &value1, T &value2)
Definition: qglobal.h:2181

◆ update()

template<class T >
void QRBTree< T >::update ( Node node)
private

Definition at line 737 of file qtriangulator.cpp.

738 {
739  for (;;) {
740  Node *parent = node->parent;
741 
742  // if the node is the root, color it black
743  if (!parent) {
744  node->red = false;
745  return;
746  }
747 
748  // if the parent is black, the node can be left red
749  if (!parent->red)
750  return;
751 
752  // at this point, the parent is red and cannot be the root
753  Node *grandpa = parent->parent;
754  Q_ASSERT(grandpa);
755 
756  Node *uncle = (parent == grandpa->left ? grandpa->right : grandpa->left);
757  if (uncle && uncle->red) {
758  // grandpa's black, parent and uncle are red.
759  // let parent and uncle be black, grandpa red and recursively update grandpa.
760  Q_ASSERT(!grandpa->red);
761  parent->red = false;
762  uncle->red = false;
763  grandpa->red = true;
764  node = grandpa;
765  continue;
766  }
767 
768  // at this point, uncle is black
769  if (node == parent->right && parent == grandpa->left)
770  rotateLeft(node = parent);
771  else if (node == parent->left && parent == grandpa->right)
772  rotateRight(node = parent);
773  parent = node->parent;
774 
775  if (parent == grandpa->left) {
776  rotateRight(grandpa);
777  parent->red = false;
778  grandpa->red = true;
779  } else {
780  rotateLeft(grandpa);
781  parent->red = false;
782  grandpa->red = true;
783  }
784  return;
785  }
786 }
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
void rotateLeft(Node *node)
void rotateRight(Node *node)

◆ validate()

template<class T >
bool QRBTree< T >::validate ( ) const
inline

Definition at line 1040 of file qtriangulator.cpp.

1041 {
1042  return checkRedBlackProperty(root) && blackDepth(root) != -1;
1043 }
Node * root
int blackDepth(Node *top) const
bool checkRedBlackProperty(Node *top) const

Properties

◆ freeList

template<class T>
Node* QRBTree< T >::freeList
private

Definition at line 649 of file qtriangulator.cpp.

◆ root

template<class T>
Node* QRBTree< T >::root

The documentation for this struct was generated from the following file: