【数据结构】4. 树与二叉树(7)
通常用树(森林)的双亲表示作为并査集的存储结构,每个子集合以一棵树表示。 例如,若设有一个全集合为 S={0,1,3,4,5,6,7,8,9},初始化时每个元素自成一个单元素 | 经过一段时间的计算,这些子集合合并成 3 个更大的子集合:\(S_1=\{0,8\}\)、\(S_2=\{1,9\}\)、\(S_3=\{2,5\}\),此时并査集的树形表示和存储结构如图 4-18 所示。 为了得到两个子集合的并,只要将其中一个子集合根结点的双亲指针指向另一个集合的根结点即可。 并査集的结构定义如下: #define SIZE 100 int UFSets[SIZE]; //集合元素数组(双亲指针数组) 并查集的初始化操作(S 即为并査集)。 void Initial(int S[]) { for(int i=0; i<size; i++) //每个自成单元素集合 S[i] = -1; } Find 操作(函数在并査集 S 中査找并返回包含元素 x 的树的根)。 int Find(int S[],int x){ while(S[x]>=0) //循环寻找 x 的根 x=S[x]; return x; //根的 s[]小于 0 } Union 操作(函数求两个不相交子集合的并集)。 void Union(int S[],int Root1,int Root2) { //要求 Rootl 与 Root2 是不同的, 且表示子集合的名字 S[Root2] = Root1; //将根 Root2 连接到另一根 Rootl 下面 } 4.5 树与二叉树的应用4.5.1 二叉排序树(1)二叉排序树的定义二叉排序树(简称 BST),也称为二叉査找树。
由此定义可知,二叉排序树是一个递归的数据结构,可以方便地使用递归算法对二叉排序树进行各种运算。 (2)二叉排序树的查找二叉排序树的査找是从根结点开始,沿某一个分支逐层向下进行比较的过程。 二叉排序树的非递归査找算法: BSTNode *BST_Search(BiTree T,ElemType key,BSTNode *&p) { //査找函数返回&向关键字值为 key 的结点指针,若不存在,返回 NULL p = NULL; //p 指向被査找结点的双亲,用于插入和删除操作中 while(T!=NULL && key!=T->data) { p = T; if(key<T->data) T = T->lchild; else T = T->rchild; } return T; } 例如,在图 4-20 中査找值为 4 的结点。 同样,二叉排序树的査找也可以用递归算法实现,递归算法比较简单,但执行效率较低。 (3)二叉排序树的插入二叉排序树作为一种动态集合,其特点是树的结构通常不是一次生成的,而是在査找过程中,当树中不存在关键字等于给定值的结点时再进行插入。 int BST_Insert(BiTree &T,KeyType k) { //在二叉奋序树 T 中插入一个关键字为 k 的结点 if(T == NULL){ //原树为空,新插入的记录为根结点 T=(BiTree)malloc(sizeof(BSTNode)); T->key = k; T->lchild = T->rhild = NULL; return 1; //返回 1,表示成功 } else if(k == T->key) //树中存在相同关键字的结点 return 0; else if(k<T->key) //插入到 T 的左子树中 return BST_Insert(T->lchild,k); else //插入到 T 的右子树中 return BST_Insert(T->rchild,k); } 由此可见,插入的新结点一定是某个叶结点。 (4)二叉排序树的构造(编辑:ASP站长网) |