顺序统计量树的检索元素和秩递归和迭代方法完整代码(C语言)

递归检索元素os_select


 node* os_select(tree &t, int i)                             //返回第i小的结点,递归
{
     node *x = t;
     int r = x->left->size + 1;
     if (i == r)
         return x;
     else if (i < r)
         return os_select(x->left, i);
     else
         return os_select(x->right, i - r);

}

迭代检索元素os_select

node* os_select_(tree &t, int i)                 //diedai
 {
     node *x = t;
     int r = x->left->size + 1;
     while (i != r)
     {
         r = x->left->size + 1;
         if (i < r)
         {
             x = x->left;

         }
         else if(i>r)
         {
             x = x->right;
             i = i - r;

         }

     }
     return x;
 }

递归检索秩os_rank

 int os_rank_(node*x,tree &t, int m)                       //digui
 {

     static int r = x->left->size + 1;
     node *y = x;
     if (y==t)
         return r;
     else
     {
         if (y == y->parent->right)
             r = r + y->parent->left->size + 1;
         return os_rank_(y->parent,t, m);
     }


 }

迭代检索秩os_rank


 int os_rank(tree &t, int m)                            //返回元素值为x的次序
 {
     node* x=search(t, m);
     int r = x->left->size + 1;
     node  *y = x;
     while (y != nil)
     {
         if (y == y->parent->right)
             r = r + y->parent->left->size + 1;
         y = y->parent;
     }
     return r;

}

完整代码
从红黑树代码修改而来,主要是加入size,以及在insert和delete和left_rotate、right_rotate时去修改size变化


#include "stdafx.h"
#include<stdio.h>
#include<stdlib.h>
typedef int type;
typedef enum Color   //定义红黑树结点颜色颜色类型  
{
    red = 0,
    black = 1
}Color;
typedef struct rbtree     //定义红黑树的结构
{
    Color color;
    type key;
    type size;
    struct rbtree *left;
    struct rbtree *right;
    struct rbtree *parent;

}node, *tree;

node *nil = NULL;                        //创建一个哨兵结点。这里要用哨兵去让空的叶子结点的颜色是black的,参照红黑树的定义

node* create(type key, node *left, node *right, node *parent,type size)                       //创建结点
{
    node *p;
    node *nil;
    nil = (node*)malloc(sizeof(node));
    p = (node*)malloc(sizeof(node));
    nil->parent = NULL;
    nil->left = NULL;
    nil->color = black;
    nil->key = NULL;
    nil->size = 0;
    p->color = black;                                                        //默认颜色为black
    p->left = left;
    p->right = right;
    p->parent = parent;
    p->key = key;
    p->size = size;
    /*  printf("创造结点完毕");*/
    return p;

}

void left_rotate(tree &t, node *x)                                 //左旋,这个看图就能理解具体操作
{
    if (x->right != nil)
    {
        node *y = x->right;
        x->right = y->left;
        if (y->left != nil)
            y->left->parent = x;
        y->parent = x->parent;
        if (x->parent == nil)
            t = y;
        else
        {
            if (x == x->parent->left)
                x->parent->left = y;
            else
                x->parent->right = y;
        }
        y->left = x;
        x->parent = y;
        y->size = x->size;
        x->size = x->left->size + x->right->size + 1;
    }
    else
    {
        printf("%s/n", "can't execute left rotate due to null right child");
    }
}

void right_rotate(tree &t, node *x)                   //右旋
{
    if (x->left != nil)
    {
        node *y = x->left;
        x->left = y->right;
        if (y->right != nil)
            y->right->parent = x;
        y->parent = x->parent;
        if (x->parent == nil)
            t = y;                             //
        else
        {
            if (x == x->parent->left)
                x->parent->left = y;
            else
                x->parent->right = y;
        }
        y->right = x;
        x->parent = y;
        y->size = x->size;
        x->size = x->left->size + x->right->size + 1;
    }

    else
        printf("%s/n", "can't execute right rotate due to null left child");
}


node* search(tree &t, type key)                        //查找元素
{
    node *x = t;
    if (x == nil || x->key == key)
    {

        return t;
    }

    if (key < x->key)
    {

        return search(x->left, key);
    }
    else

    {

        return search(x->right, key);

    }


}                                                                  //递归查找


 node* os_select(tree &t, int i)                             //返回第i小的结点,递归
{
     node *x = t;
     int r = x->left->size + 1;
     if (i == r)
         return x;
     else if (i < r)
         return os_select(x->left, i);
     else
         return os_select(x->right, i - r);

}


 node* os_select_(tree &t, int i)                 //diedai
 {
     node *x = t;
     int r = x->left->size + 1;
     while (i != r)
     {
         r = x->left->size + 1;
         if (i < r)
         {
             x = x->left;

         }
         else if(i>r)
         {
             x = x->right;
             i = i - r;

         }

     }
     return x;
 }



 int os_rank(tree &t, int m)                            //返回元素值为x的次序
 {
     node* x=search(t, m);
     int r = x->left->size + 1;
     node  *y = x;
     while (y != nil)
     {
         if (y == y->parent->right)
             r = r + y->parent->left->size + 1;
         y = y->parent;
     }
     return r;

}


 int os_rank_(node*x,tree &t, int m)                       //digui
 {

     static int r = x->left->size + 1;
     node *y = x;
     if (y==t)
         return r;
     else
     {
         if (y == y->parent->right)
             r = r + y->parent->left->size + 1;
         return os_rank_(y->parent,t, m);
     }


 }



void rb_insert_fixup(tree &t, node* z)
{
    node *y;
    while ((z->parent != nil) && (z->parent->color == red))                                //only when z's parent is red there will probably obey the red node has two black nodes
    {
        if (z->parent == z->parent->parent->left)                //z'parent is the left node
        {

            y = z->parent->parent->right;                         //let y be z's uncle node
            if (y->color == red)                                  //parent and uncle and itself are all red
            {
                z->parent->color = black;
                y->color = black;
                z->parent->parent->color = red;
                z = z->parent->parent;                              //let z up to its grandpa
            }
            else
            {
                if (z == z->parent->right)                         // z is a right node
                {
                    z = z->parent;
                    left_rotate(t, z);

                }
                z->parent->color = black;
                z->parent->parent->color = red;
                right_rotate(t, z->parent->parent);
            }

        }
        else                                                     //z's parent is the right node
        {
            y = z->parent->parent->left;
            if (y->color == red)
            {

                z->parent->color = black;
                y->color = black;
                z->parent->parent->color = red;
                z = z->parent->parent;
            }

            else
            {

                if (z == z->parent->left)                         // z is a left node
                {
                    z = z->parent;
                    right_rotate(t, z);
                }
                z->parent->color = black;
                z->parent->parent->color = red;
                left_rotate(t, z->parent->parent);
            }
        }

    }

    t->color = black;                                   //始终保持根节点是黑色
}


node* rb_insert(tree &t, node *z)                        //插入操作
{
    if (t == NULL)                                                  //t是空的树
    {
        t = (tree)malloc(sizeof(node));
        nil = (node*)malloc(sizeof(node));                       //初始化哨兵结点
        nil->color = black;
        nil->size = 0;
        t->left = nil;
        t->right = nil;
        t->parent = nil;
        t->key = z->key;
        t->size = 1;
        t->color = black;
    }

    else
    {
        node *y = nil;
        node *x = t;                             //


        while (x != nil)
        {
            y = x;
            x->size++;
            if (z->key < x->key)
                x = x->left;
            else
                x = x->right;

        }
        z->parent = y;
        if (y == nil)
            t = z;
        else
        {
            if (z->key < y->key)
                y->left = z;
            else
                y->right = z;
        }
        z->left = nil;
        z->right = nil;
        z->color = red;
        z->size = 1;
        //始终保持插入的结点是红色,不符合具体性质了再用fixup调整
        rb_insert_fixup(t, z);
    }
    return t;
}
node* rb_insert_(tree &t, type k)
{
    node *z;
    z = create(k, nil, nil, nil,1);
    return  rb_insert(t, z);
}


node* min(tree &m)                     //最小值
{
    node *n = m;

    if (n == nil)
        return nil;

    while (n->left != nil)
    {
        n = n->left;
    }
    return n;
}

node* successor(node *s)           //后继
{
    node *p;
    node *m = s;                     //代替s去移动
    if (m->right != nil)             //结点右子树非空
    {
        return  min(m->right);
    }
    else
    {
        p = m->parent;                //结点是左孩子,后继就是他的父节点
        while (p != nil && p->right == m)
        {                                       //结点是右孩子,向上查找,直到遇到一个有左孩子的父节点,那就是后继
            {
                m = p;
                p = p->parent;
            }
        }
        return p;
    }

}



void rb_delete_fixup(tree &t, node *x)
{
    node *w;
    while (x != t && x->color == black)                      //
    {
        if (x == x->parent->left)
        {
            w = x->parent->right;
            if (w->color == red)
            {
                w->color = black;
                x->parent->color = red;
                left_rotate(t, x->parent);
                w = x->parent->right;
            }
            if (w->left->color == black && w->right->color == black)
            {
                w->color = red;
                x = x->parent;
            }
            else if (w->right->color == black)
            {
                w->left->color = black;
                w->color = red;
                right_rotate(t, w);
                w = x->parent->right;
            }
            w->color = x->parent->color;
            x->parent->color = black;
            w->right->color = black;
            left_rotate(t, x->parent);
            x = t;                                        //

        }
        else
        {
            w = x->parent->left;
            if (w->color = red)
            {
                w->color = black;
                x->parent->color = red;
                right_rotate(t, x->parent);
                w = x->parent->left;
            }
            if (w->left->color == black && w->right->color == black)
            {
                w->color = red;
                x = x->parent;
            }
            else if (w->left->color == black)
            {
                w->right->color = black;
                w->color = red;
                left_rotate(t, w);
                w = x->parent->right;
            }
            w->color = x->parent->color;
            x->parent->color = black;
            w->left->color = black;
            right_rotate(t, x->parent);
            x = t;                                            //

        }
    }
    x->color = black;
}

node* rb_delete(tree &t, node *z)
{
    node *y, *x;
    node *m = nil;
    node* n = z;
    node *xxx = z->parent;
    if (z->left == nil || z->right == nil)
    {
        while (xxx != nil)
        {

            xxx->size--;
            xxx=xxx->parent;
        }
        y = z;
    }
    else
    {
        y = successor(n);
        xxx = y->parent;
        while (xxx != nil)
        {

            xxx->size--;
            xxx = xxx->parent;
        }
                                     //这一行使z的右孩子发生变化
    }
    if (y->left != nil)
        x = y->left;
    else
        x = y->right;
    x->parent = y->parent;
    if (y->parent == nil)
        t = x;                            //
    else
    {
        if (y == y->parent->left)
            y->parent->left = x;
        else
            y->parent->right = x;
    }
    if (y != z)
    {
        z->key = (y->key);

    }
    if (y->color == black)
        rb_delete_fixup(t, x);
    return t;
}

node* rb_delete_(tree &t, type k)
{
    node *z;
    z = search(t, k);

    if (z != nil)
    {
        t = rb_delete(t, z);
    }
    else
        printf("无此元素");
    return t;
}


void print_tree(tree &t)                        //中序遍历打印
{
    if (t != nil && t != NULL)
    {

        print_tree(t->left);
        printf("%7d ,   %5d\n, size= %5d\n ", t->key, t->color,t->size);
        print_tree(t->right);
    }
}

int main()
{
    int i;
    tree zz = NULL, mm = NULL, nn = NULL, xx = NULL, yy = NULL;
    type k;
    int a[12] = { 3,12,15,17,19,55,20,18,36,48,31,29 };
    printf("\n原来的数字是:----------------------------------------\n");
    for (i = 0; i<12; i++)
    {
        printf("%d  ", a[i]);
        zz = rb_insert_(zz, a[i]);
    }

    printf("\n中序遍历是:-------------------------------------------\n");
    printf("规定:red=0,black=1\n");
    print_tree(zz);

    printf("要查询第几小的元素:------------------------------------\n");
    scanf_s("%d", &k);
    printf("%d\n",os_select_(zz, k)->key);                                                    
    printf("要查询哪个元素的秩:-----------------------------------\n");
    scanf_s("%d", &k);
    printf("%d\n", os_rank_(search(zz,k),zz, k));                                          //递归

    printf("\n要删除的值是:---------------------------------------");
    scanf_s("%d", &k);
    yy = rb_delete_(zz, k);
    print_tree(yy);
    printf("\n要插入的值是:--------------------------------------");
    scanf_s("%d", &k);
    rb_insert_(zz, k);
    print_tree(zz);
}

猜你喜欢

转载自blog.csdn.net/alike_meng/article/details/82429594