不相交数据结构

摘要:
(1)不相交数据结构是一种非常有用的数据结构,它类似于一种集合,高效的支持某两个元素是否在同一个元素中的查找操作,也支持合并两个集合,在集合中删除某个元素等操作.
【1】基本数据结构:不相交数据结构常用的一种形式是由树的构成的.树被储存在一个数组中(非显式的存储).集合的名字由树的根给出.假如该数组元素的值大于0,那么它不是根,否则它就是根(大小的负值由该数组元素的值)是否进行路径压缩是一件很重要的事,所谓路径压缩就是指在查找某个元素时,将它路径上的所有点的值都记录为所在集合的根.

#include "stdafx.h"
#include "malloc.h"
#define Numelements 9
typedef int Disjset[Numelements+1];
typedef struct Record *Stack;
struct Record
{
    int size;
    int top;
    int * height;
    int * root;
};

【2】基本操作结构,查找与合并

int Find(Disjset S,int x)//查询元素x所在的集合
{
    if (S[x] <= 0)
        return x;//返回所在集合(根)
    else
          return Find(S,S[x]);//不进行路径压缩
         //return S[x] = Find(S,S[x]);//路径压缩,返回根
}

void Union_size(Disjset S,int Root1,int Root2)
{

    Root1 = Find(S,Root1), Root2 = Find(S,Root2);//确保传进来的Root代表真正的根
    //按大小合并
    if (S[Root1] <= S[Root2])//Root1大
    {
        S[Root1] += S[Root2];
        S[Root2] = Root1;
    }
    else
    {
            S[Root2] += S[Root1];//大小变大
            S[Root1] = Root2;
    }
}
3】按高度合并:
void Union_height(Disjset S,Stack record,int Root1,int Root2)
{

    //按高度合并
    Root1 = Find(S,Root1), Root2 = Find(S,Root2);//确保传进来的Root代表真正的根
    Push(record,S[Root1],S[Root2],Root1,Root2);
    if (S[Root2] < S[Root1])//Root1大
    {
        S[Root1] = Root2;
    }
    else
    {
            if (S[Root1] == S[Root2])
                S[Root1]--;
            S[Root2] = Root1;
    }
}

【5】
废除最后一次的Union操作;
使用一个栈记录最近发送的union操作与相应的集合.方便进行删除.

void Inistack(Stack S,int Size)
{
    S->height = (int *)malloc(sizeof(int)*Size);
    S->root = (int *)malloc(sizeof(int)*Size);
    S->size = Size;
    S->top = -1;
}
void Pop(Stack S ,int & oldheight1, int&oldheight2, int &root1, int &root2 )
{
    if (S->top == -1)
        return;
    oldheight2 = S->height[S->top];
    root2 = S->root[S->top--];
    root1 = S->root[S->top];
    oldheight1 = S->height[S->top--];
}
void Push(Stack S,int height1,int height2,int root1,int root2)
{
    if (S->top == S->size - 1)
        return;
    S->root[++S->top] = root1;
    S->height[S->top] = height1 ;
    S->root[++S->top] = root2;
    S->height[S->top] = height2;
}
void Deunion(Disjset S, Stack record)
{
    int oldroot1,oldroot2,oldheight1,oldheight2;
    Pop(record,oldheight1,oldheight2,oldroot1,oldroot2);
    S[oldroot1] = oldheight1;
    S[oldroot2] = oldheight2;
}

你可能感兴趣的:(数据结构,合并)