#!python
import random
class llist:
#inits the new linked list node with data
def __init__(self, data):
self.data = data
self.next = None
#links a new node to the current one (destructive if one exists already)
def append(self, node):
self.next = node
return self.next
#works out the length of the list from current node
def length(self):
length = 1
node = self
while node.next:
node = node.next
length += 1
return length
#cut the current list after 'length' nodes, return the cut off list
def cut(self,length):
node = self
while length > 1 and node.next:
node = node.next
length -= 1
next = node.next
node.next = None
return next
#compare with another list, return both lists as a tuple, ordered by data in the head nodes of each
def order(self, other):
if not other: return (self, None)
return (self, other) if other.data > self.data else (other, self)
#print list data
def print_list(self, prepend = ''):
node = self
while node:
print (prepend + str(node.data))
node = node.next
def mergesort(unsorted):
#dummy start node
start = llist(None)
start.append(unsorted)
list_length = unsorted.length()
sublist_length = 1
while sublist_length < list_length:
last = start
sub_a = start.next
while sub_a:
sub_b = sub_a.cut(sublist_length)
end = sub_b.cut(sublist_length) if sub_b else None
while sub_a:
sub_a, sub_b = sub_a.order(sub_b)
node = sub_a
sub_a = sub_a.cut(1)
last = last.append(node)
if not sub_a:
sub_a, sub_b = sub_b, None
sub_a = end
sublist_length *=2
return start.next
#create a list with a length that doesn't match 2^n to show that it handles it fine
#create a dummy node to begin the list
start = llist(None)
end = start
for i in range(16):
end = end.append(llist(random.randint(0, 50)))
unsorted = start.next
print ('unsorted:')
unsorted.print_list()
sorted = mergesort(unsorted)
print('sorted:')
sorted.print_list()
IyFweXRob24KaW1wb3J0IHJhbmRvbQoKY2xhc3MgbGxpc3Q6CgkjaW5pdHMgdGhlIG5ldyBsaW5rZWQgbGlzdCBub2RlIHdpdGggZGF0YQoJZGVmIF9faW5pdF9fKHNlbGYsIGRhdGEpOgoJCXNlbGYuZGF0YSA9IGRhdGEKCQlzZWxmLm5leHQgPSBOb25lCgkjbGlua3MgYSBuZXcgbm9kZSB0byB0aGUgY3VycmVudCBvbmUgKGRlc3RydWN0aXZlIGlmIG9uZSBleGlzdHMgYWxyZWFkeSkKCWRlZiBhcHBlbmQoc2VsZiwgbm9kZSk6CgkJc2VsZi5uZXh0ID0gbm9kZQoJCXJldHVybiBzZWxmLm5leHQKCSN3b3JrcyBvdXQgdGhlIGxlbmd0aCBvZiB0aGUgbGlzdCBmcm9tIGN1cnJlbnQgbm9kZQoJZGVmIGxlbmd0aChzZWxmKToKCQlsZW5ndGggPSAxCgkJbm9kZSA9IHNlbGYKCQl3aGlsZSBub2RlLm5leHQ6CgkJCW5vZGUgPSBub2RlLm5leHQKCQkJbGVuZ3RoICs9IDEKCQlyZXR1cm4gbGVuZ3RoCgkjY3V0IHRoZSBjdXJyZW50IGxpc3QgYWZ0ZXIgJ2xlbmd0aCcgbm9kZXMsIHJldHVybiB0aGUgY3V0IG9mZiBsaXN0CglkZWYgY3V0KHNlbGYsbGVuZ3RoKToKCQlub2RlID0gc2VsZgoJCXdoaWxlIGxlbmd0aCA+IDEgYW5kIG5vZGUubmV4dDoKCQkJbm9kZSA9IG5vZGUubmV4dAoJCQlsZW5ndGggLT0gMQoJCW5leHQgPSBub2RlLm5leHQKCQlub2RlLm5leHQgPSBOb25lCgkJcmV0dXJuIG5leHQKCSNjb21wYXJlIHdpdGggYW5vdGhlciBsaXN0LCByZXR1cm4gYm90aCBsaXN0cyBhcyBhIHR1cGxlLCBvcmRlcmVkIGJ5IGRhdGEgaW4gdGhlIGhlYWQgbm9kZXMgb2YgZWFjaAoJZGVmIG9yZGVyKHNlbGYsIG90aGVyKToKCQlpZiBub3Qgb3RoZXI6IHJldHVybiAoc2VsZiwgTm9uZSkKCQlyZXR1cm4gKHNlbGYsIG90aGVyKSBpZiBvdGhlci5kYXRhID4gc2VsZi5kYXRhIGVsc2UgKG90aGVyLCBzZWxmKQoJI3ByaW50IGxpc3QgZGF0YQoJZGVmIHByaW50X2xpc3Qoc2VsZiwgcHJlcGVuZCA9ICcnKToKCQlub2RlID0gc2VsZgoJCXdoaWxlIG5vZGU6CgkJCXByaW50IChwcmVwZW5kICsgc3RyKG5vZGUuZGF0YSkpCgkJCW5vZGUgPSBub2RlLm5leHQKCQkKZGVmIG1lcmdlc29ydCh1bnNvcnRlZCk6CiAgI2R1bW15IHN0YXJ0IG5vZGUKCXN0YXJ0ID0gbGxpc3QoTm9uZSkKCXN0YXJ0LmFwcGVuZCh1bnNvcnRlZCkKCWxpc3RfbGVuZ3RoID0gdW5zb3J0ZWQubGVuZ3RoKCkKCXN1Ymxpc3RfbGVuZ3RoID0gMQoJd2hpbGUgc3VibGlzdF9sZW5ndGggPCBsaXN0X2xlbmd0aDoKCQlsYXN0ICA9IHN0YXJ0CgkJc3ViX2EgPSBzdGFydC5uZXh0CgkJd2hpbGUgc3ViX2E6CgkJCXN1Yl9iID0gc3ViX2EuY3V0KHN1Ymxpc3RfbGVuZ3RoKQoJCQllbmQgICA9IHN1Yl9iLmN1dChzdWJsaXN0X2xlbmd0aCkgaWYgc3ViX2IgZWxzZSBOb25lCgkJCXdoaWxlIHN1Yl9hOgoJCQkJc3ViX2EsIHN1Yl9iID0gc3ViX2Eub3JkZXIoc3ViX2IpCgkJCQlub2RlID0gc3ViX2EKCQkJCXN1Yl9hID0gc3ViX2EuY3V0KDEpCgkJCQlsYXN0ID0gbGFzdC5hcHBlbmQobm9kZSkKCQkJCWlmIG5vdCBzdWJfYToKCQkJCSAgc3ViX2EsIHN1Yl9iID0gc3ViX2IsIE5vbmUKCQkJc3ViX2EgPSBlbmQKCQlzdWJsaXN0X2xlbmd0aCAqPTIKCXJldHVybiBzdGFydC5uZXh0CgojY3JlYXRlIGEgbGlzdCB3aXRoIGEgbGVuZ3RoIHRoYXQgZG9lc24ndCBtYXRjaCAyXm4gdG8gc2hvdyB0aGF0IGl0IGhhbmRsZXMgaXQgZmluZQojY3JlYXRlIGEgZHVtbXkgbm9kZSB0byBiZWdpbiB0aGUgbGlzdApzdGFydCA9IGxsaXN0KE5vbmUpCmVuZCA9IHN0YXJ0CmZvciBpIGluIHJhbmdlKDE2KToKCWVuZCA9IGVuZC5hcHBlbmQobGxpc3QocmFuZG9tLnJhbmRpbnQoMCwgNTApKSkKdW5zb3J0ZWQgPSBzdGFydC5uZXh0CnByaW50ICgndW5zb3J0ZWQ6JykKdW5zb3J0ZWQucHJpbnRfbGlzdCgpCnNvcnRlZCA9IG1lcmdlc29ydCh1bnNvcnRlZCkKcHJpbnQoJ3NvcnRlZDonKQpzb3J0ZWQucHJpbnRfbGlzdCgp