用python排序算法_Python - 八大排序算法

1、序言

本文使用Python实现了一些常用的排序方法。文章结构如下:

1.直接插入排序

2.希尔排序

3.冒泡排序

4.快速排序

5.简单选择排序

6.堆排序

7.归并排序

8.基数排序

上述所有的排序均写在一个Python自定义类中,作为成员函数。

2、排序方法详细介绍

1.直接插入排序

直接插入排序(Straight Insertion Sort)是一种最简单的排序方法,它的基本操作是一个值插入到已排好序的有序表中,从而得到一个新的、记录数增1的有序表。如下图所示:

564273-20200106151932103-1489460972.png

由上图可知若最初始的有序表即为数组的第一个元素。用Python实现如下:

defstraight_insertion_sort(self, value_list):"""直接插入排序

:param value_list: 无序列表

:return:"""

return self.__straight_insert(value_list)

@staticmethoddef __straight_insert(value_list):

sorted_list=[]

sorted_list.append(value_list.pop(0))for i inrange(0, len(value_list)):

tail= True #是否在尾部插入

insert_loc =0for j inrange(len(sorted_list)):if value_list[i] <=sorted_list[j]:

tail=False

insert_loc=jbreaksorted_list.append(value_list[i])#先将值插入尾部

if nottail:#移动值

for j in range(len(sorted_list) - 1, insert_loc, -1):

temp=sorted_list[j]

sorted_list[j]= sorted_list[j - 1]

sorted_list[j- 1] =tempreturn sorted_list

2.希尔排序

希尔排序(Shell’s Sort)又称“缩小增量排序”(Diminishing Incerement Sort),它也是一种数插入排序的方法,但在时间效率上较前面的排序方法有较大的改进。它的基本思想是:先将整个待排记录序列分割成若干个子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行一次直接插入排序。如下图所示:

564273-20200106152005120-1096826454.png

即根据增量将原序列分割成多个子序列进行直接插入排序。增量应不断减小,且最后一个增量为1。用Python实现如下:

defshells_sort(self, value_list):"""希尔排序

:param value_list: 待排序的无序列表

:return: 排序后的列表"""gap= len(value_list) // 2

while gap >= 1:

i=0while(i + gap)

start=i

gap_list=[]while start

gap_list.append(value_list[start])

start= start +gap

gap_list= self.__straight_insert(gap_list)

start=iwhile start

value_list[start]=gap_list.pop(0)

start+=gap

i+= 1gap//= 2sorted_list=value_listreturn sorted_list

3.冒泡排序

冒泡排序(Bubble Sort)的过程很简单。首先将第一个记录的关键字和第二个记录的关键字进行比较,若逆序(与需要的顺序相反),则将两个记录交换之,然后比较第二个记录和第三个记录的关键字,以此类推。为第一趟冒泡结束,接着对前n-1个记录继续进行上述的过程。这样重复的过程直至n-1=1结束。排序过程如下所示:

564273-20200106152031491-1105363606.png

用Python实现如下:

@staticmethoddefbubble_sort(value_list):"""冒泡排序

:param value_list: 待排序的无序列表

:return: 排序后的列表"""

for i in range(len(value_list) - 1):for j in range(i + 1, len(value_list)):if value_list[i] >value_list[j]:

value_list[i], value_list[j]=value_list[j], value_list[i]

sorted_list=value_listreturn sorted_list

4.快速排序

快速排序(Quick Sort)是对冒泡排序的一种改进。它的基本思想是,通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录继续进行排序,已达到整个序列有序。其排序思想如下:

首先任意选取一个记录(通常可选第一个记录)作为枢轴,然后按下述原则重新排列记录:将所有关键字较它小的记录都安置在它的位置之前,将所有关键字较它大的记录都安置在它的位置之后。一趟快速排序的具体做法是:设两个指针low和high,他们的初值分别为最低位置的下一个位置和最高位,设最低位置枢轴的关键字为pivotkey,则首先从high所指位置起向前搜索找到第一个关键字小于pivotkey的记录的枢轴记录互相交换。发生了交换后才从low所指向的位置起向后搜索,找到第一个关键字大于pivotkey的记录和枢轴记录互相交换。重复这两步直至low=how为止

如下图所示:

564273-20200106152128564-1489601762.png

特别要注意换方向的时机是发生了交换后,用Python实现如下:

defquick_sort(self, value_list):"""快速排序

:param value_list: 待排序的无序列表

:return: 排序后的列表"""low=0

high= len(value_list) - 1self.__qsort(value_list, low, high)

sorted_list=value_listreturnsorted_listdef __qsort(self, val_list, low, high):"""快速排序辅助函数

:param val_list: 无序列表

:param low: 低位

:param high: 高位

:return:"""

if low >=high:returnpivot_key=low

temp_low=pivot_key

temp_high=highwhile low

while low

temp=val_list[high]

val_list[high]=val_list[pivot_key]

val_list[pivot_key]=temp

pivot_key=highbreak #发生交换后,就换方向

else:

high-= 1

while low val_list[pivot_key]:

temp=val_list[low]

val_list[low]=val_list[pivot_key]

val_list[pivot_key]=temp

pivot_key=lowbreak #发生交换后,就换方向

else:

low+= 1self.__qsort(val_list, temp_low, pivot_key - 1)

self.__qsort(val_list, pivot_key + 1, temp_high)

5.简单选择排序

选择排序(Selection Sort)是一种简单直观的排序算法。它的基本思想是:每一趟在n-i+1(i=1,2,...,n-1)个记录中选取关键字最小的记录作为有序序列中第i个记录。简单选择排序:通过n-1次关键字的比较,从n-i+1个记录中选出关键字最小的记录,并和第i(1≤i≤n)个记录交换之。如下图所示:

564273-20200106152204551-1229161851.png

用Python实现如下:

@staticmethoddefsimple_selection_sort(value_list):"""简单选择排序

:param value_list: 待排序的无序列表

:return: 排序后的列表"""

for i inrange(len(value_list)):

min_val= 9999999

for j inrange(i, len(value_list)):if min_val >value_list[j]:

min_val=value_list[j]

count= 0 #如果有多个相同的最小值

for j inrange(i, len(value_list)):if min_val ==value_list[j]:

value_list[j], value_list[i+ count] = value_list[i +count], value_list[j]

sorted_list=value_listreturn sorted_list

6.堆排序

堆排序(Heap Sort)是指利用堆这种数据结构所设计的一种排序算法。堆的定义如下:

n个元素的序列{k1,k2,...,kn}当且仅当满足一下关系时,称之为堆。

564273-20200106152238622-1381647945.png

若将序列看成是一个完全二叉树,则堆的含义表明,完全二叉树中所有非终端节点均不大于(或不小于)其左、右孩子节点的值。由此,若序列是堆,则堆顶元素必为序列中的最小值(或最大值)。如下图所示:

564273-20200106152249982-612172871.png

至此,我们可以给出堆排序的过程:若在输出堆顶的最小值后,使得剩余n-1个元素的序列又建成一个堆,则得到n个元素中的次小值。如此反复执行,便能得到一个有序序列。

故整个堆排序可以大致分为两个过程:

·将无序序列建成堆。

·输出堆顶元素后,用类似建堆的方法调整堆。

如下两个图所示:

564273-20200106152303979-503458708.png

564273-20200106152315742-1742667521.png

根据堆排序的特点总结出两点注意事项:

1.利用把堆看成完全二叉树的特点,用完全二叉树的性质解决算法问题。

2.建堆的过程是从树种的最后一个非终端节点逆序开始调整的。

3.每调整一次需要检查前后是否依然保持堆的特征。

本文利用了二叉树的孩子兄弟表示法来生成二叉树(堆)的。代码如下:

classCldSibNode(object):"""私有内部类:孩子兄弟二叉链表节点"""

def __init__(self, val):

self.value=val

self.child=None

self.sibling=Nonedefheap_sort(self, value_list):"""堆排序

:param value_list: 待排序的无序列表

:return: 排序后的列表"""sorted_list=[]

root_node=self.CldSibNode(None)

self.__child_sibling(root_node, value_list, 0)for ct in range(1, len(value_list) // 2 + 1): #建堆

self.__adjust_heap(root_node, len(value_list) // 2 + 1 - ct, 1)for i in range(1, len(value_list) + 1): #堆排序

sorted_list.append(root_node.value) #输出堆顶元素

head =root_node

self.__shrink_heap(root_node, len(value_list) + 1 - i, 1, head)

self.__adjust_heap(root_node, 1, 1) #调整堆

returnsorted_listdef __child_sibling(self, node, value_list, ind):"""创建完全二叉树的左孩子右兄弟二叉链表

:param node: 当前节点

:param value_list: 待排序的无序列表

:param ind:

:return:"""

if ind >=len(value_list):returnnode.value=value_list[ind]if ind * 2 + 1

node.child= self.CldSibNode(None) #孩子

self.__child_sibling(node.child, value_list, ind * 2 + 1)if ind * 2 + 2

node.child.sibling= self.CldSibNode(None) #兄弟

self.__child_sibling(node.child.sibling, value_list, ind * 2 + 2)def __adjust_heap(self, root_node, last_ind, now_ind):if not root_node or not root_node.child: #不为空且有孩子

return

if now_ind ==last_ind:#需要调整的非终端节点

temp =root_node

cg=Falsewhiletemp.child:if temp.value >temp.child.value:

temp.value, temp.child.value=temp.child.value, temp.value

cg= True #发生交换

iftemp.child.sibling:if temp.value >temp.child.sibling.value:ifcg:#如果发生过交换

temp.value, temp.child.value =temp.child.value, temp.value

temp.value, temp.child.sibling.value=temp.child.sibling.value, temp.value

temp=temp.child.siblingcontinue

else:ifcg:#如果发生过交换

temp =temp.childcontinue

break

#递归

self.__adjust_heap(root_node.child, last_ind, now_ind * 2)ifroot_node.child.sibling:

self.__adjust_heap(root_node.child.sibling, last_ind, now_ind * 2 + 1)def __shrink_heap(self, root_node, last_ind, now_ind, head):if not root_node or now_ind * 2 >last_ind:#为空

return

if last_ind == now_ind * 2 + 1:

head.value=root_node.child.sibling.value

root_node.child.sibling=NonereturnTrueif last_ind == now_ind * 2:

head.value=root_node.child.value

root_node.child=NonereturnTrueifroot_node.child:

self.__shrink_heap(root_node.child, last_ind, now_ind * 2, head)

self.__shrink_heap(root_node.child.sibling, last_ind, now_ind * 2 + 1, head)

7.归并排序

归并排序(Merging Sort),“归并”的含义是将两个或两个以上的有序表组合成一个新的有序表。假设初始序列有n个记录,则可看成是n个有序的子序列,每个子序列的长度为1,然后两两归并,得到[n/2]个长度为2或1的有序子序列;再两两归并,……,如此重复,直至得到一个长度为n的有序序列为止,这种排序方法为2-路归并排序。算法的基本思想如下图所示:

564273-20200106152411417-1030023330.png

其中两个子序列的合并大有学问,基本思想就是:分别在两个序列头设置指针,比较两个序列指针所指的值的大小,将满足要求的值提取出来形成新列表,并将指针右移。当其中一个指针指向结尾之后时,表示其中一个列表已取尽,接着直接在新列表尾部连接另一个列表。如下图所示:

564273-20200106152423916-157140595.png

用Python实现如下:

@staticmethoddefmerging_sort(self, value_list):"""归并排序

:param value_list: 待排序的无序列表

:return: 排序后的新列表"""i=0while np.power(2, i)

count= np.power(2, i)

start=0

outer_temp=[]while start

other = start +count

temp=[]if other >=len(value_list):#另一边不存在:直接合并

outer_temp.extend(value_list[start: start +count])breakleft, right=0, 0while left < count or right =len(value_list):#右边提前结束

temp.extend(value_list[start + left: start +count])break

elif value_list[start + left] < value_list[other +right]:#左边更小

temp.append(value_list[start +left])

left+= 1

if left ==count:#左边遍历结束

temp.extend(value_list[other + right: other +count])break

else:#右边更小

temp.append(value_list[other +right])

right+= 1

if right ==count:#右边遍历结束

temp.extend(value_list[start + left: start +count])breakouter_temp.extend(temp)

start+= count * 2value_list=outer_temp

i+= 1sorted_list=value_listreturn sorted_list

8.基数排序

基数排序(Radix Sort)是一种非比较整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。由于整数也可以表达字符串(比如名字或日期)和特定格式的浮点数,所以基数排序也不是只能使用于整数。

564273-20200106152502524-496759605.png

排序时有两点需要注意:

1.每完成一趟排序,要清空队列。

2.队列的连接要找到第一个不为空的队列作为头,和绕开所有空队列。

用Python实现如下:

@staticmethoddefradix_sort(value_list):"""基数排序

:param value_list: 待排序的无序列表

:return: 排序后的新列表"""i=0

max_num=max(value_list)

n=len(str(max_num))while i

bucket_list = [[] for _ in range(10)]for x invalue_list:#找到位置放入桶数组

bucket_list[int(x / (10 ** i)) % 10].append(x)

value_list.clear()for x inbucket_list:#放回原序列

for y inx:

value_list.append(y)

i+= 1sorted_list=value_listreturn sorted_list

测试代码:

编写测试代码运行结果如下:

if __name__ == '__main__':

li= list(np.random.randint(1, 1000, 30))

my_sort=MySort()print("original sequence:", li)print("*" * 100)print("1.straight_insertion_sort:", my_sort.straight_insertion_sort(li.copy()))print("2.shells_sort:", my_sort.shells_sort(li.copy()))print("3.bubble_sort:", my_sort.bubble_sort(li.copy()))print("4.quick_sort:", my_sort.quick_sort(li.copy()))print("5.simple_selection_sort:", my_sort.simple_selection_sort(li.copy()))print("6.heap_sort:", my_sort.heap_sort(li.copy()))print("7.merging_sort:", my_sort.merging_sort(li.copy()))print("8.radix_sort:", my_sort.radix_sort(li.copy()))

测试运行结果:

original sequence: [424, 381, 234, 405, 554, 742, 527, 876, 27, 904, 169, 566, 854, 448, 65, 508, 226, 477, 12, 670, 408, 520, 774, 99, 159, 565, 393, 288, 149, 711]****************************************************************************************************

1.straight_insertion_sort: [12, 27, 65, 99, 149, 159, 169, 226, 234, 288, 381, 393, 405, 408, 424, 448, 477, 508, 520, 527, 554, 565, 566, 670, 711, 742, 774, 854, 876, 904]2.shells_sort: [12, 27, 65, 99, 149, 159, 169, 226, 234, 288, 381, 393, 405, 408, 424, 448, 477, 508, 520, 527, 554, 565, 566, 670, 711, 742, 774, 854, 876, 904]3.bubble_sort: [12, 27, 65, 99, 149, 159, 169, 226, 234, 288, 381, 393, 405, 408, 424, 448, 477, 508, 520, 527, 554, 565, 566, 670, 711, 742, 774, 854, 876, 904]4.quick_sort: [12, 27, 65, 99, 149, 159, 169, 226, 234, 288, 381, 393, 405, 408, 424, 448, 477, 508, 520, 527, 554, 565, 566, 670, 711, 742, 774, 854, 876, 904]5.simple_selection_sort: [12, 27, 65, 99, 149, 159, 169, 226, 234, 288, 381, 393, 405, 408, 424, 448, 477, 508, 520, 527, 554, 565, 566, 670, 711, 742, 774, 854, 876, 904]6.heap_sort: [12, 27, 65, 99, 149, 159, 169, 226, 234, 288, 381, 393, 405, 408, 424, 448, 477, 508, 520, 527, 554, 565, 566, 670, 711, 742, 774, 854, 876, 904]7.merging_sort: [12, 27, 65, 99, 149, 159, 169, 226, 234, 288, 381, 393, 405, 408, 424, 448, 477, 508, 520, 527, 554, 565, 566, 670, 711, 742, 774, 854, 876, 904]8.radix_sort: [12, 27, 65, 99, 149, 159, 169, 226, 234, 288, 381, 393, 405, 408, 424, 448, 477, 508, 520, 527, 554, 565, 566, 670, 711, 742, 774, 854, 876, 904]

总结

各个排序效率见下图:

564273-20200106152606997-804352282.png

可以得出以下几个结论:

1.从平均时间性能而言,快速排序最佳。

2.堆排序适用于n较大的数据。

3.基数排序是稳定的,时间复杂度较大的简单排序方法也是稳定的。

4.稳定性是由方法本身决定的。

5.没有最好的排序方法,视情况而定。

ContractedBlock.gif

ExpandedBlockStart.gif

#! /usr/bin/env python3#-*- coding:utf-8 -*-

#Author : MaYi#Blog : http://www.cnblogs.com/mayi0312/#Date : 2020-01-06#Name : mySort#Software : PyCharm#Note : 八大排序算法

importnumpy as npclassMySort(object):"""自定义一个排序的类"""

defstraight_insertion_sort(self, value_list):"""直接插入排序

:param value_list: 待排序的无序列表

:return: 排序后的列表"""

return self.__straight_insert(value_list)

@staticmethoddef __straight_insert(value_list):

sorted_list=[]

sorted_list.append(value_list.pop(0))for i inrange(0, len(value_list)):

tail= True #是否在尾部插入

insert_loc =0for j inrange(len(sorted_list)):if value_list[i] <=sorted_list[j]:

tail=False

insert_loc=jbreaksorted_list.append(value_list[i])#先将值插入尾部

if nottail:#移动值

for j in range(len(sorted_list) - 1, insert_loc, -1):

sorted_list[j], sorted_list[j- 1] = sorted_list[j - 1], sorted_list[j]returnsorted_listdefshells_sort(self, value_list):"""希尔排序

:param value_list: 待排序的无序列表

:return: 排序后的列表"""gap= len(value_list) // 2

while gap >= 1:

i=0while(i + gap)

start=i

gap_list=[]while start

gap_list.append(value_list[start])

start= start +gap

gap_list= self.__straight_insert(gap_list)

start=iwhile start

value_list[start]=gap_list.pop(0)

start+=gap

i+= 1gap//= 2sorted_list=value_listreturnsorted_list

@staticmethoddefbubble_sort(value_list):"""冒泡排序

:param value_list: 待排序的无序列表

:return: 排序后的列表"""

for i in range(len(value_list) - 1):for j in range(i + 1, len(value_list)):if value_list[i] >value_list[j]:

value_list[i], value_list[j]=value_list[j], value_list[i]

sorted_list=value_listreturnsorted_listdefquick_sort(self, value_list):"""快速排序

:param value_list: 待排序的无序列表

:return: 排序后的列表"""low=0

high= len(value_list) - 1self.__qsort(value_list, low, high)

sorted_list=value_listreturnsorted_listdef __qsort(self, val_list, low, high):"""快速排序辅助函数

:param val_list: 无序列表

:param low: 低位

:param high: 高位

:return:"""

if low >=high:returnpivot_key=low

temp_low=pivot_key

temp_high=highwhile low

while low

temp=val_list[high]

val_list[high]=val_list[pivot_key]

val_list[pivot_key]=temp

pivot_key=highbreak #发生交换后,就换方向

else:

high-= 1

while low val_list[pivot_key]:

temp=val_list[low]

val_list[low]=val_list[pivot_key]

val_list[pivot_key]=temp

pivot_key=lowbreak #发生交换后,就换方向

else:

low+= 1self.__qsort(val_list, temp_low, pivot_key - 1)

self.__qsort(val_list, pivot_key + 1, temp_high)

@staticmethoddefsimple_selection_sort(value_list):"""简单选择排序

:param value_list: 待排序的无序列表

:return: 排序后的列表"""

for i inrange(len(value_list)):

min_val= 9999999

for j inrange(i, len(value_list)):if min_val >value_list[j]:

min_val=value_list[j]

count= 0 #如果有多个相同的最小值

for j inrange(i, len(value_list)):if min_val ==value_list[j]:

value_list[j], value_list[i+ count] = value_list[i +count], value_list[j]

sorted_list=value_listreturnsorted_listclassCldSibNode(object):"""私有内部类:孩子兄弟二叉链表节点"""

def __init__(self, val):

self.value=val

self.child=None

self.sibling=Nonedefheap_sort(self, value_list):"""堆排序

:param value_list: 待排序的无序列表

:return: 排序后的列表"""sorted_list=[]

root_node=self.CldSibNode(None)

self.__child_sibling(root_node, value_list, 0)for ct in range(1, len(value_list) // 2 + 1): #建堆

self.__adjust_heap(root_node, len(value_list) // 2 + 1 - ct, 1)for i in range(1, len(value_list) + 1): #堆排序

sorted_list.append(root_node.value) #输出堆顶元素

head =root_node

self.__shrink_heap(root_node, len(value_list) + 1 - i, 1, head)

self.__adjust_heap(root_node, 1, 1) #调整堆

returnsorted_listdef __child_sibling(self, node, value_list, ind):"""创建完全二叉树的左孩子右兄弟二叉链表

:param node: 当前节点

:param value_list: 待排序的无序列表

:param ind:

:return:"""

if ind >=len(value_list):returnnode.value=value_list[ind]if ind * 2 + 1

node.child= self.CldSibNode(None) #孩子

self.__child_sibling(node.child, value_list, ind * 2 + 1)if ind * 2 + 2

node.child.sibling= self.CldSibNode(None) #兄弟

self.__child_sibling(node.child.sibling, value_list, ind * 2 + 2)def __adjust_heap(self, root_node, last_ind, now_ind):if not root_node or not root_node.child: #不为空且有孩子

return

if now_ind ==last_ind:#需要调整的非终端节点

temp =root_node

cg=Falsewhiletemp.child:if temp.value >temp.child.value:

temp.value, temp.child.value=temp.child.value, temp.value

cg= True #发生交换

iftemp.child.sibling:if temp.value >temp.child.sibling.value:ifcg:#如果发生过交换

temp.value, temp.child.value =temp.child.value, temp.value

temp.value, temp.child.sibling.value=temp.child.sibling.value, temp.value

temp=temp.child.siblingcontinue

else:ifcg:#如果发生过交换

temp =temp.childcontinue

break

#递归

self.__adjust_heap(root_node.child, last_ind, now_ind * 2)ifroot_node.child.sibling:

self.__adjust_heap(root_node.child.sibling, last_ind, now_ind * 2 + 1)def __shrink_heap(self, root_node, last_ind, now_ind, head):if not root_node or now_ind * 2 >last_ind:#为空

return

if last_ind == now_ind * 2 + 1:

head.value=root_node.child.sibling.value

root_node.child.sibling=NonereturnTrueif last_ind == now_ind * 2:

head.value=root_node.child.value

root_node.child=NonereturnTrueifroot_node.child:

self.__shrink_heap(root_node.child, last_ind, now_ind * 2, head)

self.__shrink_heap(root_node.child.sibling, last_ind, now_ind * 2 + 1, head)

@staticmethoddefmerging_sort(value_list):"""归并排序

:param value_list: 待排序的无序列表

:return: 排序后的新列表"""i=0while np.power(2, i)

count= np.power(2, i)

start=0

outer_temp=[]while start

other = start +count

temp=[]if other >=len(value_list):#另一边不存在:直接合并

outer_temp.extend(value_list[start: start +count])breakleft, right=0, 0while left < count or right =len(value_list):#右边提前结束

temp.extend(value_list[start + left: start +count])break

elif value_list[start + left] < value_list[other +right]:#左边更小

temp.append(value_list[start +left])

left+= 1

if left ==count:#左边遍历结束

temp.extend(value_list[other + right: other +count])break

else:#右边更小

temp.append(value_list[other +right])

right+= 1

if right ==count:#右边遍历结束

temp.extend(value_list[start + left: start +count])breakouter_temp.extend(temp)

start+= count * 2value_list=outer_temp

i+= 1sorted_list=value_listreturnsorted_list

@staticmethoddefradix_sort(value_list):"""基数排序

:param value_list: 待排序的无序列表

:return: 排序后的新列表"""i=0

max_num=max(value_list)

n=len(str(max_num))while i

bucket_list = [[] for _ in range(10)]for x invalue_list:#找到位置放入桶数组

bucket_list[int(x / (10 ** i)) % 10].append(x)

value_list.clear()for x inbucket_list:#放回原序列

for y inx:

value_list.append(y)

i+= 1sorted_list=value_listreturnsorted_listif __name__ == '__main__':

li= list(np.random.randint(1, 1000, 30))

my_sort=MySort()print("original sequence:", li)print("*" * 100)print("1.straight_insertion_sort:", my_sort.straight_insertion_sort(li.copy()))print("2.shells_sort:", my_sort.shells_sort(li.copy()))print("3.bubble_sort:", my_sort.bubble_sort(li.copy()))print("4.quick_sort:", my_sort.quick_sort(li.copy()))print("5.simple_selection_sort:", my_sort.simple_selection_sort(li.copy()))print("6.heap_sort:", my_sort.heap_sort(li.copy()))print("7.merging_sort:", my_sort.merging_sort(li.copy()))print("8.radix_sort:", my_sort.radix_sort(li.copy()))

完整代码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/306733.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

剑指offer-数组中的重复的数字-p39

数组 c中的STL中的vector (STL中的vector每次扩容量时&#xff0c;新的容量都是之前一次的两倍) 在c/c中&#xff0c;数组和指针是相互关联又有区别的两个概念。 关联&#xff1a;当我们声明一个数组时&#xff0c;其数组的名字也是一个指针&#xff0c;该指针指向数组的第一个…

尝鲜!.NET5实操之docker+k8s,这10个坑,你不得不知!

2016年发布了.NET Core第一个正式版本&#xff0c;2020年11月.NET5也正式来临了&#xff0c;技术日新月异&#xff0c;也有点让人应接不暇。在框架设计上&#xff0c;.NET Framework的全家桶理念&#xff0c;培养了一大批的CRUD&#xff0c;而.NET Core转变成了按需使用(Pay fo…

jdk解压版_命令行版的斗地主你玩过没?

相信大家都玩过斗地主游戏&#xff0c;或在现实中斗地主或在电脑和手机上斗地主&#xff0c;但你想过用命令行界面进行斗地主吗&#xff1f;先来张图体验一下&#xff1a;是不是觉得挺有意思&#xff0c;下面就带大家一起玩一下吧~部署命令行版斗地主1 环境准备该项目是基于jav…

c语言——什么时候使用getchar()读取换行符

做题的时候有时会用到getchar()接收换行符&#xff0c;然而让人困惑的是一般使用scanf("%s", str)这样的形式读取字符串的时候似乎并没有考虑这个问题。网上通常会给你讲大道理缓冲区啥的&#xff0c;然后听懂后自己得不得的出结论全看天赋&#xff08;摊手&#xff…

[项目更新] 集成RabbitMQ队列与EventBus总线

&#xff08;Blog.Core框架开发情况&#xff0c;着色部分为本次新增&#xff09;终于项目继续迭代更新了&#xff0c;在开源这两年多&#xff0c;也是感谢每一个支持Blog.Core项目的同学&#xff0c;同时也感谢每一个在生产环境中使用&#xff0c;并提出意见和建议的小伙伴&…

cv2.imread读取图像结果none_python cv2.imread 读取中文路径的图片返回为None的问题

此篇文章首发于我的csdn博客&#xff0c;见原文链接。使用cv2读取图片是常见的事情&#xff0c;但如果&#xff0c;输出图片形状大小时出现报错“ NoneType object has no attribute shape”&#xff0c;后来排查发现读取图片的返回值image为None&#xff0c; 这就说明图片根本…

利用模板化应对ERP业务模型的快速变化

源宝导读&#xff1a;ERP这类复杂系统中&#xff0c;业务模型是系统功能的核心抽象&#xff0c;但业务模型对于不同的客户会有差异&#xff0c;也会随着业务发展而变化。虽然可以对业务组件进行复用&#xff0c;但客户定制的成本依然较高&#xff0c;本文将讨论如何利用模板化应…

mockmvc get请求 tm的 一直404_大家快来看看404的兄弟姐妹

码个蛋(codeegg)第 624 次推文作者&#xff1a;xiaoxiunique博客&#xff1a;https://juejin.im/post/5cd2ea425188254459335583做开发的我们肯定少不了跟网络数据打交道&#xff0c;我们都知道&#xff0c;我们进行网络请求&#xff0c;无论成功还是失败&#xff0c;后台都会给…

网传不要升级.NET5的诸多原因,你赞同几个?

.NET5正式发布有十多天&#xff0c;博客园、知乎、技术群都讨论的非常热烈。关于项目是否迁移.NET5的话题讨论的尤为热烈&#xff0c;作为.NET十年老司机要告诉你&#xff0c;.NET5的迁移势在必行&#xff0c;当下就是最好的时机&#xff01;犹豫项目是否升级到.NET5的&#xf…

WPF开发的实用小工具 - 快捷悬浮菜单

WPF开发的实用小工具 - 快捷悬浮菜单❝本文由网友投稿&#xff0c;Dotnet9站长整理。站长觉得这小工具很实用&#xff0c;站长家里、公司也在尝试使用了。行文目录&#xff1a;这工具有什么用&#xff1f;正文源码获取及应用下载体验站长的建议1. 这工具有什么用&#xff1f;问…

accdb原有的数据怎么清除_VBA中利用数组对数据批量处理的方法

大家好&#xff0c;今日继续和大家分享VBA编程中常用的常用"积木"过程代码。这些内容大多是我的经验和记录&#xff0c;来源于我多年的经验。今日分享的是NO.225-NO.226&#xff0c;内容是&#xff1a;NO. 225&#xff1a;数组的赋值和回填工作表NO. 226&#xff1a;…

云南河道 kml文件_处理能力提升 4 倍 ,大疆智图 4 天完成 5 公里河道建模

马陵河是江苏省宿迁市老城区一条重要排涝河道&#xff0c;1974 年人工开挖而成&#xff0c;全长 5.2 km&#xff0c;汇水面积 11.6 km&#xff0c;居住人口 13.85 万人。河道水质长期处于黑臭状态&#xff0c;严重影响周边居民日常生活&#xff0c;被称为宿迁的“龙须沟”。宿迁…

linq 查询的结果会开辟新的内存吗?

一&#xff1a;背景 1. 讲故事昨天群里有位朋友问&#xff1a;linq 查询的结果会开辟新的内存吗&#xff1f;如果开了&#xff0c;那是对原序列集里面元素的深拷贝还是仅仅拷贝其引用&#xff1f;其实这个问题我觉得问的挺好&#xff0c;很多初学 C# 的朋友或多或少都有这样的疑…

问题 B: 十进制到二进制的转换

这个问题我们来用栈来实现 首先&#xff0c;我们先定义一个栈的结构体&#xff08;栈的结构体与链表的结构体不可同&#xff0c;栈的结构体第二项是用int定义栈的顶端; 而链表的第二项&#xff0c;是用struct定义一个指针&#xff09; struct stack{int data[10005];int top;…

javascript内存泄漏调试工具mac_node.js 内存泄漏的秘密

一直以来&#xff0c;跟踪 Node.js 的内存泄漏是一个反复出现的话题&#xff0c;人们始终希望对其复杂性和原因了解更多。并非所有的内存泄漏都显而易见。但是&#xff0c;一旦我们确定了其模式&#xff0c;就必须在内存使用率&#xff0c;内存中保存的对象和响应时间之间寻找关…

Leansoft再发招贤令:面试官徐磊有话讲 | IDCF

&#xff08;图片来源于网络&#xff09;2020是Leansoft成立的第五年&#xff0c;凭借专业的服务及实施能力&#xff0c;逐渐成长为国内唯一的端到端专业DevOps实施服务公司。Leansoft是一家怎样的公司呢&#xff1f;准确地说&#xff0c;我们其实是国内唯一一家提供端到端的De…

问题 B: 数塔问题

题目描述 有如下所示的数塔&#xff0c;要求从顶层走到底层&#xff0c;若每一步只能走到相邻的结点&#xff0c;则经过的结点的数字之和最大是多少&#xff1f; 输入 第一行是一个整数N(1 < N < 20)&#xff0c;表示数塔的高度&#xff0c;接下来用N个数字表示数塔&a…

e盾服务端源码_gRPC服务注册发现及负载均衡的实现方案与源码解析

今天聊一下gRPC的服务发现和负载均衡原理相关的话题&#xff0c;不同于Nginx、Lvs或者F5这些服务端的负载均衡策略&#xff0c;gRPC采用的是客户端实现的负载均衡。什么意思呢&#xff0c;对于使用服务端负载均衡的系统&#xff0c;客户端会首先访问负载均衡的域名/IP&#xff…

堆问题(最小堆变最大堆,堆删除,中序遍历)

2-6 设最小堆&#xff08;小根堆&#xff09;的层序遍历结果为 {8, 38, 25, 58, 52, 82, 70, 60}。用线性时间复杂度的算法将该堆调整为最大堆&#xff08;大根堆&#xff09;&#xff0c;然后连续执行两次删除最大元素操作&#xff08;DeleteMax&#xff09;。则该树的中序遍历…

推荐一款.NET Core开源爬虫神器:DotnetSpider

没有爬虫就没有互联网&#xff01;爬虫的意义在于采集大批量数据&#xff0c;然后基于此进行加工/分析&#xff0c;做更有意义的事情。谷歌&#xff0c;百度&#xff0c;今日头条&#xff0c;天眼查都离不开爬虫。去开源中国和Github查询C#的爬虫项目&#xff0c;仅有几个非常简…