Пример #1
0
int Repository_update(int key, int data) {
	
	// A variable the loops through the list
	element *temp_pointer;
	
	// A variable that will hold the new element in the list
	element *pelement;
	
	// When adding a new variable, will hold what level the variable was added to
	int curr_level = 0;
	
	// Temp variable to use with the pop() function
	int r;
	
	// Will hold a pointer to the val of the very bottom row since there should only be 
	// one copy of data per column in the skip list
	int *val_ptr;
	
	// Holds a pointer down so each subsequent layer in the skip list point to the element below it
	element *down_ptr;
	
	
	// Initializes the looping variable to the very top sentinel node
	temp_pointer = top_ptr;
	
	// This will serve as a sentinel node for the new level
	element *new_head;
	
	
	// Loops through the list
	while(temp_pointer!= NULL){
		// Loop through each level until the end of the list or a key greater than
		// the key being searched for is found
		
		while(temp_pointer->next != NULL && key >= (temp_pointer->next)->key){
			// If the key is found, update its associated value and return 0
			if((temp_pointer->next)->key == key){
				*((temp_pointer->next)->val) = data;
				return 0;
			}
			// Make temp_pointer equal to the next element in the level
			temp_pointer = temp_pointer -> next;
			steps++;
		}
		// Hold the value of the element before the one greater than the key in a stack.
		// If there is not an element with a key hreater than the key being searched for,
		// the last element in the level is saved. 
		// This can then be used to add the new element to the super list
		
		r = push(temp_pointer);
		if( r == 0) return -1;
		
		// Go down one level when a value greater than the one being searched for is found, then
		// search for a value equal to or greater than the key
		temp_pointer = temp_pointer->down;
		steps++;
	}
	
	// This block of code runs if the key is not found in the bottom level
	
	r = pop(&temp_pointer);
	pelement = malloc(sizeof(element));
	if( pelement == NULL) return -1;
	pelement->val = malloc(sizeof(int));
	*(pelement->val) = data;
	
	// Save a pointer to the value associated with the key
	val_ptr = pelement->val;
	
	pelement->key = key;
	pelement->down = NULL;
	
	// Save a pointer to the element being added. The element on the next row up
	// can use this pointer
	down_ptr = pelement;
	
	pelement->next = temp_pointer->next;
	steps++;
	temp_pointer->next = pelement;
	steps++;
	
	// Increase the size of the bottom level in the array of level sizes
	size[curr_level]++;
	
	// We are now done working with the bottom level, so the curr_level value is iterated
	curr_level++;
	
	// This loop runs while rand100() produces a value greater than the previously specified percent
	// Every time this is true, an element is added one level up
	while(rand100() <= percent){
		// Runs if the level being added to exists already
		if(curr_level <= level){
			// Set temp_pointer equal to the last saved item
			// The new element is added after this item
			r = pop(&temp_pointer);
			
			pelement = malloc(sizeof(element));
			if( pelement == NULL) return -1;
			pelement->val = val_ptr;
			pelement->key = key;
			pelement->down = down_ptr;
			steps++;
			pelement->next = temp_pointer->next;
			steps++;
			temp_pointer->next = pelement;
			steps++;
			
			// Pelement will then be the last added element, so the next one should point
			// down to it
			down_ptr = pelement;
			size[curr_level]++;
			curr_level++;
		}
		else{
			// Creates space for the new sentinel node
			new_head = malloc(sizeof(element));
			
			// Creates the new element to be added
			pelement = malloc(sizeof(element));
			pelement->val = val_ptr;
			pelement->key = key;
			pelement->down = down_ptr;
			steps++;
			pelement->next = NULL;
			new_head->next = pelement;
			new_head->val = malloc(sizeof(int));
			
			// Point this sentinel node towards the last sentinel node
			new_head->down = top_ptr;
			steps++;
			
			// Change top_ptr to point to the new sentinel node
			top_ptr = new_head;
			size[curr_level]++;
			down_ptr = pelement;
			
			// Increment this since a new level has been added
			level++;
			curr_level++;
		}
	}
	r = 1;
	
	// Make sure there is nothing left in the stack at the end of the function
	while(r != 0) r = pop(&temp_pointer);
	return 1;
}
/*Updates the data if the key is found. If not, insert new record and roll to see how many "layers" needed for this new record*/
int Repository_update(int key, int data)        
{                                               
    record *tempList = ListHead;                /*tempList is used to traverse data structure*/
    record *tempPointer = NULL;                 /*tempPointer points to the previous inserted record*/
    record *temp_record;                        /*record to be added*/
    
    record *newListHead;                        /*newListHead is a temp ListHead if we need to create a new lvl*/
    record *level_save[levels];                 /*level_save is an array of pointers that mark where we stopped on prev lvl*/
    int *data_pointer;                          /*data_pointer creates a pointer to data, so easy to manipulate across all lvls*/
    int x = 0;                                  /*x keeps track of where in array to access*/

    while(tempList != NULL)/*Checks by level for the record to insert after*/
    {
        while(tempList->next != NULL && tempList->next->key <= key)
        {
            if(tempList->next->key == key)
                {
                    *tempList->next->data = data;
                    return 0; /*data updated*/
                }
            tempList = tempList->next;
            next_count++;
        }
        level_save[x] = tempList;/*stores the record where it stopped and went down*/
        x++;
        tempList = tempList->down;
        next_count++;
    record *tempHead2 = ListHead;
    }
    /*Now that we have all the points of insertion, add them in*/
    /*If we reach this point, it means we need to insert*/
    data_pointer = malloc(sizeof(int));
    if(data_pointer == NULL) return -1;
    *data_pointer = data;

    do
    {
        temp_record = malloc(sizeof(record));
        if(temp_record == NULL) return -1;
        temp_record->key = key;
        temp_record->data = data_pointer;
        temp_record->down = tempPointer;
        if(x >= 1)
            {
                temp_record->next = level_save[x-1]->next;
                level_save[x-1]->next = temp_record;
                level_save[x-1] = NULL;
                x--;        
            }
        else if( x < 1)/*Creates new level if probability is "rolled"*/
        {
            temp_record->next  = NULL;
            newListHead = malloc(sizeof(record));
            if(newListHead == NULL) return -1;
            newListHead->down = ListHead;
            newListHead->next = temp_record;
            ListHead = newListHead;
            next_count = next_count + 3;
            levels++;
        }
        tempPointer = temp_record;
    }while(rand100() <= probability && levels <= MAX_LEVELS);
    
    return 1;/*successful insert*/
}