二叉查找树(binary search tree (BST))--算法导论示例
2008-01-27 17:14
549 查看
二叉查找树(binary search tree (BST))--算法导论示例
二叉查找树(Binary Search Tree),或者是一棵空树,或者是具有下列性质的二叉树:
1. 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
2. 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
3. 它的左、右子树也分别为二叉排序树。
二叉排序树的查找过程和次优二叉树类似,通常采取二叉链表作为二叉排序树的存储结构。中序遍历二叉排序树可得到一个关键字的有序序列,一个无序序列可以通过构造一棵二叉排序树变成一个有序序列,构造树的过程即为对无序序列进行排序的过程。每次插入的新的结点都是二叉排序树上新的叶子结点,在进行插入操作时,不必移动其它结点,只需改动某个结点的指针,由空变为非空即可。搜索,插入,删除的复杂度等于树高,O(log(n)).
若b是空树,则搜索失败,否则:
若x等于b的根结点的数据域之值,则查找成功;否则:
若x小于b的根结点的数据域之值,则搜索左子树;否则:
查找右子树。
若b是空树,则将s所指结点作为根结点插入,否则:
若s->data等于b的根结点的数据域之值,则返回,否则:
若s->data小于b的根结点的数据域之值,则把s所指结点插入到左子树中,否则:
把s所指结点插入到右子树中。
若*p结点为叶子结点,即PL(左子树)和PR(右子树)均为空树。由于删去叶子结点不破坏整棵树的结构,则只需修改其双亲结点的指针即可。
右*p结点只有左子树PL或右子树PR,此时只要令PL或PR直接成为其双亲结点*f的左子树即可,作此修改也不破坏二叉排序树的特性。
若*p结点的左子树和右子树均不空。在删去*p之后,为保持其它元素之间的相对位置不变,可按中序遍历保持有序进行调整,可以有两种做法:其一是令*p的左子树为*f的左子树,*s为*f左子树的最右下的结点,而*p的右子树为*s的右子树;其二是令*p的直接前驱(或直接后继)替代*p,然后再从二叉排序树中删去它的直接前驱(或直接后继)。

#include "stdio.h"

#include "stdlib.h"


struct Node


...{

int key;//结点值

struct Node *parent;//父结点

struct Node *left;//左结点

struct Node *right;//右结点

};


//打印二叉树

void PrintTree(struct Node *Root)


...{

struct Node *pointer=(struct Node*)malloc(sizeof(struct Node));

pointer=Root;

if(pointer!=NULL)


...{

PrintTree(pointer->left);

printf("%d ",pointer->key);

PrintTree(pointer->right);

}

}


//删除树,递归释放树的结点

void DeleteTree(struct Node *Root)


...{

struct Node *pointer=(struct Node*)malloc(sizeof(struct Node));

pointer=Root;


if(pointer!=NULL)


...{

DeleteTree(pointer->left);

free(pointer);

DeleteTree(pointer->right);

}

}


//最小值

struct Node *Minimum(struct Node *Root)


...{

struct Node *pointer=(struct Node*)malloc(sizeof(struct Node));

pointer=Root;


while(pointer->left!=NULL)

pointer=pointer->left;


return pointer;

}


//最大值

struct Node *Maximum(struct Node *Root)


...{

struct Node *pointer=(struct Node*)malloc(sizeof(struct Node));

pointer=Root;


while(pointer->right!=NULL)

pointer=pointer->right;


return pointer;

}


//查找

struct Node *Search(struct Node *Root,int value)


...{

struct Node *pointer=(struct Node*)malloc(sizeof(struct Node));

pointer=Root;


while(pointer!=NULL&&pointer->key!=value)


...{

//如果查找值比结点值小,查找它的左子树

if(value<pointer->key)

pointer=pointer->left;

else

pointer=pointer->right;//如果查找值比结点值大,查找它的右子树

}


return pointer;

}


//后继

struct Node *Successor(struct Node *pointer)


...{

if(pointer->right!=NULL)

return Minimum(pointer->right);


struct Node *y=(struct Node*)malloc(sizeof(struct Node));

y=pointer->parent;

while(y!=NULL&&y->right==pointer)


...{

pointer=y;

y=pointer->parent;

}


return y;

}


//前驱

struct Node *Predecessor(struct Node *pointer)


...{

if(pointer->left!=NULL)

return Maximum(pointer->left);


struct Node *y=(struct Node*)malloc(sizeof(struct Node));

y=pointer->parent;

while(y!=NULL&&y->left==pointer)


...{

pointer=y;

y=pointer->parent;

}


return y;

}


//插入新结点

struct Node *Insert(struct Node *Root,struct Node *newNode)


...{

struct Node *back=(struct Node*)malloc(sizeof(struct Node));

struct Node *pointer=(struct Node*)malloc(sizeof(struct Node));

back=NULL;

pointer=Root;


//找到要插入的位置

while(pointer!=NULL)


...{

back=pointer;

if(newNode->key<pointer->key)

pointer=pointer->left;

else

pointer=pointer->right;

}


//新结点的Parent指针先指向父结点

newNode->parent=back;


if(back==NULL)

Root=newNode;//树为空,新结点成为树根

else


...{

if(newNode->key<back->key)

back->left=newNode;

else

back->right=newNode;

}


return Root;

}


//删除结点

struct Node *Delete(struct Node *Root,struct Node *pointer)


...{

struct Node *y=(struct Node*)malloc(sizeof(struct Node));

y->parent=NULL;

y->left=NULL;

y->right=NULL;

//找到实际要删除的结点

if(pointer->left==NULL||pointer->right==NULL)

y=pointer;

else

y=Successor(pointer);


struct Node *x=(struct Node*)malloc(sizeof(struct Node));

x->parent=NULL;

x->left=NULL;

x->right=NULL;

//要删除结点的子结点

if(y->left!=NULL)

x=y->left;

else

x=y->right;


if(x!=NULL)

x->parent=y->parent;


if(y->parent==NULL)

Root=x;//删除的是根结点

else


...{

if(y==y->parent->left)

y->parent->left=x;

else

y->parent->right=x;

}


if(y!=pointer)

pointer->key=y->key;


if(y!=NULL)


...{

free(y);

printf("Delete success! ");

}

else

printf("Delete failure! ");


return Root;

}


int main()


...{

struct Node *Root=NULL;

int value;


int flag=1;

while(flag)


...{

printf("1:Insert ");

printf("2:Delete ");

printf("3:Search ");

printf("4:Minimum ");

printf("5:Maximum ");

printf("6:Successor ");

printf("7:Predecessor ");

printf("0:Exit ");

printf("Please input your choice:");

scanf("%d",&flag);


switch(flag)


...{

case 0:

return 0;

case 1:


...{

printf("Please input the value you want to input:");

scanf("%d",&value);

struct Node *newNode=(struct Node*)malloc(sizeof(struct Node));

newNode->key=value;

newNode->parent=NULL;

newNode->left=NULL;

newNode->right=NULL;

Root=Insert(Root,newNode);

break;

}

case 2:


...{

printf("Please input the value you want to delete:");

scanf("%d",&value);

struct Node *newNode=(struct Node*)malloc(sizeof(struct Node));

newNode=Search(Root,value);

if(newNode!=NULL)

Root=Delete(Root,newNode);

else

printf("%d does'n exist in this tree! ",value);

break;

}

case 3:


...{

printf("Please input the value you want to input:");

scanf("%d",&value);

struct Node *newNode=(struct Node*)malloc(sizeof(struct Node));

newNode=Search(Root,value);

if(newNode!=NULL)

printf("%d exist in this tree! ",newNode->key);

else

printf("%d does'n exist in this tree! ",value);

break;

}

case 4:


...{

if(Root!=NULL)


...{

struct Node *newNode=(struct Node*)malloc(sizeof(struct Node));

newNode=Minimum(Root);

printf("The minimum value of this tree is %d! ",newNode->key);

}

else

printf("This tree is empty! ");

break;

}

case 5:


...{

if(Root!=NULL)


...{

struct Node *newNode=(struct Node*)malloc(sizeof(struct Node));

newNode=Maximum(Root);

printf("The Maximum value of this tree is %d! ",newNode->key);

}

else

printf("This tree is empty! ");

break;

}

case 6:


...{

printf("Please input the value:");

scanf("%d",&value);

struct Node *newNode=(struct Node*)malloc(sizeof(struct Node));

newNode=Search(Root,value);

if(newNode!=NULL)


...{

newNode=Successor(newNode);

if(newNode!=NULL)

printf("%d's successor is %d! ",value,newNode->key);

else

printf("%d has't successor int this tree! ",value);

}

else

printf("%d does'n exist in this tree! ",value);

break;

}

case 7:


...{

printf("Please input the value:");

scanf("%d",&value);

struct Node *newNode=(struct Node*)malloc(sizeof(struct Node));

newNode=Search(Root,value);

if(newNode!=NULL)


...{

newNode=Predecessor(newNode);

if(newNode!=NULL)

printf("%d's Predecessor is %d! ",value,newNode->key);

else

printf("%d has't predecessor int this tree! ",value);

}

else

printf("%d does'n exist in this tree! ",value);

break;

}

default:

break;

}


PrintTree(Root);

}


DeleteTree(Root);

return 0;

}
二叉查找树(Binary Search Tree),或者是一棵空树,或者是具有下列性质的二叉树:
1. 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
2. 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
3. 它的左、右子树也分别为二叉排序树。
二叉排序树的查找过程和次优二叉树类似,通常采取二叉链表作为二叉排序树的存储结构。中序遍历二叉排序树可得到一个关键字的有序序列,一个无序序列可以通过构造一棵二叉排序树变成一个有序序列,构造树的过程即为对无序序列进行排序的过程。每次插入的新的结点都是二叉排序树上新的叶子结点,在进行插入操作时,不必移动其它结点,只需改动某个结点的指针,由空变为非空即可。搜索,插入,删除的复杂度等于树高,O(log(n)).
二叉排序树的查找算法
在二叉排序树b中查找x的过程为:若b是空树,则搜索失败,否则:
若x等于b的根结点的数据域之值,则查找成功;否则:
若x小于b的根结点的数据域之值,则搜索左子树;否则:
查找右子树。
在二叉排序树插入结点的算法
向一个二叉排序树b中插入一个结点s的算法,过程为:若b是空树,则将s所指结点作为根结点插入,否则:
若s->data等于b的根结点的数据域之值,则返回,否则:
若s->data小于b的根结点的数据域之值,则把s所指结点插入到左子树中,否则:
把s所指结点插入到右子树中。
在二叉排序树删除结点的算法
在二叉排序树删去一个结点,分三种情况讨论:若*p结点为叶子结点,即PL(左子树)和PR(右子树)均为空树。由于删去叶子结点不破坏整棵树的结构,则只需修改其双亲结点的指针即可。
右*p结点只有左子树PL或右子树PR,此时只要令PL或PR直接成为其双亲结点*f的左子树即可,作此修改也不破坏二叉排序树的特性。
若*p结点的左子树和右子树均不空。在删去*p之后,为保持其它元素之间的相对位置不变,可按中序遍历保持有序进行调整,可以有两种做法:其一是令*p的左子树为*f的左子树,*s为*f左子树的最右下的结点,而*p的右子树为*s的右子树;其二是令*p的直接前驱(或直接后继)替代*p,然后再从二叉排序树中删去它的直接前驱(或直接后继)。
二叉排序树性能分析
每个结点的Ci为该结点的层次数。最坏情况下,当先后插入的关键字有序时,构成的二叉排序树蜕变为单支树,树的深度为n,其平均查找长度为(n+1)/2(和顺序查找相同),最好的情况是二叉排序树的形态和折半查找的判定树相同,其平均查找长度和log2n成正比(O(log2n))。
#include "stdio.h"

#include "stdlib.h"


struct Node


...{

int key;//结点值

struct Node *parent;//父结点

struct Node *left;//左结点

struct Node *right;//右结点

};


//打印二叉树

void PrintTree(struct Node *Root)


...{

struct Node *pointer=(struct Node*)malloc(sizeof(struct Node));

pointer=Root;

if(pointer!=NULL)


...{

PrintTree(pointer->left);

printf("%d ",pointer->key);

PrintTree(pointer->right);

}

}


//删除树,递归释放树的结点

void DeleteTree(struct Node *Root)


...{

struct Node *pointer=(struct Node*)malloc(sizeof(struct Node));

pointer=Root;


if(pointer!=NULL)


...{

DeleteTree(pointer->left);

free(pointer);

DeleteTree(pointer->right);

}

}


//最小值

struct Node *Minimum(struct Node *Root)


...{

struct Node *pointer=(struct Node*)malloc(sizeof(struct Node));

pointer=Root;


while(pointer->left!=NULL)

pointer=pointer->left;


return pointer;

}


//最大值

struct Node *Maximum(struct Node *Root)


...{

struct Node *pointer=(struct Node*)malloc(sizeof(struct Node));

pointer=Root;


while(pointer->right!=NULL)

pointer=pointer->right;


return pointer;

}


//查找

struct Node *Search(struct Node *Root,int value)


...{

struct Node *pointer=(struct Node*)malloc(sizeof(struct Node));

pointer=Root;


while(pointer!=NULL&&pointer->key!=value)


...{

//如果查找值比结点值小,查找它的左子树

if(value<pointer->key)

pointer=pointer->left;

else

pointer=pointer->right;//如果查找值比结点值大,查找它的右子树

}


return pointer;

}


//后继

struct Node *Successor(struct Node *pointer)


...{

if(pointer->right!=NULL)

return Minimum(pointer->right);


struct Node *y=(struct Node*)malloc(sizeof(struct Node));

y=pointer->parent;

while(y!=NULL&&y->right==pointer)


...{

pointer=y;

y=pointer->parent;

}


return y;

}


//前驱

struct Node *Predecessor(struct Node *pointer)


...{

if(pointer->left!=NULL)

return Maximum(pointer->left);


struct Node *y=(struct Node*)malloc(sizeof(struct Node));

y=pointer->parent;

while(y!=NULL&&y->left==pointer)


...{

pointer=y;

y=pointer->parent;

}


return y;

}


//插入新结点

struct Node *Insert(struct Node *Root,struct Node *newNode)


...{

struct Node *back=(struct Node*)malloc(sizeof(struct Node));

struct Node *pointer=(struct Node*)malloc(sizeof(struct Node));

back=NULL;

pointer=Root;


//找到要插入的位置

while(pointer!=NULL)


...{

back=pointer;

if(newNode->key<pointer->key)

pointer=pointer->left;

else

pointer=pointer->right;

}


//新结点的Parent指针先指向父结点

newNode->parent=back;


if(back==NULL)

Root=newNode;//树为空,新结点成为树根

else


...{

if(newNode->key<back->key)

back->left=newNode;

else

back->right=newNode;

}


return Root;

}


//删除结点

struct Node *Delete(struct Node *Root,struct Node *pointer)


...{

struct Node *y=(struct Node*)malloc(sizeof(struct Node));

y->parent=NULL;

y->left=NULL;

y->right=NULL;

//找到实际要删除的结点

if(pointer->left==NULL||pointer->right==NULL)

y=pointer;

else

y=Successor(pointer);


struct Node *x=(struct Node*)malloc(sizeof(struct Node));

x->parent=NULL;

x->left=NULL;

x->right=NULL;

//要删除结点的子结点

if(y->left!=NULL)

x=y->left;

else

x=y->right;


if(x!=NULL)

x->parent=y->parent;


if(y->parent==NULL)

Root=x;//删除的是根结点

else


...{

if(y==y->parent->left)

y->parent->left=x;

else

y->parent->right=x;

}


if(y!=pointer)

pointer->key=y->key;


if(y!=NULL)


...{

free(y);

printf("Delete success! ");

}

else

printf("Delete failure! ");


return Root;

}


int main()


...{

struct Node *Root=NULL;

int value;


int flag=1;

while(flag)


...{

printf("1:Insert ");

printf("2:Delete ");

printf("3:Search ");

printf("4:Minimum ");

printf("5:Maximum ");

printf("6:Successor ");

printf("7:Predecessor ");

printf("0:Exit ");

printf("Please input your choice:");

scanf("%d",&flag);


switch(flag)


...{

case 0:

return 0;

case 1:


...{

printf("Please input the value you want to input:");

scanf("%d",&value);

struct Node *newNode=(struct Node*)malloc(sizeof(struct Node));

newNode->key=value;

newNode->parent=NULL;

newNode->left=NULL;

newNode->right=NULL;

Root=Insert(Root,newNode);

break;

}

case 2:


...{

printf("Please input the value you want to delete:");

scanf("%d",&value);

struct Node *newNode=(struct Node*)malloc(sizeof(struct Node));

newNode=Search(Root,value);

if(newNode!=NULL)

Root=Delete(Root,newNode);

else

printf("%d does'n exist in this tree! ",value);

break;

}

case 3:


...{

printf("Please input the value you want to input:");

scanf("%d",&value);

struct Node *newNode=(struct Node*)malloc(sizeof(struct Node));

newNode=Search(Root,value);

if(newNode!=NULL)

printf("%d exist in this tree! ",newNode->key);

else

printf("%d does'n exist in this tree! ",value);

break;

}

case 4:


...{

if(Root!=NULL)


...{

struct Node *newNode=(struct Node*)malloc(sizeof(struct Node));

newNode=Minimum(Root);

printf("The minimum value of this tree is %d! ",newNode->key);

}

else

printf("This tree is empty! ");

break;

}

case 5:


...{

if(Root!=NULL)


...{

struct Node *newNode=(struct Node*)malloc(sizeof(struct Node));

newNode=Maximum(Root);

printf("The Maximum value of this tree is %d! ",newNode->key);

}

else

printf("This tree is empty! ");

break;

}

case 6:


...{

printf("Please input the value:");

scanf("%d",&value);

struct Node *newNode=(struct Node*)malloc(sizeof(struct Node));

newNode=Search(Root,value);

if(newNode!=NULL)


...{

newNode=Successor(newNode);

if(newNode!=NULL)

printf("%d's successor is %d! ",value,newNode->key);

else

printf("%d has't successor int this tree! ",value);

}

else

printf("%d does'n exist in this tree! ",value);

break;

}

case 7:


...{

printf("Please input the value:");

scanf("%d",&value);

struct Node *newNode=(struct Node*)malloc(sizeof(struct Node));

newNode=Search(Root,value);

if(newNode!=NULL)


...{

newNode=Predecessor(newNode);

if(newNode!=NULL)

printf("%d's Predecessor is %d! ",value,newNode->key);

else

printf("%d has't predecessor int this tree! ",value);

}

else

printf("%d does'n exist in this tree! ",value);

break;

}

default:

break;

}


PrintTree(Root);

}


DeleteTree(Root);

return 0;

}

相关文章推荐
- 二叉查找树(binary search tree (BST))--算法导论示例
- 【算法导论学习-24】二叉树专题2:二叉搜索树(Binary Search Tree,BST)
- BST(Binary Search Tree,二叉查找树,二叉排序树)c的实现(部分函数不知如何调用)
- leetcode:Recover Binary Search Tree (修正二叉查找树错误节点,不改变结构)【面试算法题】
- 72【leetcode】经典算法- Lowest Common Ancestor of a Binary Search Tree(lct of bst)
- BST(Binary Search Tree 二叉查找树模版)
- 72【leetcode】经典算法- Lowest Common Ancestor of a Binary Search Tree(lct of bst)
- 72【leetcode】经典算法- Lowest Common Ancestor of a Binary Search Tree(lct of bst)
- 72【leetcode】经典算法- Lowest Common Ancestor of a Binary Search Tree(lct of bst)
- 【数据结构与算法基础】二叉查找树 / Binary Search Tree
- 二叉搜索树;二叉查找树;二叉排序树;binary search tree(BST)
- 72【leetcode】经典算法- Lowest Common Ancestor of a Binary Search Tree(lct of bst)
- 二叉排序树(Binary Sort Tree,二叉查找树,二叉搜索树)--【算法导论】
- Lowest Common Ancestor of a Binary Search Tree (BST)
- 【二叉查找树】04根据升序数组构造二叉查找树【Convert Sorted Array to Binary Search Tree】
- leetcode99---Recover Binary Search Tree(morris中序遍历恢复BST)
- 1043. Is It a Binary Search Tree (25)--BST引用插入、二叉树遍历模板
- Convert Sorted List to Binary Search Tree——将链表转换为平衡二叉搜索树 &&convert-sorted-array-to-binary-search-tree——将数列转换为bst
- 二叉查找树的原理与实现 Binary Search Tree
- Convert Sorted List to Binary Search Tree ------C++ 递归创建平衡二叉查找树