コード例 #1
0
//returns the total number of collided cells
int add_block_1_axis(rb_red_blk_tree *tree, int x1, int y1, int x2, int y2, unsigned int type, int add_amount) {
  circ_tree_node *node_begin, *node_end;
  node_end = get_node(tree, x2, type)->key;  //the end strictly needs to be called before the beginning
  node_begin = get_node(tree, x1, type)->key;
  stk_stack *axis_range = RBEnumerate(tree, node_begin, node_end);

  rb_red_blk_node *rb_node, *rb_node_prev = NULL;
  int temp_collision = 0, collision = 0, prev_pos;

  for (;;) {
    //rb_node_prev = rb_node;
    rb_node = (rb_red_blk_node *) StackPop(axis_range);

    //if (rb_node_prev == NULL)
      rb_node_prev = TreePredecessor(tree, rb_node);
    
    circ_tree_node *node = (circ_tree_node *) rb_node->key;
    circ_tree_node *node_prev;

    if (rb_node_prev == NULL || rb_node_prev == tree->nil)
      node_prev = NULL;
    else
      node_prev = (circ_tree_node *) rb_node_prev->key;

    unsigned int stack_not_empty = StackNotEmpty(axis_range);

    //collision
    if (temp_collision) 
      //if temp collision is non-zero, by definition, node_prev
      //cannot be NULL
      collision += temp_collision * (node->pos - prev_pos);

    prev_pos = node->pos;

    if (type == TOP_LEVEL) {
      if (stack_not_empty) 
	temp_collision = add_block_1_axis(node->data.tree, y1, 0, y2, 0, SECOND_LEVEL, add_amount);
      if ((node_prev != NULL && 
	   !RBTreeCompare(node->data.tree, node_prev->data.tree, 
			  circ_node_equals)) ||
	  (node_prev == NULL && RBIsTreeEmpty(node->data.tree)))
	RBDelete(tree, rb_node);
      
    } else {
      if (stack_not_empty) {
	if (node->data.state > 0 && node->data.state > -add_amount) 
	  //if there is already a block here, and if there would still 
	  //be a block left, assess collision
	  temp_collision = add_amount;
	else
	  temp_collision = 0;
	node->data.state += add_amount;
      }

      //if both nodes are the same
      if ((node_prev != NULL && node_prev->data.state == node->data.state) ||
	  //or the previous node is null and this is zero
	  (node_prev == NULL && node->data.state == 0)) {
	RBDelete(tree, rb_node);
      }
    }

    if (!stack_not_empty)
      break;
  }
  StackDestroy(axis_range, dummy_fun);

  return collision;
}
コード例 #2
0
//prints x by x view of the tree
//assumes the grid starts from 0, 0; if there are entries less
//than that, it will be ignored, possibly to yield weird results
void print_tree(circ_tree *c_tree, int x, unsigned int print_mode) {
  rb_red_blk_tree *tree = c_tree->main_tree;
  static int static_x = 0;
  static circ_tree_node query_node_low, query_node_high;
  static char *line, *header_line;
  if (static_x != x) {
    if (line != NULL)
      free(line);
    if (header_line != NULL)
      free(header_line);

    static_x = x;
    query_node_low.pos = 0; //start node
    query_node_high.pos = x;
    int size = sizeof(char) * (x + 3);
    line = (char *) malloc(size);
    header_line = (char *) malloc(size);

    header_line[0] = ' ';
    header_line[1] = ' ';
    int i;
    for (i = 0; i < x; i++)
      header_line[2 + i] = '0' + (i % 10);
    header_line[x + 2] = '\0';

  }
  line[1] = ' ';
  memset(line + 2, print_mode == PRINT_CELLS ? '0' : ' ', x);  //initial line is all zeros
  line[x + 2] = '\0';  //null char at the end 
  stk_stack *stack = RBEnumerate(tree, &query_node_low, &query_node_high);
  int line_n = 0;
  puts(header_line);

  int cont_print = 1;

  while (cont_print) {

    int node_pos;
    rb_red_blk_tree *node_tree;    
    if (cont_print = StackNotEmpty(stack)) {
      circ_tree_node *node = ((rb_red_blk_node *) StackPop(stack))->key;
      node_pos = node->pos;
      node_tree = node->data.tree;
    } else {
      node_pos = x;
      node_tree = c_tree->y_bound_tree;
    }

    for (; line_n < node_pos; line_n++) {  
      //print the lines until this point / rest of the lines
      line[0] = '0' + (line_n % 10);
      puts(line);
    }

    //set the new line
    stk_stack *stack2 = RBEnumerate(node_tree, &query_node_low, &query_node_high);
    char c = print_mode == PRINT_CELLS ? '0' : ' ';
    int row_n = 0;
    while (StackNotEmpty(stack2)) {
      circ_tree_node *node2 = ((rb_red_blk_node *) StackPop(stack2))->key;
      for (; row_n < node2->pos; row_n++)  //print the chars until this point
	line[row_n + 2] = c;
      if (print_mode == PRINT_CELLS)
	c = '0' + node2->data.state;
      else
	line[row_n++ + 2] = '0' + node2->data.state;
    }

    if (print_mode == PRINT_NODES && row_n == 0)
      line[1] = '0';


    for (; row_n < x; row_n++)  //print the rest of the chars
      line[row_n + 2] = c;
    free(stack2);

    if (print_mode == PRINT_NODES || !cont_print) {
      if (cont_print)
	line[0] = '0' + (line_n++ % 10);
      else 
	line[0] = '>';  //print a different indicator for the boundary tree
      puts(line);
      memset(line + 1, ' ', x + 1);
    }
  }
  
  free(stack);
}
コード例 #3
0
int main() {
  stk_stack* enumResult;
  int option=0;
  int newKey,newKey2;
  int* newInt;
  rb_red_blk_node* newNode;
  rb_red_blk_tree* tree;

  tree=RBTreeCreate(IntComp,IntDest,InfoDest,IntPrint,InfoPrint);
  while(option!=8) {
    printf("choose one of the following:\n");
    printf("(1) add to tree\n(2) delete from tree\n(3) query\n");
    printf("(4) find predecessor\n(5) find sucessor\n(6) enumerate\n");
    printf("(7) print tree\n(8) quit\n");
    do option=fgetc(stdin); while(-1 != option && isspace(option));
    option-='0';
    switch(option)
      {
      case 1:
	{
	  printf("type key for new node\n");
	  scanf("%i",&newKey);
	  newInt=(int*) malloc(sizeof(int));
	  *newInt=newKey;
	  RBTreeInsert(tree,newInt,0);
	}
	break;
	
      case 2:
	{
	  printf("type key of node to remove\n");
	  scanf("%i",&newKey);
	  if ( ( newNode=RBExactQuery(tree,&newKey ) ) ) RBDelete(tree,newNode);/*assignment*/
	  else printf("key not found in tree, no action taken\n");
	}
	break;

      case 3:
	{
	  printf("type key of node to query for\n");
	  scanf("%i",&newKey);
	  if ( ( newNode = RBExactQuery(tree,&newKey) ) ) {/*assignment*/
	    printf("data found in tree at location %i\n",(int)newNode);
	  } else {
	    printf("data not in tree\n");
	  }
	}
	break;
      case 4:
	{
	  printf("type key of node to find predecessor of\n");
	  scanf("%i",&newKey);
	  if ( ( newNode = RBExactQuery(tree,&newKey) ) ) {/*assignment*/
	    newNode=TreePredecessor(tree,newNode);
	    if(tree->nil == newNode) {
	      printf("there is no predecessor for that node (it is a minimum)\n");
	    } else {
	      printf("predecessor has key %i\n",*(int*)newNode->key);
	    }
	  } else {
	    printf("data not in tree\n");
	  }
	}
	break;
      case 5:
	{
	  printf("type key of node to find successor of\n");
	  scanf("%i",&newKey);
	  if ( (newNode = RBExactQuery(tree,&newKey) ) ) {
	    newNode=TreeSuccessor(tree,newNode);
	    if(tree->nil == newNode) {
	      printf("there is no successor for that node (it is a maximum)\n");
	    } else {
	      printf("successor has key %i\n",*(int*)newNode->key);
	    }
	  } else {
	    printf("data not in tree\n");
	  }
	}
	break;
      case 6:
	{
	  printf("type low and high keys to see all keys between them\n");
	  scanf("%i %i",&newKey,&newKey2);
	  enumResult=RBEnumerate(tree,&newKey,&newKey2);	  
	  while ( (newNode = StackPop(enumResult)) ) {
	    tree->PrintKey(newNode->key);
	    printf("\n");
	  }
	  free(enumResult);
	}
	break;
      case 7:
	{
	  RBTreePrint(tree);
	}
	break;
      case 8:
	{
	  RBTreeDestroy(tree);
	  return 0;
	}
	break;
      default:
	printf("Invalid input; Please try again.\n");
      }
  }
  return 0;
}