944,123 Members | Top Members by Rank

Ad:
  • Python Discussion Thread
  • Marked Solved
  • Views: 25621
  • Python RSS
Nov 27th, 2005
0

Sorting in Python

Expand Post »
Hello people of Python community,
I'm back with (so far) strong will to learn Python, just like you.
I remember once, Narue told me that good way to learn different prog. languages
is to concetrate on algorithms and data structures and their implementation in
language of choice. That way, she said, one can learn both algorithms and data structrues
which are language independent but also at the same time can learn the programming language.
I tried to follow her advice and by reading her tutorials, I manage to implement most of sorting
algorithms in C. Also, I didn't have tough time with BST and linked lists. And yesterday I
decided to implement a couple algorithms and data structures in Python. I manage to implement
sorting algorithms well. here is what I have done. I think someone will find it usefull.
I know that this can be don in more elegant way using some Python trait's but I tried to avoid
thing that are Python's specific because of the following reasons:

1. I don't know nearly enough Python as I'd like to
2. These implementations are very similar to those in C and can be easily rewritten in other
programming language.

Of course, problem is how to implement, say a linked list in Python, since it doesn't have
pointers, or even static types so how this could be implemented is pretty unclear to me:
Python Syntax (Toggle Plain Text)
  1. struct node
  2. {
  3. int data;
  4. struct node * link;
  5. };
I know, because of very powerfull data structures that exists like built in types this
is not neccessary but still...
Anyway I want to share my sort implementations:
Python Syntax (Toggle Plain Text)
  1. import random #modul random used for generating random numbers
  2.  
  3. N = 100 #defining number of elements
  4. lista = [] #defining list of elements
  5.  
  6. for i in range ( 0, N ) : #popuna liste slucajnim brojevima
  7. lista.append ( int ( random.uniform ( 0, 100 ) ) )
  8.  
  9. #sort functions definitions
  10. #bubble_sort
  11. def bubble_sort ( lista ) :
  12. swap_test = False
  13. for i in range ( 0, len ( lista ) - 1 ):
  14. for j in range ( 0, len ( lista ) - i - 1 ):
  15. if lista[j] > lista[j + 1] :
  16. lista[j], lista[j + 1] = lista[j + 1], lista[j] #elegentan way of swap
  17. swap_test = True
  18. if swap_test == False:
  19. break
  20.  
  21. #selection sort
  22. def selection_sort ( lista ):
  23. for i in range ( 0, len ( lista ) ):
  24. min = i
  25. for j in range ( i + 1, len ( lista ) ):
  26. if lista[j] < lista[min] :
  27. min = j
  28. lista[i], lista[min] = lista[min], lista[i]
  29.  
  30. #insertion sort
  31. def insertion_sort ( lista ):
  32. for i in range ( 1, len ( lista ) ):
  33. save = lista[i]
  34. j = i
  35. while ( j > 0 and lista [j - 1] > save ):
  36. lista[j] = lista[j - 1];
  37. j -= 1
  38. lista[j] = save
  39.  
  40. #quick sort
  41. def quick_sort ( lista ):
  42. quick_sort_r ( lista, 0, len ( lista ) - 1 )
  43. #end quick_sort
  44.  
  45. #quick_sort_r, rekurzivna funkcija
  46. def quick_sort_r ( lista , first, last ):
  47. if last > first :
  48. pivot = partition ( lista, first, last )
  49. quick_sort_r ( lista, first, pivot - 1 )
  50. quick_sort_r ( lista, pivot + 1, last )
  51. #end quick_sort_r
  52.  
  53. #funkcija partition
  54. def partition ( lista, first, last ):
  55. #prvo ide median of three biranje pocetnog pivota
  56. sred = ( first + last ) / 2
  57. if lista[first] > lista [sred] :
  58. lista[first], lista [sred] = lista [sred], lista[first]
  59. if lista[first] > lista [last] :
  60. lista[first], lista[last] = lista[last], lista[first]
  61. if lista[sred] > lista[last] :
  62. lista[sred], lista[last] = lista[last], lista[sred]
  63. lista [sred], lista [first] = lista[first], lista[sred]
  64.  
  65. pivot = first
  66. i = first + 1
  67. j = last
  68.  
  69. while ( True ):
  70. while ( i <= last and lista[i] <= lista [pivot] ):
  71. i += 1
  72. while ( j >= first and lista[j] > lista[pivot] ):
  73. j -= 1
  74. if i >= j :
  75. break
  76. else:
  77. lista[i], lista[j] = lista[j], lista[i]
  78. lista[j], lista[pivot] = lista[pivot], lista[j]
  79. return j
  80. #end partition
  81.  
  82. #heap sort
  83. def heap_sort ( lista ):
  84. first = 0;
  85. last = len ( lista ) - 1;
  86. create_heap ( lista, first, last )
  87. for i in range ( last, first, -1 ):
  88. lista[i], lista[first] = lista[first], lista[i]
  89. establish_heap_property ( lista, first, i - 1 )
  90. #kraj f-je heap_sort
  91.  
  92. #create heap
  93. def create_heap ( lista, first, last ):
  94. i = last / 2;
  95. while ( i >= first ):
  96. establish_heap_property ( lista, i, last )
  97. i -= 1
  98. #end create_heap
  99.  
  100. #establish heap property
  101. def establish_heap_property ( lista, first, last ):
  102. while 2 * first + 1 <= last :
  103. k = 2 * first + 1;
  104. if k < last and lista[k] < lista[k + 1] :
  105. k += 1
  106. if lista[first] >= lista[k] :
  107. break
  108. lista[first], lista[k] = lista[k], lista[first]
  109. first = k
  110. #end establish_heap_property
  111.  
  112. #merge sort
  113. def merge_sort ( lista ):
  114. merge_sort_r ( lista, 0, len ( lista ) -1 )
  115. #end merge_sort_r
  116.  
  117. #merge sort rekurzivna f-ja
  118. def merge_sort_r ( lista, first, last ):
  119. if first < last:
  120. sred = ( first + last ) / 2
  121. merge_sort_r ( lista, first, sred )
  122. merge_sort_r ( lista, sred + 1, last )
  123. merge ( lista, first, last, sred )
  124. #end merge_sort_r
  125.  
  126. #merge
  127. def merge ( lista, first, last, sred ):
  128. helper_list = []
  129. i = first
  130. j = sred + 1
  131. while ( i <= sred and j <= last ):
  132. if lista [i] <= lista [j] :
  133. helper_list.append ( lista[i] )
  134. i += 1
  135. else:
  136. helper_list.append ( lista [j] )
  137. j += 1
  138. while ( i <= sred ):
  139. helper_list.append ( lista[i] )
  140. i +=1
  141. while ( j <= last ):
  142. helper_list.append ( lista[j] )
  143. j += 1
  144.  
  145. for k in range ( 0, last - first + 1):
  146. lista[first + k] = helper_list [k]
  147. #end merge
  148.  
  149. #test if script is executed or module is imported
  150. if __name__ == "__main__" :
  151. merge_sort ( lista )
  152. print lista
  153. raw_input ( "Press Enter to continue..." )

I didn't commented or explain code in detail since really valueable and detail explanations
can be found on
www.eternallyconfuzzled.com
and I, with my poor English and programming skills, don't have minimum chance to write somthing good like that.

If you like this code, or find it useful in any way, I'd be happy, if not, sorry because wasting your time
and wasting space on this forum...

Regards,
Micko
Similar Threads
Reputation Points: 55
Solved Threads: 6
Junior Poster
Micko is offline Offline
148 posts
since Aug 2005
Nov 27th, 2005
0

Re: Sorting in Python

Looks like you met Narue on the C/C++ forum, she is the best!

Your Python code is great, works well. It would be a fabulous addition to the Python Snippets.

It depends how you look at it, Python variables are all pointers or references to a heap memory location. Take a look at the Python Tutorials here, I have tried to take a closer look at some variables and structures.
Moderator
Reputation Points: 1333
Solved Threads: 1404
DaniWeb's Hypocrite
vegaseat is offline Offline
5,792 posts
since Oct 2004
Nov 27th, 2005
0

Re: Sorting in Python

>problem is how to implement, say a linked list in Python, since it doesn't have
>pointers, or even static types so how this could be implemented is pretty unclear to me
Python is kind of screwy if you're used to a strongly typed language like C++ (or even C!). To make a node, create a class:
Python Syntax (Toggle Plain Text)
  1. class node:
  2. def __init__ ( self, data = None, link = None ):
  3. self.data = data
  4. self.link = link
Administrator
Reputation Points: 6442
Solved Threads: 1393
Bad Cop
Narue is offline Offline
11,807 posts
since Sep 2004
Nov 27th, 2005
0

Re: Sorting in Python

Didn't I tell you, she is the best!

Well, anyway I took your sorting algorithms and timed them. Increased elements to 1000 to get better times.
python Syntax (Toggle Plain Text)
  1. # timing Micko's 6 sorting algorithms 11/27/2005
  2.  
  3. import random # for generating random numbers
  4. import time # for timing each sort function with time.clock()
  5.  
  6. N = 1000 # number of elements
  7. lista = [] # list of comparable elements
  8.  
  9. for i in range ( 0, N ) :
  10. lista.append ( int ( random.uniform ( 0, N ) ) )
  11.  
  12. def print_timing(func):
  13. def wrapper(*arg):
  14. t1 = time.clock()
  15. res = func(*arg)
  16. t2 = time.clock()
  17. print '%s took %0.3fms.' % (func.func_name, (t2-t1)*1000.)
  18. return res
  19. return wrapper
  20.  
  21. # declare the @ decorator just above each sort function, invokes print_timing()
  22. @print_timing
  23. def bubble_sort( lista ):
  24. swap_test = False
  25. for i in range ( 0, len ( lista ) - 1 ):
  26. for j in range ( 0, len ( lista ) - i - 1 ):
  27. if lista[j] > lista[j + 1] :
  28. lista[j], lista[j + 1] = lista[j + 1], lista[j] # swap
  29. swap_test = True
  30. if swap_test == False:
  31. break
  32.  
  33. # selection sort
  34. @print_timing
  35. def selection_sort( lista ):
  36. for i in range ( 0, len ( lista ) ):
  37. min = i
  38. for j in range ( i + 1, len ( lista ) ):
  39. if lista[j] < lista[min] :
  40. min = j
  41. lista[i], lista[min] = lista[min], lista[i]
  42.  
  43. # insertion sort
  44. @print_timing
  45. def insertion_sort( lista ):
  46. for i in range ( 1, len ( lista ) ):
  47. save = lista[i]
  48. j = i
  49. while ( j > 0 and lista [j - 1] > save ):
  50. lista[j] = lista[j - 1];
  51. j -= 1
  52. lista[j] = save
  53.  
  54. # quick sort
  55. @print_timing
  56. def quick_sort( lista ):
  57. quick_sort_r( lista, 0, len ( lista ) - 1 )
  58. # end quick_sort
  59.  
  60. # quick_sort_r, recursive (used by quick_sort)
  61. def quick_sort_r( lista , first, last ):
  62. if last > first :
  63. pivot = partition ( lista, first, last )
  64. quick_sort_r ( lista, first, pivot - 1 )
  65. quick_sort_r ( lista, pivot + 1, last )
  66. # end quick_sort_r
  67.  
  68. # partition (used by quick_sort_r)
  69. def partition( lista, first, last ):
  70. sred = ( first + last ) / 2
  71. if lista[first] > lista [sred] :
  72. lista[first], lista [sred] = lista [sred], lista[first]
  73. if lista[first] > lista [last] :
  74. lista[first], lista[last] = lista[last], lista[first]
  75. if lista[sred] > lista[last] :
  76. lista[sred], lista[last] = lista[last], lista[sred]
  77. lista [sred], lista [first] = lista[first], lista[sred]
  78.  
  79. pivot = first
  80. i = first + 1
  81. j = last
  82.  
  83. while ( True ):
  84. while ( i <= last and lista[i] <= lista [pivot] ):
  85. i += 1
  86. while ( j >= first and lista[j] > lista[pivot] ):
  87. j -= 1
  88. if i >= j :
  89. break
  90. else:
  91. lista[i], lista[j] = lista[j], lista[i]
  92. lista[j], lista[pivot] = lista[pivot], lista[j]
  93. return j
  94. # end partition
  95.  
  96. # heap sort
  97. @print_timing
  98. def heap_sort( lista ):
  99. first = 0;
  100. last = len ( lista ) - 1;
  101. create_heap ( lista, first, last )
  102. for i in range ( last, first, -1 ):
  103. lista[i], lista[first] = lista[first], lista[i]
  104. establish_heap_property ( lista, first, i - 1 )
  105. # end heap_sort
  106.  
  107. # create heap (used by heap_sort)
  108. def create_heap( lista, first, last ):
  109. i = last / 2;
  110. while ( i >= first ):
  111. establish_heap_property ( lista, i, last )
  112. i -= 1
  113. # end create_heap
  114.  
  115. # establish heap property (used by create_heap)
  116. def establish_heap_property ( lista, first, last ):
  117. while 2 * first + 1 <= last :
  118. k = 2 * first + 1;
  119. if k < last and lista[k] < lista[k + 1] :
  120. k += 1
  121. if lista[first] >= lista[k] :
  122. break
  123. lista[first], lista[k] = lista[k], lista[first]
  124. first = k
  125. # end establish_heap_property
  126.  
  127. # merge sort
  128. @print_timing
  129. def merge_sort( lista ):
  130. merge_sort_r ( lista, 0, len ( lista ) -1 )
  131. # end merge_sort_r
  132.  
  133. # merge sort recursive (used by merge_sort)
  134. def merge_sort_r( lista, first, last ):
  135. if first < last:
  136. sred = ( first + last ) / 2
  137. merge_sort_r ( lista, first, sred )
  138. merge_sort_r ( lista, sred + 1, last )
  139. merge ( lista, first, last, sred )
  140. # end merge_sort_r
  141.  
  142. # merge (used by merge_sort_r)
  143. def merge( lista, first, last, sred ):
  144. helper_list = []
  145. i = first
  146. j = sred + 1
  147. while ( i <= sred and j <= last ):
  148. if lista [i] <= lista [j] :
  149. helper_list.append ( lista[i] )
  150. i += 1
  151. else:
  152. helper_list.append ( lista [j] )
  153. j += 1
  154. while ( i <= sred ):
  155. helper_list.append ( lista[i] )
  156. i +=1
  157. while ( j <= last ):
  158. helper_list.append ( lista[j] )
  159. j += 1
  160.  
  161. for k in range ( 0, last - first + 1):
  162. lista[first + k] = helper_list [k]
  163. # end merge
  164.  
  165.  
  166. # run test if script is executed
  167. if __name__ == "__main__" :
  168. print "timing the 6 sorting algorithms with a list of 1000 integers:"
  169. bubble_sort( lista )
  170. heap_sort( lista )
  171. insertion_sort( lista )
  172. merge_sort( lista )
  173. quick_sort( lista )
  174. selection_sort( lista )
  175.  
  176. raw_input( "Press Enter to continue..." )
  177.  
  178. """
  179. typical results:
  180. bubble_sort took 426.132ms.
  181. heap_sort took 28.322ms.
  182. insertion_sort took 1.091ms.
  183. merge_sort took 34.000ms.
  184. quick_sort took 6.494ms.
  185. selection_sort took 177.234ms.
  186. """
I understand that the Python interpreter gives repeated function calls a time penalty. That makes your recursives look worse than they should. By the way, the Python internal list sort of this particular list takes 0.082ms.

For your information the Python list container does behave like an array, but it may slow external sorting down. You can get true array modules for scientific stuff, it may be interesting to test these out. Google for NumArray.
Last edited by vegaseat; Aug 15th, 2008 at 7:21 pm. Reason: replaced non functioning php code tags
Moderator
Reputation Points: 1333
Solved Threads: 1404
DaniWeb's Hypocrite
vegaseat is offline Offline
5,792 posts
since Oct 2004
Nov 27th, 2005
0

Re: Sorting in Python

Quote originally posted by vegaseat ...
Your Python code is great, works well. It would be a fabulous addition to the Python Snippets.
I you like add it there if it is OK with Narue, since most of the code in C (as initial idea ) is hers...
Cheers

- Micko
Reputation Points: 55
Solved Threads: 6
Junior Poster
Micko is offline Offline
148 posts
since Aug 2005
Mar 27th, 2006
0

Re: Sorting in Python

Your "typical results" for timing are typical results for timing a sorted list. Only bubble sort sorts a random list. Try putting listb = list( lista ) before each sort call and then sort listb. This creates a fresh copy of the original unsorted lista. Here are typical results:

timing the 6 sorting algorithms with a list of 1000 integers:
bubble_sort took 269.410ms.
heap_sort took 10.810ms.
insertion_sort took 139.228ms.
merge_sort took 14.764ms.
quick_sort took 7.494ms.
selection_sort took 118.048ms.

Note that insertion and selection sorts are now way slower than heap, merge, and quick --as they should be-- and heap and merge are about the same.
ddc
Reputation Points: 10
Solved Threads: 1
Newbie Poster
ddc is offline Offline
1 posts
since Mar 2006
Mar 27th, 2006
0

Re: Sorting in Python

Quote originally posted by ddc ...
Your "typical results" for timing are typical results for timing a sorted list. Only bubble sort sorts a random list. Try putting listb = list( lista ) before each sort call and then sort listb. This creates a fresh copy of the original unsorted lista. Here are typical results:

timing the 6 sorting algorithms with a list of 1000 integers:
bubble_sort took 269.410ms.
heap_sort took 10.810ms.
insertion_sort took 139.228ms.
merge_sort took 14.764ms.
quick_sort took 7.494ms.
selection_sort took 118.048ms.

Note that insertion and selection sorts are now way slower than heap, merge, and quick --as they should be-- and heap and merge are about the same.
Micko and I came to the same conclusion. For the finished version of this, posted about two months ago, see:
http://www.daniweb.com/code/snippet452.html
Moderator
Reputation Points: 1333
Solved Threads: 1404
DaniWeb's Hypocrite
vegaseat is offline Offline
5,792 posts
since Oct 2004
Mar 29th, 2006
0

Re: Sorting in Python

I am starting to learn Python and have a good crasp of C++ from school. I must say, that I find this thread very interesting information. Thanks all of you who contributed!
Reputation Points: 625
Solved Threads: 211
Posting Virtuoso
Ene Uran is offline Offline
1,704 posts
since Aug 2005

This thread is solved

Either the thread starter or a moderator has marked this thread as solved. You can most likely trust the responses and answers given. There is most likely no reason for any further responses to be posted here. If you have a related question, please start a new thread in this forum instead.

This thread is more than three months old

No one has posted to this discussion for at least three months. Please let old threads die and do not reply to them unless you feel you have something new and valuable to contribute that absolutely must be added to make the discussion complete. Otherwise, please start a new thread in this forum instead.
Message:
Previous Thread in Python Forum Timeline: Help
Next Thread in Python Forum Timeline: Safety of eval function





About Us | Contact Us | Advertise | Acceptable Use Policy
Forum Index | Build Custom RSS Feed


Follow us on Twitter


© 2011 DaniWeb® LLC