Esempio n. 1
0
    def partition(numbers, pivot):
        '''The original partition scheme described by C.A.R. Hoare 
		uses two indices that start at the ends of the array being 
		partitioned, then move toward each other, until they detect 
		an inversion: a pair of elements, one greater than or equal 
		to the pivot, one lesser or equal, that are in the wrong 
		order relative to each other. The inverted elements are 
		then swapped'''

        left = DoubleLinkedList()
        right = DoubleLinkedList()

        numbers.detach_node(pivot)

        i = numbers.begin
        j = numbers.end

        while True:
            while i.value <= pivot.value:
                if i == numbers.end:
                    break
                i = i.next

            while j.value >= pivot.value:
                if j == numbers.begin:
                    break
                j = j.prev

        #Trying to avoid having to tack on index numbers to my
        #double linked lists. Using a "position()" function to
        #calculate the position instead

            if sorting.position(numbers, i) < sorting.position(numbers, j):
                i.value, j.value = j.value, i.value
            else:
                if i.value > pivot.value:
                    split = sorting.position(numbers, i) - 1
                else:
                    split = sorting.position(numbers, i)

                while numbers.count() > 0:
                    if split > 0:
                        #print("split=",split,"num=",numbers.begin)
                        left.push(numbers.unshift())
                        split -= 1
                    else:
                        #print("split=",split,"num=",numbers.begin)
                        right.push(numbers.unshift())
                break

        return left, right
Esempio n. 2
0
    def merge(left, right):
        '''	   
		function merge(left, right)
		    var result := empty list

		    while left is not empty and right is not empty do
		        if first(left) <= first(right) then
		            append first(left) to result
		            left := rest(left)
		        else
		            append first(right) to result
		            right := rest(right)

		    while left is not empty do
		        append first(left) to result
		        left := rest(left)
		    while right is not empty do
		        append first(right) to result
		    right := rest(right)
		return result
		'''
        result = DoubleLinkedList()
        while left.count() > 0 and right.count() > 0:
            if left.begin.value <= right.begin.value:
                result.push(left.unshift())
            else:
                result.push(right.unshift())
        while left.count() > 0:
            result.push(left.unshift())
        while right.count() > 0:
            result.push(right.unshift())
        return result
Esempio n. 3
0
    def quick_sort(numbers):
        if numbers.count() <= 1:
            return numbers
        result = DoubleLinkedList()

        #There are many different strategies for picking a pivot
        #This allows for flexibility in defining the pivot
        pivotIndex = randint(1, numbers.count())
        index = 1
        pivot = numbers.begin
        while index != pivotIndex:
            pivot = pivot.next
            index += 1

        #Now send the list to partition() and get back two lists,
        #one that contains values less than, and one that has
        #values greater than the pivot
        left, right = sorting.partition(numbers, pivot)

        #Prepend the sorted left side to the pivot and append the
        #sorted right side
        sorting.quick_sort(left)
        while left.count() > 0:
            result.push(left.unshift())
        result.push(pivot)
        sorting.quick_sort(right)
        while right.count() > 0:
            result.push(right.unshift())
        return result
Esempio n. 4
0
def homogenous_list():
    numbers = DoubleLinkedList()
    numbers.push(1)
    numbers.push(1)
    numbers.push(1)
    numbers.push(1)
    numbers.push(1)
    return numbers
Esempio n. 5
0
def presorted_list():
    numbers = DoubleLinkedList()
    numbers.push(1)
    numbers.push(2)
    numbers.push(3)
    numbers.push(4)
    numbers.push(5)
    return numbers
Esempio n. 6
0
    def merge_sort(numbers):
        '''
		Pseudocode from wikipedia:
		function merge_sort(list m)
		    if length of m <= 1 then
				return m

		    var left := empty list
		    var right := empty list
		    for each x with index i in m do
		        if i < (length of m)/2 then
		            add x to left
		        else
		            add x to right

		    left := merge_sort(left)
		    right := merge_sort(right)

		    return merge(left, right)
		   '''
        if numbers.count() <= 1:
            return numbers

        left = DoubleLinkedList()
        right = DoubleLinkedList()
        split = numbers.count() / 2
        while numbers.count() > 0:
            if split > 0:
                left.push(numbers.unshift())
                split -= 1
            else:
                right.push(numbers.unshift())

        left = sorting.merge_sort(left)
        right = sorting.merge_sort(right)

        return sorting.merge(left, right)
Esempio n. 7
0
class Dictionary(object):
    '''
	Transcription of Zed's prototype dictionary class
	Terms: 
	bucket = a list within the Map list that contains key value pairs
	slot = a key value pair within a bucket
	node = any generic node within a DoubleLinkedList
	'''
    def __init__(self, num_buckets=256):
        '''Initialize a map with num_buckets number of buckets.
		Basically a list of lists'''
        self.map = DoubleLinkedList()
        for i in range(0, num_buckets):
            self.map.push(DoubleLinkedList())

    def hash_key(self, key):
        '''Take a key and create a number, then convert it to 
		an index for the Map's buckets.
		Basically creates a randomized index for each key'''
        return hash(key) % self.map.count()

    def get_bucket(self, key):
        '''Given a key, find the bucket where it lives'''
        bucket_id = self.hash_key(key)
        print("get_bucket() calling get() on", self.map, "with", bucket_id)
        return self.map.get(bucket_id)

    def get_slot(self, key, default=None):
        '''return the bucket and node (key,value) for a given key
		Hmmm, the 'default' parameter never gets used'''

        print("get_slot() calling get_bucket() with", self, key)
        bucket = self.get_bucket(key)

        if bucket:
            node = bucket.begin
            #Not sure why an index is needed, since it's never
            #used later
            i = 0

            while node:
                if key == node.value[0]:
                    return bucket, node
                else:
                    node = node.next
                    i += 1

        return bucket, None

    def get(self, key, default=None):
        '''Take a key and get the its full slot and value, or the default
		Hmmmm, Zed's code ends with "or node" which doesn't make
		sense to me. Changed to "or default"'''
        print("get() calling get_slot() with", self, key)
        bucket, node = self.get_slot(key, default=default)
        return node and node.value[1] or default

    def set(self, key, value):
        '''Set a key to the given value, replacing any old values'''
        bucket, slot = self.get_slot(key)

        if slot:
            '''key already exists, replace it'''
            '''Why does Zed use python builtin lists here, rather than the
			DoubleLinkedLists we've been using?'''
            slot.value = (key, value)
        else:
            bucket.push((key, value))

    def delete(self, key):
        '''Deletes a given key from the map'''
        bucket = self.get_bucket(key)
        node = bucket.begin

        while node:
            k, v = node.value
            if key == k:
                bucket.detach_node(node)
                break

    def list(self):
        '''Prints out the map'''
        bucket_node = self.map.begin
        while bucket_node:
            slot_node = bucket_node.value.begin
            while slot_node:
                print(slot_node.value)
                slot_node = slot_node.next
            bucket_node = bucket_node.next
Esempio n. 8
0
def homogenous_list(count):
    numbers = DoubleLinkedList()
    for i in range(1, count + 1):
        numbers.push(1)
    return numbers
Esempio n. 9
0
def presorted_list(count):
    numbers = DoubleLinkedList()
    for i in range(1, count + 1):
        numbers.push(i)
    return numbers