Sorting in python does not work - python

i'm a beginning python programmer and i'm trying to write a code that sorts data in an array in increasing order as below:
A = [2,3,6,8,4,5,7,123,543,65435,31,43]
for i in range(len(A)-1):
if A[i] > A[i+1]:
A[i] , A[i+1] = A[i+1] , A[i]
print (A)
However the result returns this:
[2, 3, 6, 4, 5, 7, 8, 123, 543, 31, 43, 65435]
May I know what I'm doing wrong? Any help would be much appreciated. Thanks!

You are only performing a single stage of bubble-sort; to get the list completely sorted, you would have to float the numbers up n - 1 times, not only one.
Try this:
for i in range(len(A)-1):
for i in range(len(A)-1):
if A[i] > A[i+1]:
A[i] , A[i+1] = A[i+1] , A[i]

You are trying to do Bubble Sort. Actually the part of your code works, In your result the greatest element is at the end of the sorted array. Now you have to do the same for all remaining elements in a nested for loop. That's why Bubble Sort has the complexity of O(n^2)

A = [2,3,6,8,4,5,7,123,543,65435,31,43]
for i in range(0,len(A)):
for j in range(i+1):
if A[i] > A[j]:
A[i] , A[j] = A[j] , A[i]
print A
Sorting needs comparing an element with rest of the elements in that array

Related

Fastest (least execution time) approach to get max/min of an array of int without inbuilt functions except range() and len() [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
This post was edited and submitted for review 1 year ago and failed to reopen the post:
Original close reason(s) were not resolved
Improve this question
I am looking for a faster, less execution time approach to get maximum and minimum elements of an array of integer, which means we need to sort an array of integers. Without using any inbuilt functions like sort() except range() and len() and using only one for or while loop, which I can't figure out.
def getMinMax( a, n):
while 1 == 1:
run = False
for i in range(n):
if i < (n-1) and a[i] > a[i+1]:
run = True
if run:
for i in range(n):
if i < (n-1) and a[i] > a[i+1]:
temp = a[i]
a[i] = a[i+1]
a[i+1] = temp
else:
break
return a[0], a[i], a
A = [2, 167, 56, 3, 10000, 1]
min_elem, max_elem, sorted_array = getMinMax(A, len(A))
min_elem, max_elem, sorted_array
Output:
(1, 10000, [1, 2, 3, 56, 167, 10000])
With one loop
def getMinMax( a, n):
min_elem = a[0]
max_elem = a[0]
for i in range(n):
if i < (n-1):
if a[i] > a[i+1]:
temp = a[i]
a[i] = a[i+1]
a[i+1] = temp
max_var, min_var = a[n-1], a[0]
return max_elem, min_elem
array = [3,123,200,4,500000,1]
getMinMax( array, len(array))
Output:
(500000, 3)
Basically, your method to find min and max is not having any major effect at all. Besides, it is taking more time to execute than the normal method of finding min and max. (i.e. to iterate twice and swap adjacent elements if the preceding and succeeding are lesser or greater, and then access the first and last element directly to get the min and max values resp.)
To demonstrate why your code is not efficient as the traditional method, I executed your code 100000000 times vs my traditional code the same number of times and found out that your code actually takes more time than mine!
import timeit
A = [3, 2, 1, 56, 10000, 167]
code1 = '''
def getMinMax( a, n):
while 1 == 1:
run = False
for i in range(n):
if i < (n-1) and a[i] > a[i+1]:
run = True
if run:
for i in range(n):
if i < (n-1) and a[i] > a[i+1]:
temp = a[i]
a[i] = a[i+1]
a[i+1] = temp
else:
break
print(a[i], a[0])
return a[i], a[0]
'''
code2 = '''
def min_max(A):
for i in range(len(A)):
for j in range(1, len(A)-1):
if A[j] > A[j+1]:
A[j],A[j+1] = A[j+1],A[j]
print(A[0], A[len(A)-1])
return A[0],A[len(A)-1]
'''
print(timeit.timeit(stmt=code1, number=100000000))
print(timeit.timeit(stmt=code2, number=100000000))
Output:
6.4907884000000005 #<-- your code's execution time after the 100000000th execution
5.600494200000001 #<-- my code's execution time after the 100000000th execution
I know this is ridiculous but if the person asking the question really doesn't want to use min() and/or max() then this also works:
def getMinMax(A):
if A:
a = sorted(A)
return a[0], a[-1]
return None, None
l=[1,2,3,4,5]
print(max(l),min(l))
Just use min() and max() function.
syntax:
for min()
min(iterable_name)
for max()
max(iterable_name)

How to implement the pseudocode Swap A[i] and A[j]?

I have this pseudocode to implement:
function partition (A, start, stop)
Set pivot = A[stop]
Set i = start
for j in range(start, stop) do
if A[j] ≤ pivot then
Swap A[i] and A[j]
i++
end if
end for
Swap A[i] and A[stop]
return i
end function
I am lost in line 6: "Swap A[i] and A[j]". How would that be written exactly?
It's a lot easier in Python than most other languages, because Python has tuple packing and unpacking.
A[i], A[j] = A[j], A[i]

Insertion Sort in python using Key

def insertion_sort2(A):
for i in range(1,len(A)):
key = A[i]
j = i-1
for j in range(i-1,0,-1):
if A[j] > key :
A[j+1] = A[j]
else:
A[j+1] = key
break
for i in range(1, len(arr)):
key = arr[i]
j = i-1
while j >=0 and key < arr[j] :
arr[j+1] = arr[j]
j -= 1
arr[j+1] = key
Hello I have tried both methods to do simple Insertion Sort in c++ it works but in python it is not working,but both of them are giving answers like
1st one:
[56, 77, 77, 77, 77, 77, 77, 99]
2nd one:
does not sort even
Note:The second one starts after break and I have not run them both together,I commented out one and then run the other one
First of all you don't go upto the 0th element in the array in the inner loop. In python's range function, the range is counted uptil one before the second term. On putting range(i-1,-1,-1) the range becomes i-1 to 0.
Secondly, you are not swapping the two consecutive elements , just assigning (j)th element a value of (j+1)th element. But what about assigning jth value to (j-1)th element.
Third, there's no meaning of doing A[j+1] = key as it already is key.
def insertion_sort2(A):
for i in range(1,len(A)):
key = A[i]
j = i-1
for j in range(i-1,-1,-1):
if A[j] > key :
A[j+1], A[j] = A[j], A[j+1]
else:
break

sorting a list in python without the sorted function

import sys
import pdb
a = [5, 2, 4, 1]
for i in range(len(a)):
for j in range(len(a) - 1):
if a[j] > a[j+1]:
t = a[j]
a[j] = a[j+1]
a[j] = t
print a
sys.exit()
I just tried a C program in Python – a normal sort without the sorted function. Why am I not getting the sorted list?
t = a[j]
followed by
a[j] = t
doesn’t seem right. If you meant to swap them, the second one should be:
a[j + 1] = t
But in Python, that’s better written as:
a[j], a[j + 1] = a[j + 1], a[j]
(Of course, in Python, it’s much better written as quicksort.)
Try This -:
for i in range(len(a)):
for j in range(len(a) - 1):
if a[j] > a[j+1]:
a[j+1], a[j] = a[j], a[j+1]
print a
:)
The last line in your for loop should be a[j+1] = t. I think it's just a code mistake. Take care the next time. Also, in Python, when you want to exchange two variables, you should follow what #minitech and #Nilesh G said.
a = [5,2,4,1]
for i in range(len(a)):
for j in range(len(a)-1):
If a[j]>a[j+1]:
a[j],a[j+1] = a[j+1],a[j]
Print a
s = [3, 6, 4, 5, 2, 1, 7, 8, 11, 12]
for k in range(len(s)):
for m in range(len(s)-1):
if s[m]>s[m+1]:
s[m],s[m+1] = s[m+1],s[m]
print s
if time complexity matters then, this can help you,
nums = [8,3,4,2,7,-9,5,0,1]
tmp = []
def get_index(val:int):
for i in range(0,len(tmp)):
if tmp[i] > val:
return i
else:
continue
for one_num in nums:
print(one_num, tmp)
if len(tmp) == 0:
tmp.append(one_num) #[8]
else: # [3,8]
if one_num > tmp[-1]:
tmp.append(one_num)
else:
tmp.insert(get_index(one_num, ),one_num)
print(tmp)

Having difficulty in implementing QuickSort

I have been trying to implement quicksort for like 2 days now (Looks like my programming skills are getting rusty). I do not know what I am doing wrong. I was about to give up so I thought I should consult the discussion forum.
here is the code that I am trying to implement in python. But it is not giving the desired result. Anyone can please point out what I am doing wrong?
def QuickSort(A,p,r):
if p < r:
pivotIndex = Partition(A,p,r)
QuickSort(A,p,pivotIndex-1)
QuickSort(A,pivotIndex+1,r)
return A
def Partition(A,p,r):
m = A[p]
i = p+1
for j in range( p+1 , r ):
if A[j] < m:
A[j] , A[i] = A[i] , A[j]
i+=1
A[p], A[i-1] = A[i-1] , A[p]
return i-1
The output for test input is:
>>>QuickSort([9,8,7,6,5,4,3,2,1],0,9)
[1, 3, 5, 6, 7, 4, 8, 2, 9]
I will be very thankful if anyone help me in implementing this.
Regards
Slicing doesn't return a view of the original list; it makes a new list out of data from the old list. That means the recursive calls to QuickSort don't change the original list.
You can try this implementation in one line of code:
def QuickSort(list):
return [] if list==[] else QuickSort([x for x in list[1:] if x < list[0]]) + [list[0]] + QuickSort([x for x in list[1:] if x >= list[0]])
print QuickSort([9,8,7,6,5,4,3,2,1])
I have figured out the answer. It appeared that I was passing one-less to the QuickSort method
def QuickSort(A,p,r):
if r-p <= 1: return
pivotIndex = Partition(A,p,r)
QuickSort(A,p,pivotIndex)
QuickSort(A,pivotIndex+1,r)
return A
def Partition(A,p,r):
m = A[p]
i = p+1
for j in range( p+1 , r ):
if A[j] < m:
A[j] , A[i] = A[i] , A[j]
i= i + 1
A[p], A[i-1] = A[i-1] , A[p]
return i-1
It is the correct implementation
It seems that you wanted to keep the pivot on the left side and skip it, but that didn't turn out well, so I just moved it to the end of the array and reduced the iteration index accordingly and then reversed the post-partition swap (to take into consideration the pivot movement).
def Partition(A,p,r):
m = A[p]
A[p], A[r] = A[r], A[p]
i = p
for j in range( p, r ):
if A[j] < m:
A[j] , A[i] = A[i] , A[j]
i+=1
A[r], A[i] = A[i] , A[r]
return i
I think that you could do it with the pivot on the left side, but then you would have to change the loop direction I guess, but I am not sure.
EDIT: Sorry I forgot to add the call is then QuickSort([9,8,7,6,5,4,3,2,1],0,8), since the indices are inclusive now.

Categories