数据结构–二叉排序树

2023-05-26 0 948

链表次序树

链表次序树(BST)

表述

链表次序树又称为链表搜寻树。链表次序树或者一株空树,或者一株具备以下优点的有向链表树:

1)若左结点树有向,则左结点树下大部份结点URL波皮夫大于根结点的URL值。

2)若左结点树非空,则左结点树下大部份结点URL波皮夫大于根结点的URL值。

3)左、左结点树这类也依次是一株链表次序树

数据结构–二叉排序树

左结点树结点值 < 根结点值 < 左结点树结点值,对链表次序树展开前序结点,能获得两个递减的科学规范字符串。

搜寻

二叉次序树的搜寻从根结点已经开始,沿某一组成部分逐级向上展开较为的操作过程。若链表树有向,则将取值值与根结点的URL较为;若成正比,则搜寻获得成功;若以内,则现阶段结点的URL值大于取值URL值时,在根结点的左结点树搜寻,不然在根结点的左结点根上搜寻。这是两个递回的操作过程。

链表次序树的递回搜寻演算法:

BSTNode* BST_Search(BitTree T, ElemType key){ if(T == NULL){ return NULL; } if( T->data == key){ return T; }else if( T->data > key){ return BST_Search(T->lchild, key); }else if( T->data < key){ return BST_Search(T->rchild, key); } }

链表次序树的非递回搜寻演算法:

BSTNode* BST_Search(BitTree T, ElemType key, BSTNode* &p){ p = NULL; while( T != NULL && key != T->data ){ p = T; if( key < T->data ){ T = T->lchild; }else{ T = T->rchild; } } return T; }

插入

链表次序树是一种动态几何,其特点是树的结构通常不是一次生成的,而是在搜寻操作过程中,当根上不存在URL值等于取值值的结点时在展开插入的。

由于链表次序树是递回表述的,因此插入结点的操作过程如下:若链表次序树为空,则直接插入结点;不然,若URLk大于根结点URL,则插入左结点树,若URL大于根结点URL,则插入左结点树。

bool BST_Insert(BitTree& T, ElemType k){ if( T == NULL){ T = (BitTree*)malloc(sizeof(BitTree)); T->data = k; T->lchild = T->rchild = NULL; return true; }else if( T->data == k){ //根上存在相同URL的结点 return false; }else if( k < T->key ){ return BST_Insert(T->lchild, k); }else if( k > T->data ){ return BST_Insert(T->rchild, k); } return true; }
数据结构–二叉排序树

链表次序树的构造

构造一株链表树就是依次输入数据元素,并将它们插入链表次序根上适当位置上的操作过程。具体操作过程:每读入两个元素,就建立两个结点,若链表次序树有向,则将新结点的值与根结点的值作较为,若大于根结点的值,则插入左结点树,不然插入左结点树;若链表次序树为空,则将新结点作为链表次序树的根结点。

void BST_Create(BitTree& T, ElemType str[]){ int sz = sizeof(str)/sizeof(str[0]); T = NULL; int i = 0; while( i < sz ){ Create_BST(T,str[i]); i++; } }

删除(难点)

在链表次序根上删除两个结点时,不能把以结点为根的结点下的结点都删除,必须先把被删除结点从存储链表次序树的链表上摘下,将因删除结点而断开的链表链表重新链接起来,同时确保链表次序树的性质不会丢失。

删除操作按三种情况来处理:

若被删除结点 x 是叶结点,则直接删除,不会破坏链表次序树的性质若结点 x 只有一株左结点树或左结点树,则让 x 的结点成为 x 父结点 的结点,替代 x 的位置若结点 x 有左、右两棵结点,则令 x 的直接后继(或直接前驱)替代 x ,然后从链表次序根上删除这个直接后继(或直接前驱),这样就转换成了第一或第二种情况。
数据结构–二叉排序树
//前序结点字符串的下两个结点,即比当前结点大的最小结点,简称后继结点。int successor(BSTTree* p){ p = p->rchild; while(p->lchild != NULL){ p = p->left; } return p->data; } //前序结点字符串的前两个结点,即比现阶段结点小的最大结点,简称前驱结点。 int predecessor(BSTTree* p){ p = p->lchild; while(p->rchild != NULL){ p = p->rchild; } return p->data; } BSTNode* BST_Delete(BSTTree& T, ElemType x){ if( T == NULL){ return NULL; }else{ if( x < T->data ){ //要删除的在左边 T->lchild = BST_Delete(T->lchild, x); }else if( x > T->data ){ //要删除的在右边 T->rchild = BST_Delete(T->rchild, x); }else{ if( T->lchild == NULL && T->rchild == NULL){//叶子结点 T = NULL; }else if( T->rchild != NULL){ //如果该结点不是叶子结点且有右结点,则用它的后继结点的值替代,然后删除后继结点 T->data = successor(T); T->rchild = BST_Delete(T->rchild, T->data); }else { //如果该结点不是叶子结点且只有左结点,则用它的前驱结点的值替代,然后删除前驱结点 T->data = predecessor(T); T->lchild = BST_Delete(T->lchild, T->data); } } } return T; }

链表次序树的搜寻效率

对于高度为h的链表次序树,插入和删除操作的运行时间都是O(h)。但在最坏情况下,构造链表次序树的输入字符串是科学规范的,则会形成两个倾斜的单支树,此时链表次序树的性能新竹变坏,树的高度也增加为元素个数n。

链表次序树的搜寻演算法平均搜寻长度,主要取决于树的高度,即与链表树的形态有关。若退化成链表,则为O(n);若为平衡链表树,则为O(log2n)。

相同的URL其插入顺序不同可能生成不同的链表次序树。

数据结构–二叉排序树
https://xiuxin.gitbook.io/datastructre/xiuxin.gitbook.io/datastructre/

个人主页:

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务