Cod sursa(job #1747957)

Utilizator dementorrDementhor dementorr Data 25 august 2016 20:49:47
Problema Hashuri Scor 20
Compilator c Status done
Runda Arhiva educationala Marime 5.36 kb
#include <stdio.h>
#include <stdlib.h>

typedef int key_t;

typedef struct tr_n_t {
  key_t key;
  
  struct tr_n_t *left;
  struct tr_n_t *right;
  struct tr_n_t *parent;
} tree_node_t;

typedef struct {
  tree_node_t * root;
} splay_tree;

tree_node_t * find_largest (splay_tree *tree) {
  tree_node_t *current_node = tree->root;
  while (current_node->right != NULL)
    current_node = current_node->right;

  return current_node;
}

void rotate_right (tree_node_t *node) {
  if (node->left == NULL)
    return;

  tree_node_t *left = node->left;
  
  key_t node_key = node->key;
  node->key = left->key;
  left->key = node_key;

  node->left = left->left;
  if (node->left)
    node->left->parent = node;

  left->left = left->right;
  
  left->right = node->right;
  if (node->right)
    node->right->parent = left;

  node->right = left;
}

void rotate_left (tree_node_t *node) {
  if (node->right == NULL)
    return;

  tree_node_t *right = node->right;
  
  key_t node_key = node->key;
  node->key = right->key;
  right->key = node_key;

  node->right = right->right;
  if (node->right)
    node->right->parent = node;

  right->right = right->left;
  
  right->left = node->left;
  if (node->left)
    node->left->parent = right;

  node->left = right;
}

void inord (FILE *out, tree_node_t *node) {
  if (node == NULL)
    return;

  inord (out, node->left);
  fprintf (out, "%d ", node->key);
  inord (out, node->right);
}

void splay (tree_node_t *node) {
  tree_node_t *parent = node->parent;

  if (parent == NULL) {
    return;
  }

  tree_node_t *grand_parent = parent->parent;

  // Zig-case
  if (grand_parent == NULL) {
    if (parent->left == node) {
      rotate_right (parent);
    } else {
      rotate_left (parent);
    }

    return;
  }

  if (grand_parent->left == parent) {
    if (parent->left == node) {
      // Zig-Zig
      rotate_left (parent);
      rotate_left (grand_parent);
    } else {
      // Zig-Zag
      rotate_right (parent);
      rotate_left (grand_parent);
    }
  } else {
    if (parent->left == node) {
      // Zig-Zag
      rotate_right (parent);
      rotate_left (grand_parent);
    } else {
      // Zig-Zig
      rotate_right (parent);
      rotate_right (grand_parent);
    }
  }

  splay(grand_parent);
}

splay_tree * create_tree (void) {
  splay_tree *tree = (splay_tree *) malloc (sizeof (splay_tree));
  tree->root = NULL;
  return tree;
}

splay_tree * join (splay_tree *first, splay_tree *second) {
  if (first->root == NULL)
    return second;

  if (second->root == NULL)
    return first;
  
  tree_node_t *largest_first = find_largest (first);
  splay (largest_first);

  largest_first->right = second->root;

  //if (second->root != NULL)
  second->root->parent = largest_first;

  return first;
}

int insert (splay_tree *tree, key_t new_key) {
  if (tree->root == NULL) {
    tree_node_t *root = (tree_node_t *) malloc (sizeof (tree_node_t));
    root->left = NULL;
    root->right = NULL;
    root->parent = NULL;
    
    root->key = new_key;          
    tree->root = root;
    return 0;
  }

  tree_node_t *current_node, *previous_node;
  
  current_node = tree->root;
  while (current_node != NULL) {
    previous_node = current_node;
    
    if (new_key < current_node->key)
      current_node = current_node->left;
    else if (new_key > current_node->key)
      current_node = current_node->right;
    else {
      splay (current_node);
      return 0;
    }
  }

  tree_node_t *new = (tree_node_t *) malloc (sizeof (tree_node_t));
  new->left = NULL;
  new->right = NULL;
  new->parent = previous_node;
  new->key = new_key;
  
  if (new_key < previous_node->key) {
    previous_node->left = new;
  } else {
    previous_node->right = new;
  }

  splay (new);
  return 0;
}

tree_node_t* find (splay_tree *tree, key_t query_key ) {
  if (tree->root == NULL)
    return NULL;

  tree_node_t *current_node, *previous_node;
  
  current_node = tree->root;
  while (current_node != NULL) {
    previous_node = current_node;

    if (query_key < current_node->key)
      current_node = current_node->left;
    else if (query_key > current_node->key)
      current_node = current_node->right;
    else {
      splay (current_node);
      return current_node;
    }
  }

  splay (previous_node);
  return NULL;
}

tree_node_t* delete (splay_tree **tree, key_t delete_key) {
  tree_node_t *deleted_node = find(*tree, delete_key);

  if (deleted_node == NULL)
    return NULL;
  else {
    splay (deleted_node);

    splay_tree *first, *second;
    first = create_tree ();
    second = create_tree ();

    if (deleted_node->left) {
      deleted_node->left->parent = NULL;
      first->root = deleted_node->left;
    }

    if (deleted_node->right) {
      deleted_node->right->parent = NULL;
      second->root = deleted_node->right;
    }

    splay_tree *new = join (first, second);
    *tree = new;
    
    return deleted_node;
  }
}

int main () {
  int n;

  FILE *in = fopen ("hashuri.in", "r");
  FILE *out = fopen ("hashuri.out", "w");
  
  fscanf (in, "%d\n", &n);

  splay_tree *tree = create_tree ();
  
  int i;
  for (i = 0; i < n; ++i) {
    int t, x;
    fscanf (in, "%d %d\n", &t, &x);

    if (t == 1)   
      insert (tree, x);
    else if (t == 2)
      delete (&tree, x);
    else if (t == 3) {
      tree_node_t *found = find (tree, x);
      if (found != NULL)
	fprintf (out, "1\n");
      else
	fprintf (out, "0\n");
    }      
  }

  fclose (in);
  fclose (out);
  
  return 0;
}