简单地说就是两层循环,第一次循环每循环一次就找到一个最大的排到列表的尾部(通过第二层循环里面不停的交换),这样第一次循环循环数组的长度次数,就可得到一个排序好的数组。
def bubbleSort(input_list):
n=len(input_list)
if n==0:
return []
sorted_list=input_list
for i in range(n-1):
bChanged=False
print('第%d趟排序:'%(i+1))
for j in range (n-1):
if sorted_list[j+1]<sorted_list[j]:
sorted_list[j],sorted_list[j+1]=sorted_list[j+1],sorted_list[j]
print(sorted_list)
return sorted_list
input_list=[50,123,543,187,49,30,0,2,11,100]
print('排序前',input_list)
sorted_list=bubbleSort(input_list)
print('排序后',sorted_list)
def bubbleSort(input_list):
n=len(input_list)
for i in range(n-1):
bchanged=False
for j in range(n-1):
if input_list[j]>input_list[j+1]:
input_list[j],input_list[j+1]=input_list[j+1],input_list[j]
bchanged=True
if bchanged==False:
return input_list
return input_list
input_list=[50,123,543,187,49,30,0,2,11,100]
print('排序前',input_list)
sorted_list=bubbleSort(input_list)
print('排序后',sorted_list)
# print(bubbleSort([]))
排序前 [50, 123, 543, 187, 49, 30, 0, 2, 11, 100]
排序后 [0, 2, 11, 30, 49, 50, 100, 123, 187, 543]
[]
直接插入排序就是先从头到后面遍历一遍,然后对于每一个都遍历这个元素之前的元素使其插入到合适的位置,由于是从头往前遍历所以该元素之前的元素本身已经是排序好的元素了,我们需要做的事情只是将该元素插入合适的位置。
def insertSort(input_list):
n=len(input_list)
for i in range(n):
for j in range(i)[::-1]:
if input_list[j+1]<input_list[j]:
input_list[j+1],input_list[j]=input_list[j],input_list[j+1]
return input_list
input_list=[50,123,543,187,49,30,0,2,11,100]
print('排序前',input_list)
sorted_list=insertSort(input_list)
print('排序后',sorted_list)
排序前 [50, 123, 543, 187, 49, 30, 0, 2, 11, 100]
排序后 [0, 2, 11, 30, 49, 50, 100, 123, 187, 543]
def insertSort(input_list):
n=len(input_list)
for i in range(n):
j=i-1
temp=input_list[i]
while j>=0 and temp<input_list[j]:
input_list[j+1]=input_list[j]
j-=1
input_list[j+1]=temp
return input_list
input_list=[50,123,543,187,49,30,0,2,11,100]
print('排序前',input_list)
sorted_list=insertSort(input_list)
print('排序后',sorted_list)
排序前 [50, 123, 543, 187, 49, 30, 0, 2, 11, 100]
排序后 [0, 2, 11, 30, 49, 50, 100, 123, 187, 543]
希尔(Shell)排序又称为缩小增量排序,它是一种插入排序。它是直接插入排序算法的一种威力加强版。
希尔排序,也称递减增量排序算法,以其设计者希尔(Donald Shell)的名字命名,该算法由 1959 年公布。
希尔排序,他的主要思想是先把比较大放到后面,然后把比较小的移到前面去。你想他开始以gap这个步长。然后集体就可以并行的集体的去往后移这个操作。这样的话,它就是可以用多处理器来进行处理,而不是用单个处理器一个一个的来进行处理。
def shellSort(input_list):
n=len(input_list)
if n<=1:
return input_list
gap=n//2
while gap>0:
for i in range(gap,n):
j=i-gap
temp=input_list[i]
while j>=0 and input_list[j]>temp:
input_list[j+gap]=input_list[j]
j-=gap
input_list[j+gap]=temp
gap//=2
return input_list
input_list=[50,123,543,187,49,30,0,2,11,100]
print('排序前',input_list)
sorted_list=shellSort(input_list)
print('排序后',sorted_list)
排序前 [50, 123, 543, 187, 49, 30, 0, 2, 11, 100]
排序后 [0, 2, 11, 30, 49, 50, 100, 123, 187, 543]
快速排序的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分:分割点左边都是比它小的数,右边都是比它大的数。
然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
def QuickSort(input_list,left,right):
def mid(input_list,left,right):
mid=input_list[left]
while left<right:
while left<right and input_list[right]>mid:
right-=1
input_list[left]=input_list[right]
while left<right and input_list[left]<mid:
left+=1
input_list[right]=input_list[left]
input_list[left]=mid
return left
if left<right:
mid=mid(input_list,left,right)
QuickSort(input_list,left,mid-1)
QuickSort(input_list,mid+1,right)
return input_list
input_list=[50,123,543,187,49,30,0,2,11,100]
print('排序前',input_list)
sorted_list=QuickSort(input_list,0,len(input_list)-1)
print('排序后',sorted_list)
排序前 [50, 123, 543, 187, 49, 30, 0, 2, 11, 100]
排序后 [0, 2, 11, 30, 49, 50, 100, 123, 187, 543]
def QuickSort(input_list,left,right):
i=left
j=right
mid=input_list[i]
while i<j:
while i<j and input_list[j]>mid:
j-=1
while i<j and input_list[i]<mid:
i+=1
if i<j:
input_list[i],input_list[j]=input_list[j],input_list[i]
i+=1
j-=1
if left<right:
QuickSort(input_list,left,i-1)
QuickSort(input_list,j+1,right)
return input_list
input_list=[50,123,543,187,49,30,0,2,11,100]
print('排序前',input_list)
sorted_list=QuickSort(input_list,0,len(input_list)-1)
print('排序后',sorted_list)
排序前 [50, 123, 543, 187, 49, 30, 0, 2, 11, 100]
排序后 [0, 2, 11, 30, 49, 50, 100, 123, 187, 543]
遍历一遍数组,每趟排序中,将当前第 i 小的元素放在位置 i 上。
def SelectSort(input_list):
n=len(input_list)
for i in range(n):
temp=input_list[i]
min_index=i
for j in range(i,n):
if input_list[j]<temp:
temp=input_list[j]
min_index=j
imput_list[i],input_list[min_index]=input_list[min_index],input_list[i]
return input_list
input_list=[50,123,543,187,49,30,0,2,11,100]
print('排序前',input_list)
sorted_list=QuickSort(input_list,0,len(input_list)-1)
print('排序后',sorted_list)
排序前 [50, 123, 543, 187, 49, 30, 0, 2, 11, 100]
排序后 [0, 2, 11, 30, 49, 50, 100, 123, 187, 543]
def HeadSort(input_list):
n=len(input_list)
def HeadAdjust(input_list,parent,length):
child=2*parent+1
temp=input_list[parent]
while child<length:
if child+1<length and input_list[child]<input_list[child+1]:
child+=1
if temp>input_list[child]:
break
input_list[parent]=input_list[child]
parent=child
child=2*parent+1
input_list[parent]=temp
for i in range(n//2)[::-1]:
HeadAdjust(input_list,i,n)
for j in range(n)[::-1]:
input_list[j],input_list[0]=input_list[0],input_list[j]
HeadAdjust(input_list,0,j)
return input_list
input_list=[50,123,543,187,49,30,0,2,11,100]
print('排序前',input_list)
sorted_list=HeadSort(input_list)
print('排序后',sorted_list)
排序前 [50, 123, 543, 187, 49, 30, 0, 2, 11, 100]
排序后 [0, 2, 11, 30, 49, 50, 100, 123, 187, 543]
归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。
def MergeSort(input_list):
def merge(left,right):
temp=[]
i=0
j=0
while i<len(left) and j<len(right):
if left[i]<right[j]:
temp.append(left[i])
i+=1
else:
temp.append(right[j])
j+=1
while i<len(left):
temp.append(left[i])
i+=1
while j<len(right):
temp.append(right[j])
j+=1
return temp
def merge_sort(input_list):
if len(input_list)<=1:
return input_list
mid=len(input_list)//2
left=merge_sort(input_list[:mid])
right=merge_sort(input_list[mid:])
return merge(left,right)
sort_list=merge_sort(input_list)
return sort_list
input_list=[50,123,543,187,49,30,0,2,11,100]
print('排序前',input_list)
sorted_list=MergeSort(input_list)
print('排序后',sorted_list)
排序前 [50, 123, 543, 187, 49, 30, 0, 2, 11, 100]
排序后 [0, 2, 11, 30, 49, 50, 100, 123, 187, 543]
kruskal算法基本思路:先对边按权重从小到大排序,先选取权重最小的一条边,如果该边的两个节点均为不同的分量,则加入到最小生成树,否则计算下一条边,直到遍历完所有的边。
prim算法基本思路:所有节点分成两个group,一个为已经选取的selected_node(为list类型),一个为candidate_node,首先任取一个节点加入到selected_node,然后遍历头节点在selected_node,尾节点在candidate_node的边,选取符合这个条件的边里面权重最小的边,加入到最小生成树,选出的边的尾节点加入到selected_node,并从candidate_node删除。直到candidate_node中没有备选节点(这个循环条件要求所有节点都有边连接,即边数要大于等于节点数-1,循环开始前要加入这个条件判断,否则可能会有节点一直在candidate中,导致死循环)。
class Graph(object):
def __init__(self, maps):
self.maps = maps
self.nodenum = self.get_nodenum()
self.edgenum = self.get_edgenum()
def get_nodenum(self):
return len(self.maps)
def get_edgenum(self):
count = 0
for i in range(self.nodenum):
for j in range(i):
if self.maps[i][j] > 0 and self.maps[i][j] < 9999:
count += 1
return count
def kruskal(self):
res = []
if self.nodenum <= 0 or self.edgenum < self.nodenum-1:
return res
edge_list = []
for i in range(self.nodenum):
for j in range(i,self.nodenum):
if self.maps[i][j] < 9999:
edge_list.append([i, j, self.maps[i][j]])#按[begin, end, weight]形式加入
edge_list.sort(key=lambda a:a[2])#已经排好序的边集合
group = [[i] for i in range(self.nodenum)]
for edge in edge_list:
for i in range(len(group)):
if edge[0] in group[i]:
m = i
if edge[1] in group[i]:
n = i
if m != n:
res.append(edge)
group[m] = group[m] + group[n]
group[n] = []
return res
def prim(self):
res = []
if self.nodenum <= 0 or self.edgenum < self.nodenum-1:
return res
res = []
seleted_node = [0]
candidate_node = [i for i in range(1, self.nodenum)]
while len(candidate_node) > 0:
begin, end, minweight = 0, 0, 9999
for i in seleted_node:
for j in candidate_node:
if self.maps[i][j] < minweight:
minweight = self.maps[i][j]
begin = i
end = j
res.append([begin, end, minweight])
seleted_node.append(end)
candidate_node.remove(end)
return res
max_value = 9999
row0 = [0,7,max_value,max_value,max_value,5]
row1 = [7,0,9,max_value,3,max_value]
row2 = [max_value,9,0,6,max_value,max_value]
row3 = [max_value,max_value,6,0,8,10]
row4 = [max_value,3,max_value,8,0,4]
row5 = [5,max_value,max_value,10,4,0]
maps = [row0, row1, row2,row3, row4, row5]
graph = Graph(maps)
print('邻接矩阵为\n%s'%graph.maps)
print('节点数据为%d,边数为%d\n'%(graph.nodenum, graph.edgenum))
print('------最小生成树kruskal算法------')
print(graph.kruskal())
print('------最小生成树prim算法')
print(graph.prim())
邻接矩阵为
[[0, 7, 9999, 9999, 9999, 5], [7, 0, 9, 9999, 3, 9999], [9999, 9, 0, 6, 9999, 9999], [9999, 9999, 6, 0, 8, 10], [9999, 3, 9999, 8, 0, 4], [5, 9999, 9999, 10, 4, 0]]
节点数据为6,边数为8
------最小生成树kruskal算法------
[[1, 4, 3], [4, 5, 4], [0, 5, 5], [2, 3, 6], [3, 4, 8]]
------最小生成树prim算法
[[0, 5, 5], [5, 4, 4], [4, 1, 3], [4, 3, 8], [3, 2, 6]]