关于C++类库KYLib: 平衡二叉树类(AVL tree)

    在KYLib 2.0.9.0(build 2009.10.21) 中增加了TKYAVLTree类, 使用与TKYList相似, 但又有很大区别。在搜索方面TKYList使用二分查找,项比较事件为 OnCompare,而在TKYAVLTree中使用二叉树查找,结点项比较事件为OnCompare;二者搜索性能相差不大,但在增/删操作的性能却相差很大,若项数低于10,TKYList性能略好,否则项数越多TKYAVLTree性能就远远高于TKYList。TKYList的优势在于可以直接根据索引快速读取项,而TKYAVLTree使用索引需要前后循环查找,也就是说,TKYList的随机读取比TKYAVLTree方便和快速。

 

TKYAVLTree和TKYList的类声明:

/* TKYAVLTree – 平衡二叉树类 */ class TKYAVLTree { public: // 树结点 typedef struct { void* Item; // 项数据 void* Data; // 自定义数据 } TNode, *PNode; // TOnCopy 结点拷贝事件 typedef void (TObject::*TDoCopy)(TNode* ADest, const TNode* ASource); typedef struct { TDoCopy Method; void* Object; } TOnCopy; // TOnCompare 结点比较事件 // 若 ANode1 等于 ANode2 则 ACompare == 0 // 若 ANode1 大于 ANode2 则 ACompare > 0 // 若 ANode1 小于 ANode2 则 ACompare < 0 typedef void (TObject::*TDoCompare)(const TNode* ANode1, const TNode* ANode2, long& ACompare); typedef struct { TDoCompare Method; void* Object; } TOnCompare; // TOnDeletion 结点删除事件 typedef void (TObject::*TDoDeletion)(void* Sender, TNode* ANode); typedef struct { TDoDeletion Method; void* Object; } TOnDeletion; protected: // 树结点项 #pragma pack(push, 1) typedef struct TNodeItem { TNode Node; // 结点 TNodeItem* Parent; // 父结点项 TNodeItem* Left; // 左子结点项 TNodeItem* Right; // 右子结点项 TNodeItem* Prior; // 前一结点项 TNodeItem* Next; // 下一结点项 char Balance; // 平衡标志: Height(Left) – Height(Right) bool Deleting; // 正在删除 } *PNodeItem; #pragma pack(pop) // 拷贝项 typedef struct { TNodeItem* Dest; // 目标结点项 TNodeItem* Source; // 源结点项 } TCopyItem, *PCopyItem; public: TKYAVLTree(bool ACanLock = false, bool AIsHuge = false); virtual ~TKYAVLTree(); // 重载操作符 TKYAVLTree& operator=(const TKYAVLTree& ATree) { Assign(ATree); return *this; } TNode* operator[](long AIndex) const { return Node(AIndex); } // 属性 void* Data() const { return FData; } // default: NULL long Count() const { return FCount; } // default: 0 long MaxCount() const { return FMaxCount; } // default: 0 bool CanDuplicate() const { return FCanDuplicate; } // default: false TNode* Root() const { return (TNode*)FRoot; } // default: NULL TNode* Node(long AIndex) const; // 设置属性 void SetData(void* AData) { FData = AData; } void SetMaxCount(long AMaxCount); void SetCanDuplicate(bool ACanDuplicate); // 方法 void Assign(const TKYAVLTree& ATree); void Clear(); TNode* Add(void* AItem, void* AData = NULL); TNode* Search(const void* AItem, const void* AData = NULL) const; bool Delete(const void* AItem, const void* AData = NULL); bool Remove(TNode* ANode); bool Existed(TNode* ANode) const; bool Existed(const void* AItem, const void* AData = NULL) const { return (Search(AItem, AData) != NULL); } // 查找最近一个结点 // 若 ANearest == NULL 则表示项值大于树中的最后一个结点值; // 若返回值为 true, 则表示找到项值的结点, 否则项值在 ANearest 结点之前 bool FindNearest(const void* AItem, const void* AData, PNode& ANearest) const; // 结点的属性 long Level(TNode* ANode) const; // 结点所在的层号, Level(NULL) = -1 long Height(TNode* ANode) const; // 结点的子树高度, Height(NULL) = 0 char Balance(TNode* ANode) const; // 结点的子树平衡标志 // 取左右子结点及父结点 TNode* Left(TNode* ANode) const; TNode* Right(TNode* ANode) const; TNode* Parent(TNode* ANode) const; // 取前后结点(若ANode == NULL, 则 Next 取首结点, Prior 取尾结点) TNode* Prior(TNode* ANode) const; TNode* Next(TNode* ANode) const; // 取当前结点的前后结点 TNode* First(); TNode* Prior(); TNode* Next(); TNode* Last(); // 事件 TOnCopy OnCopy; // 结点拷贝事件, 用于 Assign 方法 TOnCompare OnCompare; // 结点比较事件 TOnDeletion OnDeletion; // 结点删除事件 protected: // FCurr 锁 void LockCurr() const { if (FLock != NULL) { FLock->Enter(); FLockRW->LockRead(); }} void UnlockCurr() const { if (FLock != NULL) { FLockRW->UnlockRead(); FLock->Leave(); }} // 读锁 void LockRead() const { if (FLockRW != NULL) FLockRW->LockRead(); } void UnlockRead() const { if (FLockRW != NULL) FLockRW->UnlockRead(); } // 写锁 void LockWrite() const { if (FLockRW != NULL) FLockRW->LockWrite(); } void UnlockWrite() const { if (FLockRW != NULL) FLockRW->UnlockWrite(); } // 结点层号/高度/是否存在 long DoLevel(TNodeItem* ANode) const; long DoHeight(TNodeItem* ANode) const; bool DoExisted(TNodeItem* ANode) const; // 查找(若 ANearest 返回为 NULL, 则表示此结点大于所有结点值, 添加时要加入末尾) long Compare(const TNode* ANode1, const TNode* ANode2) const; bool FindNode(const TNode* ANode, PNodeItem& ANearest) const; // 拷贝树, 返回拷贝结点个数 long CopyTree(const TKYAVLTree& ATree, PNodeItem& ARoot, PNodeItem& AHead, PNodeItem& ATail, PNodeItem& ACurr); long CopyNodes(TNodeItem* ADest, const TNodeItem* ASource); // 插入/删除结点 TNodeItem* InsertNode(const TNode* ANode, TNodeItem* ATo); void DeleteNode(TNodeItem* ANode); // 清除结点的相关方法 void ClearNodes(TNodeItem* AHead); void SetAllDeleting(TNodeItem* AHead); private: // OnDeletion != NULL inline void DoDeletion(TNode* ANode); // OnCompare.Method != NULL inline long DoCompare(const TNode* ANode1, const TNode* ANode2) const; bool DoFindNode(const TNode* ANode, PNodeItem& ANearest) const; // 新增结点并修改链接 void DoAdd(TNodeItem* ANode, TNodeItem* ATo); void DoInsert(TNodeItem* ANode, TNodeItem* ATo); TNodeItem* DoNewNode(const TNode* ANode, PNodeItem& ATo, bool& AIsAdd, bool& AIsBreak); // 减/增平衡值 void DecBalance(bool AIsRight, TNodeItem* AParent); void IncBalance(bool AIsRight, TNodeItem* AParent, TNodeItem* ATo, TNodeItem* ANode); // 调整结点并返回调整后的子树根结点 TNodeItem* Adjust(bool AIsRight1, bool AIsRight2,TNodeItem* AParent, TNodeItem* ATo, TNodeItem* ANode) { return (this->*_DoAdjust[AIsRight1][AIsRight2]) (AParent, ATo, ANode); } // 调整结点并返回调整后的子树根结点 TNodeItem* AdjustLL(TNodeItem* AParent, TNodeItem* ATo, TNodeItem* ANode); TNodeItem* AdjustLR(TNodeItem* AParent, TNodeItem* ATo, TNodeItem* ANode); TNodeItem* AdjustRL(TNodeItem* AParent, TNodeItem* ATo, TNodeItem* ANode); TNodeItem* AdjustRR(TNodeItem* AParent, TNodeItem* ATo, TNodeItem* ANode); private: void* FData; // 自定义数据 TKYCritSect* FLock; // 锁当前结点 TKYLockRW* FLockRW; // 读写锁 TKYMemBlock* FNodes; // 结点集 TNodeItem* FRoot; // 根结点 TNodeItem* FHead; // 首结点 TNodeItem* FTail; // 尾结点 TNodeItem* FCurr; // 当前结点 long FCount; // 结点个数 long FMaxCount; // 结点最大个数, 默认值为 0 表示无限制 bool FCanDuplicate; // 是否允许重复, 默认值为 false private: // 调整结点的方法 typedef TNodeItem* (TKYAVLTree::*TDoAdjust)(TNodeItem* AParent, TNodeItem* ATo, TNodeItem* ANode); // 调整结点方法列表 static const TDoAdjust _DoAdjust[2][2]; // 左右结点调整的平衡增量 static const char _Delta_Balance[2]; static const char _Bool_Delta[2]; }; /* TKYList – 列表类 {建议不要继承, 若要继承请使用 TKYCustomList} */ class TKYList { public: // TOnCompare 项比较事件 // 若 AItem1 等于 AItem2 则 ACompare == 0 // 若 AItem1 大于 AItem2 则 ACompare > 0 // 若 AItem1 小于 AItem2 则 ACompare < 0 typedef void (TObject::*TDoCompare)(const void* AItem1, const void* AItem2, int& ACompare); typedef struct { TDoCompare Method; void* Object; } TOnCompare; // TOnDeletion 项删除事件 typedef void (TObject::*TDoDeletion)(void* AItem); typedef struct { TDoDeletion Method; void* Object; } TOnDeletion; public: TKYList(bool ACanLock = false); TKYList(const TKYList& AList); virtual ~TKYList(); TKYList& operator=(const TKYList& AList); void* operator[](long AIndex) const { return Item(AIndex); } void* Item(long AIndex) const; long Capacity() const { return FCapacity; } long Count() const { return FCount; } long Delta() const { return FDelta; } bool Sorted() const { return FSorted; } bool CanDuplicate() const { return FCanDuplicate; } bool SetItem(long AIndex, void* AItem); void SetDelta(long ADelta); void SetSorted(bool ASorted); void SetCanDuplicate(bool ACanDuplicate); void Assign(const TKYList& AList); void ChangeCapacity(long ACapacity); long Add(void* AItem); bool Insert(long AIndex, void* AItem); void Delete(long AIndex); // 删除指定索引项 void Delete(void* AItem); // 删除<满足条件>的第一项 long Remove(void* AItem); // 删除<项指针相同>的第一项, 并返回删除前的索引 void Clear(); void Sort(); bool MoveTo(long AIndex, long ANewIndex); bool Exchange(long AIndex1, long AIndex2); long IndexOf(const void* AItem) const; long SameCount(const void* AItem, long AFrom = 0) const; long Search(const void* AItem, long AFrom = 0) const; long Search(const void* AItem, Pointer& ARetItem, long AFrom = 0) const; // 查找最近一个索引 // 若 ANearest == -1 则表示未排序, 查找失败; // 若返回值为 true, 则表示找到项索引, 否则项值在 ANearest 索引之前 bool FindNearest(const void* AItem, long& ANearest, long AFrom = 0) const; // 事件 TOnCompare OnCompare; TOnDeletion OnDeletion; protected: void LockRead() const { if (FLockRW != NULL) FLockRW->LockRead(); } void UnlockRead() const { if (FLockRW != NULL) FLockRW->UnlockRead(); } void LockWrite() const { if (FLockRW != NULL) FLockRW->LockWrite(); } void UnlockWrite() const { if (FLockRW != NULL) FLockRW->UnlockWrite(); } // FindItem 已排序列表二分查找, FindByOrder 是逐项顺序查找 int Compare(const void* AItem1, const void* AItem2) const; bool FindItem(long AFrom, long ATo, const void* AItem, long& ANearest) const; long FindByOrder(long AFrom, long ATo, const void* AItem) const; long InsertItem(long AIndex, void* AItem); bool UpdateItem(long AIndex, void* AItem); void ClearItems(); void FreeItems(long AFrom, long ACount); void QuickSort(long AFrom, long ATo); bool SetCapacity(long ACapacity); private: bool Grow(); // OnCompare.Method != NULL bool DoFindItem(long AFrom, long ATo, const void* AItem, long& ANearest) const; inline int DoCompare(const void* AItem1, const void* AItem2) const; private: TKYLockRW* FLockRW; Pointer* FItems; long FCapacity; long FCount; long FDelta; bool FSorted; bool FHasSorted; bool FCanDuplicate; };

 

    原文作者:平衡二叉树
    原文地址: https://blog.csdn.net/kyee/article/details/4711654
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞