算法10---二叉搜索树存在重复数据插入的实现

算法10---二叉搜索树存在重复数据插入的实现

当用TREE-INSERT将n个具有相同关键字的数据项插入到一棵初始为空的二叉查找树中时,该算法的渐近性能如何?

我们可以对TREE-INSERT做一些改进,即在第5行的前面测试key[z] = key[x],在第11行的前面测试key[z] = key[y]。如果等式成立,我们对下列策略中的某一种加以实现。对每一种策略,请给出将n个具有相同关键字的数据插入一棵初始为空的二叉查找树中的渐近性能(以下的策略是针对第5行的,比较的是z和x的关键字。将x换成y即可用于第11行)。

b)在结点x处设一个布尔标志b[x],并根据b[x]的不同值,置x为left[x]或right[x]。每当插入一个与x具有相同关键字的结点时,b[x]取TRUE或FALSE。

c)在结点x处设置一个列表,其中所有结点都具有与x相同的关键字,并将z插入到该列表中。

d)随机地将置为left[x]或right[x]

思考:

b)每次测试到等式成立时,若b[x]为FLASE,插入到左子树中,b[x]为TRUE时,插入到右子树中,然后将b[x]取反。

c)使用一个链表,所有具有相同关键字的结点组成一个链表,结点中的一个指针指向这个链表。

d)使用rand()%2随机地决定插入到左子树中还是右子树中。

代码实现如下;首先是b方法

 1 //二叉查找树结点的结构
 2 struct node
 3 {
 4     int key;//关键字
 5     int data;//卫星数据
 6     bool b;
 7     node *left;//左孩子
 8     node *right;//右孩子
 9     node *p;//父结点
10     node(int x):key(x),data(x),b(0),left(NULL),right(NULL),p(NULL){}; //初始化
11 };
12 //二叉查找树的结构
13 struct tree
14 {
15     node *root;
16     tree():root(NULL){}//都是初始化的方法
17 };
18 //二叉查找树的插入
19 void Tree_Insert(tree *T, node *z)
20 {
21     //找到要插入的位置
22     node *x = T->root, *y = NULL;
23     //若x为空,x是要插入的位置,x的父是z->p
24     while(x != NULL)
25     {
26         y = x;
27         //等式成立时,由b决定插入到哪个子树
28         if(z->key == x->key)
29         {
30             if(x->b == 0)
31                 x = x->left;
32             else
33                 x = x->right;
34             //对b取反
35             x->b = !x->b;
36         }
37         else if(z->key < x->key)
38             x = x->left;
39         else
40             x = x->right;
41     }
42     //修改指针,注意树为空的情况
43     z->p = y;
44     if(y == NULL)
45         T->root = z;
46     else if(z->key == y->key)
47     {
48         if(y->b == 0)
49             y->left = z;
50         else y->right = z;
51         y->b = !y->b;
52     }
53     else if(z->key < y->key)
54         y->left = z;
55     else y->right = z;
56 }

C方法代码实现如下

 1 //二叉查找树结点的结构
 2 struct node
 3 {
 4     int key;//关键字
 5     int data;//卫星数据
 6     node *next;//指向具体相同关键字的链表
 7     node *left;//左孩子
 8     node *right;//右孩子
 9     node *p;//父结点
10     node(int x):key(x),data(x),left(NULL),right(NULL),p(NULL),next(NULL){}
11 };
12 //二叉查找树的结构
13 struct tree
14 {
15     node *root;
16     tree():root(NULL){}
17 };
18 //二叉查找树的插入
19 void Tree_Insert(tree *T, node *z)
20 {
21     //找到要插入的位置
22     node *x = T->root, *y = NULL;
23     //若x为空,x是要插入的位置,x的父是z->p
24     while(x != NULL)
25     {
26         y = x;
27         //等式成立时,不继续插入到子树中,而是链入链表中
28         if(z->key == x->key)
29         {
30             z->next = x->next;
31             x->next = z;
32             return;
33         }
34         else if(z->key < x->key)
35             x = x->left;
36         else
37             x = x->right;
38     }
39     //修改指针,注意树为空的情况
40     z->p = y;
41     if(y == NULL)
42         T->root = z;
43     //等式成立时,不是插入到子树中,而是链入链表中
44     else if(z->key == y->key)
45     {
46         z->next = y->next;
47         y->next = z;
48     }
49     else if(z->key < y->key)
50         y->left = z;
51     else y->right = z;
52 }

d方法实现如下

 1 //二叉查找树结点的结构
 2 struct node
 3 {
 4         int key;//关键字
 5         int data;//卫星数据
 6         node *left;//左孩子
 7         node *right;//右孩子
 8         node *p;//父结点
 9         node(int x):key(x),data(x),left(NULL),right(NULL),p(NULL){}
10 };
11 //二叉查找树的结构
12 struct tree
13 {
14         node *root;
15         tree():root(NULL){}
16 };
17 //二叉查找树的插入
18 void Tree_Insert(tree *T, node *z)
19 {
20         //找到要插入的位置
21         node *x = T->root, *y = NULL;
22         //若x为空,x是要插入的位置,x的父是z->p
23         while(x != NULL)
24         {
25                 y = x;
26                 //若等式成立,随机地决定插入到哪个子树中
27                 if(z->key == x->key)
28                 {
29                         if(rand()%2 == 0)
30                                 x = x->left;
31                         else
32                                 x = x->right;
33                 }
34                 else if(z->key < x->key)
35                         x = x->left;
36                 else
37                         x = x->right;
38         }
39         //修改指针,注意树为空的情况
40         z->p = y;
41         if(y == NULL)
42                 T->root = z;
43         else if(z->key == y->key)
44         {
45                 if(rand()%2 == 0)
46                         x = x->left;
47                 else
48                         x = x->right;
49         }
50         else if(z->key < y->key)
51                 y->left = z;
52         else y->right = z;
53 }
时间: 2024-12-26 19:23:16

算法10---二叉搜索树存在重复数据插入的实现的相关文章

70 数组的Kmin算法和二叉搜索树的Kmin算法对比

[本文链接] http://www.cnblogs.com/hellogiser/p/kmin-of-array-vs-kmin-of-bst.html [分析] 数组的Kmin算法和二叉搜索树的Kmin算法非常类似,其本质是找序列中的第K大或者第K小的元素,可以借鉴QuickSort的思想加以实现. [Kmin_of_Array] C++ Code 1234567891011121314151617181920212223242526272829303132333435363738394041

C++算法之 二叉搜索树转换为双向链表

题目: 输入一颗二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的节点,只能调整树中节点指针的方向: 分析: 1:由于要求链表是有序的,可以借助二叉树中序遍历,因为中序遍历算法的特点就是从小到大访问结点.当遍历访问到根结点时,假设根结点的左侧已经处理好,只需将根结点与上次访问的最近结点(左子树中最大值结点)的指针连接好即可.进而更新当前链表的最后一个结点指针. 2:由于中序遍历过程正好是转换成链表的过程,即可采用递归处理 代码: // BT.cpp : 定义控制台应用程序的

数据结构与算法之二叉搜索树

与链表不同,树是一种非线性的数据结构.树中最常用的是二叉树,二叉树限制了子树的数量,也就是每个结点的子树至多2个,并且这两个子树是有顺序的.而二叉搜索树(二叉查找树,二叉排序树)是指根节点的关键字大于左子树的,而小于右子树,并且,左右子树也是一颗二叉搜索树.也就是说中序遍历一颗二叉搜索树,它的输出是从小到大排序好的. 除了普通的二叉搜索树之外,还有很多关于它的变形. 二叉平衡搜索树,即即是一颗二叉平衡树,也是一颗搜索树,平衡树即任意一个结点的左子树的高度与右子树的高度之差的绝对值不大于1. 红黑

一步两步学算法之二叉搜索树

Binary Search Tree  又叫二叉查找树,二叉排序树 这是种什么样的树呢? 其实就是根节点的左子树比根节点小  右子树比根节点大  同时 左子树和右子树也是二叉搜索树 代码比较简单 基本用递归实现 比较好理解  只有删除带有左右子树的节点时比较难理解 方法就是 直接在右子树找一个最小的节点 取代要被删除的节点 再继续删除右子树里的节点 详细看代码 1 #include "stdio.h" 2 #include "stdlib.h" 3 typedef

算法导论—二叉搜索树(BST)

华电北风吹 天津大学认知计算与应用重点实验室 日期:2015/9/9 与散列表一样,搜索树数据结构也支持动态集合操作,包含插入,查询,删除,最小值,最大值,前驱,后继等. 一.二叉搜索树: 二叉搜索树节点:关键字key,卫星数据,左孩子指针,右孩子指针,父节点指针,其他特殊类型(红黑树的节点颜色,AVL树的树高等). 二叉搜索树性质:x是二叉搜索树中的任意一个节点.若y是x左子树中任意一个节点有x.key>=y.key.若y是x右子树中任意一个节点有x.key<=y.key. 二.二叉搜索树的

二叉搜索树的创建 &amp;&amp; 查找 &amp; 插入 &amp; 删除

二叉搜索树的删除: 在删除之前需要从树中查找到这个节点,然后再针对情况来判断如何删除. 分为三种情况,首先是此节点没有孩子节点,此节点有一个孩子节点,此节点有两个孩子节点 void Delete(BinTree*& root,int value) { BinTree* delnode= NULL; if(root == NULL) return ; BinTree* temp = root; BinTree* parent =NULL; while(temp!=NULL) { if(temp-&g

算法导论-----------二叉搜索树

先上二叉树查找树的删除的代码,因为删除是二叉查找树最复杂的操作: int BinarySearchTree<T>::tree_remove(const T& elem) { BinarySearchTreeNode<T> *z = tree_search(elem);//根据元素查找到要删除的节点 BinarySearchTreeNode<T> *x, *y; if (z != NULL) { //用y来表示实际要删除的节点 if (z->left ==

【算法设计-二叉搜索树】二叉查找树的操作与实现

二叉查找树某个结点的左子树的值都比它小,其右子树的值比它大. 要实现的主要操作 代码实现 #include <iostream> using namespace std; // BST的结点 typedef struct node { int key; struct node *lChild, *rChild,*parent; }Node, *BST; BST lvis=NULL;//用来保存父节点的地址 void createBST(BST &p); void assignmentP

数据结构与算法问题 二叉搜索树

1.序 具体实现了二叉查找树的各种操作:插入结点.构造二叉树.删除结点.查找.  查找最大值.查找最小值.查找指定结点的前驱和后继 2.二叉查找树简单介绍 它或者是一棵空树:或者是具有下列性质的二叉树: (1)若左子树不空,则左子树上全部结点的值均小于它的根结点的值. (2)若右子树不空.则右子树上全部结点的值均大于它的根结点的值: (3)左.右子树也分别为二叉排序树 3.二叉查找树的各种操作 此处给出代码.凝视很具体.具体操作请參考代码: #include <iostream> using