基于python的冒泡算法和鸡尾酒算法程序设计(持续更新)
冒泡算法
冒泡算法就是通过相邻两个数依次做比较,取大/取小进行位置调换,最后进行排序。
对冒泡算法进行了优化,在第二层循环处添加了type判断了后续是否已经进行好排序,如果已经排好序则跳出循环。
若对存在大量已经有序数列进行排序添加了sort_lastnumber记录了有序数列的位置,对后面的数不再遍历
程序片段
def bubble(sort_number,sort_type): #冒泡排序法 sort_type=1为倒序 0为正序
print('冒泡排序:', len(sort_number))
global sort_lastnumber #末端排序标志位
global sort_last_len #排序数列长度
sort_lastnumber = 0
sort_last_len = len(sort_number)-1
print(sort_last_len)
for i in range(0,len(sort_number)):
print(i)
type = True
for j in range(0,sort_last_len):
#print('j:',j)
if (sort_number[j+1]<sort_number[j] and sort_type == 0) or (sort_number[j+1]>number[j] and sort_type == 1):
item = sort_number[j+1]
sort_number[j+1]=sort_number[j]
sort_number[j]=item
type = False
sort_lastnumber = j
print('冒泡排序:',sort_number)
draw1(sort_number, sort_number[j])
sort_last_len =sort_lastnumber
if type == True:
return
效果视频
冒泡排序
鸡尾酒算法
鸡尾酒算法就是先是从左到右,再从右到左排序,来来回回进行排序。与冒泡算法有相似处。
程序片段
def Cocktail_sort(sort_number,sort_type):
print('鸡尾酒排序:',sort_number)
for i in range(0,(len(sort_number)-1)//2):
type = True
print('外层:',i)
for j in range(0,len(sort_number)-1):
if(sort_number[j+1]>sort_number[j] and sort_type ==1) or (sort_number[j+1]<sort_number[j] and sort_type ==0):
item = sort_number[j+1]
sort_number[j+1]=sort_number[j]
sort_number[j]=item
type=False
print('鸡尾酒排序:', sort_number)
draw1(sort_number, sort_number[j])
if type == True:
break
type = True
for k in range(len(sort_number)-2,0,-1):
if(sort_number[k-1]<sort_number[k] and sort_type ==1)or (sort_number[k-1]>sort_number[k] and sort_type ==0):
item=sort_number[k]
sort_number[k]=sort_number[k-1]
sort_number[k-1]=item
type=False
print('鸡尾酒排序:', sort_number)
draw1(sort_number, sort_number[k])
if type == True:
break
视频效果
基于python—鸡尾酒排序
快速排序算法
所谓快速排序算法,就是确定一个基数,以基数进行对比,将数分为大于基数和小于基数的两端,将基数-1和基数+1分别为下次递归的左终点,和右起始点,进行递归,最终达到有序数列。具体分布算法有双边循环、和单边循环。
快速排序算法(双边循环)
快速排序算法(双边循环)首先通过确定一个基准数,列表两端分别为start和end,定义两个指针(不是实际的指针,标志位),分别位left和right,指向左端和有端,从右到左开始与基准数做比较,如果大于/小于(区别是排序的正/倒序)基准数,则换left从左到右进行与基准数做比较,如果小于/大于基准数,这停止继续比较,把left和right的数进行对调,然后再次进行和基准数进行比较,直到left和right重合(下文记为left),将基准数与其对调。后以重合部分的两端继续做上面部分,一个是以[start,left-1],一个是以[left+1,end],继续重复上述快速排序方法,可以采用递归的方法,进行快速排序。
def Quick_sort(sort_number,left_pointer,right_pointer,sort_type,loop_type): # 快速排序法
global location_point
if(left_pointer >= right_pointer):
return
if(loop_type == 0):
print("双边循环")
location_point = Bilateral_loop(sort_number,left_pointer,right_pointer,sort_type)
Quick_sort(sort_number,left_pointer,location_point-1,sort_type,loop_type)
Quick_sort(sort_number,location_point+1,right_pointer,sort_type,loop_type)
elif(loop_type == 1):
print("单边循环")
location_point = Unilateral_loop(sort_number,left_pointer,right_pointer,sort_type)
print("第一个:")
Quick_sort(sort_number, left_pointer, location_point - 1, sort_type, loop_type)
print("第二个:")
Quick_sort(sort_number, location_point + 1, right_pointer, sort_type, loop_type)
def Bilateral_loop(sort_number,start_pointer,end_pointer,sort_type): #双边循环法
global pivot
global left
global right
pivot = sort_number[start_pointer]
print('基准:',pivot)
left = start_pointer
right = end_pointer
while(left != right):
print(sort_type)
while((left<right and sort_number[right]>pivot and sort_type == 0) or
(left<right and sort_number[right]<pivot and sort_type == 1)):
right-=1
while((left<right and sort_number[left]<=pivot and sort_type == 0) or
(left<right and sort_number[left]>=pivot and sort_type == 1)):
left+=1
if(left<right):
item = sort_number[left]
sort_number[left] = sort_number[right]
sort_number[right] = item
print('快速排序(双边循环):',sort_number)
draw1(sort_number, sort_number[left])
sort_number[start_pointer] = sort_number[left]
sort_number[left] = pivot
print('快速排序(双边循环):', sort_number)
draw1(sort_number, sort_number[left])
return left
快速排序(单边循环)
单边循环具体算法,首先确定一个基数和mark点指向基数,然后通过循环,如果发现比基数小/大的数,则将mark+1,并将此时mark点指向的数与比较的数进行对调。之后继续执行比较,如若发现比基数小/大的数,继续执行上述操作,当完成第一轮比较,可以将大于/小于基数的数分布到两端,将此时的mark-1和mark+1的点作为左端的终点和右端的起始点,通过递归的方式,再进行上述操作,最后会得出一个有序数列。
def Quick_sort(sort_number,left_pointer,right_pointer,sort_type,loop_type): # 快速排序法
global location_point
if(left_pointer >= right_pointer):
return
if(loop_type == 0):
print("双边循环")
location_point = Bilateral_loop(sort_number,left_pointer,right_pointer,sort_type)
Quick_sort(sort_number,left_pointer,location_point-1,sort_type,loop_type)
Quick_sort(sort_number,location_point+1,right_pointer,sort_type,loop_type)
elif(loop_type == 1):
print("单边循环")
location_point = Unilateral_loop(sort_number,left_pointer,right_pointer,sort_type)
print("第一个:")
Quick_sort(sort_number, left_pointer, location_point - 1, sort_type, loop_type)
print("第二个:")
Quick_sort(sort_number, location_point + 1, right_pointer, sort_type, loop_type)
def Unilateral_loop(sort_number,start_pointer,end_pointer,sort_type):
if(start_pointer >= end_pointer):
return
pivot = sort_number[start_pointer]
mark = start_pointer
print('快速排序(单边循环)0:', sort_number)
#print('基准:', pivot,'mark:',mark)
for i in range(start_pointer+1,end_pointer+1):
print("i:",i)
if(sort_number[i]<pivot and sort_type == 0) or\
(sort_number[i]>pivot and sort_type == 1):
mark+=1
print("对调:",sort_number[mark],"和",sort_number[i])
p = sort_number[mark]
sort_number[mark] = sort_number[i]
sort_number[i] = p
draw1(sort_number,sort_number[mark])
print('sort_number:', sort_number[i], '基准:', pivot, 'mark:', mark)
print('快速排序(单边循环)1:', sort_number)
sort_number[start_pointer] = sort_number[mark]
sort_number[mark] = pivot
draw1(sort_number, sort_number[mark])
print('快速排序(单边循环)2:', sort_number)
print('基准:', pivot, 'mark:', mark)
#print('快速排序(单边循环):', sort_number)
return mark
完整程序代码
import matplotlib.pyplot as plt
import numpy as np
number = np.array([4,7,3,5,6,2,8,1])
def bubble(sort_number, sort_type): # 冒泡排序法 sort_type=1为倒序 0为正序
print('冒泡排序:', len(sort_number))
global sort_lastnumber # 末端排序标志位
global sort_last_len # 排序数列长度
sort_lastnumber = 0
sort_last_len = len(sort_number)-1
print(sort_last_len)
for i in range(0,len(sort_number)):
print(i)
type = True
for j in range(0,sort_last_len):
# print('j:',j)
if (sort_number[j+1]<sort_number[j] and sort_type == 0) or (sort_number[j+1]>number[j] and sort_type == 1):
item = sort_number[j+1]
sort_number[j+1]=sort_number[j]
sort_number[j]=item
type = False
sort_lastnumber = j
print('冒泡排序:',sort_number)
draw1(sort_number, sort_number[j])
sort_last_len =sort_lastnumber
if type == True:
return
def Cocktail_sort(sort_number,sort_type): # 鸡尾酒排序法
print('鸡尾酒排序:',sort_number)
for i in range(0,(len(sort_number)-1)//2):
type = True
print('外层:',i)
for j in range(0,len(sort_number)-1):
if(sort_number[j+1]>sort_number[j] and sort_type ==1) or (sort_number[j+1]<sort_number[j] and sort_type ==0):
item = sort_number[j+1]
sort_number[j+1]=sort_number[j]
sort_number[j]=item
type=False
print('鸡尾酒排序:', sort_number)
draw1(sort_number, sort_number[j])
if type == True:
break
type = True
for k in range(len(sort_number)-2,0,-1):
if(sort_number[k-1]<sort_number[k] and sort_type ==1)or (sort_number[k-1]>sort_number[k] and sort_type ==0):
item=sort_number[k]
sort_number[k]=sort_number[k-1]
sort_number[k-1]=item
type=False
print('鸡尾酒排序:', sort_number)
draw1(sort_number, sort_number[k])
if type == True:
break
def Quick_sort(sort_number,left_pointer,right_pointer,sort_type,loop_type): # 快速排序法
global location_point
if(left_pointer >= right_pointer):
return
if(loop_type == 0):
print("双边循环")
location_point = Bilateral_loop(sort_number,left_pointer,right_pointer,sort_type)
Quick_sort(sort_number,left_pointer,location_point-1,sort_type,loop_type)
Quick_sort(sort_number,location_point+1,right_pointer,sort_type,loop_type)
elif(loop_type == 1):
print("单边循环")
location_point = Unilateral_loop(sort_number,left_pointer,right_pointer,sort_type)
print("第一个:")
Quick_sort(sort_number, left_pointer, location_point - 1, sort_type, loop_type)
print("第二个:")
Quick_sort(sort_number, location_point + 1, right_pointer, sort_type, loop_type)
def Bilateral_loop(sort_number,start_pointer,end_pointer,sort_type): # 双边循环法
global pivot
global left
global right
pivot = sort_number[start_pointer]
print('基准:',pivot)
left = start_pointer
right = end_pointer
while(left != right):
print(sort_type)
while((left<right and sort_number[right]>pivot and sort_type == 0) or
(left<right and sort_number[right]<pivot and sort_type == 1)):
right-=1
while((left<right and sort_number[left]<=pivot and sort_type == 0) or
(left<right and sort_number[left]>=pivot and sort_type == 1)):
left+=1
if(left<right):
item = sort_number[left]
sort_number[left] = sort_number[right]
sort_number[right] = item
print('快速排序(双边循环):',sort_number)
draw1(sort_number, sort_number[left])
sort_number[start_pointer] = sort_number[left]
sort_number[left] = pivot
print('快速排序(双边循环):', sort_number)
draw1(sort_number, sort_number[left])
return left
def Unilateral_loop(sort_number,start_pointer,end_pointer,sort_type):
if(start_pointer >= end_pointer):
return
pivot = sort_number[start_pointer]
mark = start_pointer
print('快速排序(单边循环)0:', sort_number)
#print('基准:', pivot,'mark:',mark)
for i in range(start_pointer+1,end_pointer+1):
print("i:",i)
if(sort_number[i]<pivot and sort_type == 0) or\
(sort_number[i]>pivot and sort_type == 1):
mark+=1
print("对调:",sort_number[mark],"和",sort_number[i])
p = sort_number[mark]
sort_number[mark] = sort_number[i]
sort_number[i] = p
draw1(sort_number,sort_number[mark])
print('sort_number:', sort_number[i], '基准:', pivot, 'mark:', mark)
print('快速排序(单边循环)1:', sort_number)
sort_number[start_pointer] = sort_number[mark]
sort_number[mark] = pivot
draw1(sort_number, sort_number[mark])
print('快速排序(单边循环)2:', sort_number)
print('基准:', pivot, 'mark:', mark)
#print('快速排序(单边循环):', sort_number)
return mark
def draw1(l, v): # 绘制单个变化
plt.cla()
# 绘制列表柱状图
x = [x + 1 for x in range(len(l))]
bar = plt.bar(x, l)
# 绘制数值
for a, b in zip(x, l):
plt.text(a, b + 0.05, '%.0f' % b, ha='center', va='bottom', fontsize=11)
# 绘制当前移动的数
for ba, y in zip(bar, l):
if y == v:
ba.set(color="red")
plt.pause(0.01)
if __name__ == '__main__':
sort_type = str(input("请输入排序类型【冒泡(bubble)鸡尾酒(cocktail)快速(quick)】\n:"))
sort_way = int(input("请输入排序方式【正序(0)倒序(1)】:"))
print(sort_type,sort_way)
if sort_type == str('bubble'):
bubble(number,int(sort_way))
elif sort_type == 'cocktail':
Cocktail_sort(number,int(sort_way))
elif sort_type == 'quick':
sort_loop_type = int(input("请输入循环排序方式【双边循环(0)单边循环(1)】:"))
Quick_sort(number,0,len(number)-1,sort_way,sort_loop_type)
else :print("(!)输入错误,请重新输入")
print("最终结果",number)
plt.show()