编写一个关于对序列进行排序的方法类
排序一共有八种经典的算法,对于任何待排序的序列,我们定义一个类实现对序列的排序的方法类
排序算法的原理
交换类排序
- 冒泡排序是重复的遍历待排序的序列,每次比较两个元素,如果大小顺序错误则交换其顺序,直至没有需要交换的元素时则序列排序完成,经过不断地交换,最大(最小的)元素会慢慢的浮出,具体步骤:
a. 比较相邻的元素,若第一个比第二个元素大,则交换其顺序;
b. 对每一对相邻元素做同样的工作,从第一对到最后一对,这样可以找出最大的数;
c. 针对剩余的元素重复上面的步骤,每次总能找到当前待排序序列的最大元素;
d. 每次找出当前待排序序列的最大元素,这样待排序序列的元素不断减少,直到没有待排序的序列。
- 快速排序使用分治法将一个待排序的序列分为两个子序列,对这样两个执行快速排序,不断分治,直到排序完成。具体的步骤:
a. 从当前待排序序列中找出一个元素,作为基准元素;
b. 重新排序该序列,所有待排序的元素中,比基准元素小的放在前一个子序列中,比基准元素大的放在后一个子序列中(至于与基准元素相同的可以放在任一边的子序列中),这样一来,基准元素就处于正确的位置;
c. 采用递归的策略把小于基准元素的子序列和大于基准元素的子序列进行快速排序,直到子序列的只有一个元素时无法分治时递归结束。
选择类排序
直接选择排序是直接从当前待排序的序列中选出最大(最小的)一个元素,置于正确的位置,在从剩余的待排序元素中找出最大(最小的),直至所有的待排序元素全部排完,则排序结束。
堆排序是利用堆这样一种数据结构而设计的一种排序算法,堆是一种类似于完全二叉树的结构,同时具有性质:子节点的键值总是小于(或者大于)父节点的键值(小于的时候称为最大堆,大于的时候称为最小堆),需要进行升序排序时,构造最大堆,需要进行降序排序时,构造最小堆。堆排序(升序排序)的具体步骤如下:
a.创建当前待排序序列的最大堆:将当前所有数据重新排序,使其成为最大堆;
b.对创建的最大堆,其堆顶元素即是当前待排序序列的最大元素,此时即选出了最大元素,然后移除该堆顶节点;
c.对剩余的待排序序列进行最大堆排序的递归运算。
插入类排序
- 直接插入排序是每一步直接将一个待排序的元素插入到已经排序好的序列的合适位置处,直至全部元素插入完成则排序完成。具体实现步骤如下:
a. 从一个元素开始,默认为第一个元素已经排好序;
b. 取当前待排序序列的第一个元素,置于已经排好序的序列的正确位置;
c. 重复步骤b,直到所有元素都排好序,则排序完成。
- 希尔排序是一种插入类排序,是将整个待排序序列分组(按序号进行分组)成若干小的子序列分别进行插入排序。排序过程如下:
a. 先取一个正整数d1
归并排序
- 二路归并排序是一种将两个分别排好序的序列合并为一个序列的排序算法,利用递归法步骤如下:
a. 对于一个长度为n的待排序序列,首先将相邻的两个元素进行归并操作,这样得到n/2个子序列,对每个子序列进行排序,每个序列包含两个元素;
b. 将上述得到的序列再次进行归并,得到n/4个子序列,每个序列包含4个元素;
c. 重复上述步骤,知道所有元素归并为一个序列,则排序完成。
class SortMethods:
def __init__(self,Seq):
self.Seq = Seq
def BuddleSort(self):
# 待排序的列表为self.Seq
for i in range(len(self.Seq)-1,-1,-1):
for j in range(i):
if self.Seq[j] > self.Seq[j+1]:
self.Seq[j],self.Seq[j+1] = self.Seq[j+1],self.Seq[j]
return self.Seq
def BuddleSort_1(self):
n = len(self.Seq)
while n > 1:
for i in range(n-1):
if self.Seq[i] > self.Seq[i+1]:
self.Seq[i],self.Seq[i+1] = self.Seq[i+1],self.Seq[i]
n -= 1
return self.Seq
# 快速排序(采用递归实现)
def QuickSort(self):
less = []
pivotList = []
more = []
if len(self.Seq) <= 1:
return self.Seq
else:
pivot = self.Seq[0]
for i in self.Seq:
if i < pivot:
less.append(i)
elif i > pivot:
more.append(i)
else:
pivotList.append(i)
less = SortMethods(less).QuickSort() # 此处的递归调用一定要注意
more = SortMethods(more).QuickSort() # 此处的递归调用一定要注意
return less + pivotList + more
def QuickSort_1(self):
if len(self.Seq) <= 1:
return self.Seq
else:
pivot = self.Seq[0]
less = SortMethods([i for i in self.Seq if i<pivot]).QuickSort_1() # 此处的递归调用一定要注意
pivotList = SortMethods([i for i in self.Seq if i==pivot]).QuickSort_1() # 此处的递归调用一定要注意
more = SortMethods([i for i in self.Seq if i>pivot]).QuickSort_1()
return less + pivotList + more
# 直接选择排序
def SelectSort(self):
for i in range(len(self.Seq)):
for j in range(i+1,len(self.Seq)):
if self.Seq[j] < self.Seq[i]:
self.Seq[i],self.Seq[j] = self.Seq[j],self.Seq[i]
return self.Seq
# 堆排序
# 构造最大堆,如何通过调整构造最大堆
def max_heap(self,start,end):
root = start
while True:
child = root*2 + 1
if child > end:
break
# 在一颗完全二叉树中,所有叶节点均已满足最大堆的定义
# 对于非叶节点,先找出其左右子节点的较大者,与该非叶节点进行比较
# 若满足最大堆的定义,则不用调整,若不满足,交换该节点与较大的叶节点
if child + 1 <= end and self.Seq[child] < self.Seq[child+1]:
child = child + 1
if self.Seq[root] < self.Seq[child]:
# 此处交换父节点与叶节点的值使其满足最大堆的定义,并以此往下判断
self.Seq[root],self.Seq[child] = self.Seq[child],self.Seq[root]
root = child
else:
break
def HeapSort(self):
n = len(self.Seq)
k = n//2 - 1
# 创建第一个包含所有待排序元素的最大堆
for start in range(k,-1,-1):
SortMethods(self.Seq).max_heap(start,n-1)
# 找出最大元素后对剩余元素接着找出最大堆,依次进行循环直至剩余一个元素
for end in range(n-1,0,-1):
self.Seq[end],self.Seq[0] = self.Seq[0],self.Seq[end]
SortMethods(self.Seq).max_heap(0,end-1)
return self.Seq
# 直接插入排序
def InsertSort(self):
N = len(self.Seq)
for i in range(1,N):
key = self.Seq[i]
while i>0:
if self.Seq[i-1] > key:
self.Seq[i],self.Seq[i-1] = self.Seq[i-1],key
i -= 1
return self.Seq
def InsertSort_1(self):
N = len(self.Seq)
for i in range(1,N):
if self.Seq[i] < self.Seq[i-1]:
key = self.Seq[i]
for j in range(i-1,-1,-1):
if self.Seq[j] > key:
self.Seq[j+1],self.Seq[j] = self.Seq[j],key
return self.Seq
# 希尔排序
def ShellSort(self):
n = len(self.Seq)
d = n // 2
while d >= 1: # 步长为1时,循环终止
for i in range(d,n): # 对于self.Seq[d]---self.Seq[n-1]按照步长进行排序
temp = self.Seq[i]
j = i
# 组内比较,进行插入排序
while j >= d and temp < self.Seq[j-d]:
self.Seq[j] = self.Seq[j-d]
j -= d
self.Seq[j] = temp
d = d // 2
return self.Seq
def Merge(self,left,right):
l,r =0,0
result = []
while l<len(left) and r<len(right):
if left[l]<right[r]:
result.append(left[l])
l += 1
else:
result.append(right[r])
r += 1
result += left[l:]
result += right[r:]
return result
# 归并排序是一种递归方式的排序算法
def MergeSort(self):
if len(self.Seq) <= 1:
return self.Seq
middle = len(self.Seq) // 2
left = SortMethods(self.Seq[:middle]).MergeSort()
right = SortMethods(self.Seq[middle:]).MergeSort()
return SortMethods(self.Seq).Merge(left,right)
A = SortMethods([10,23,1,53,654,54,16,646,65,3155,546,31])
print(A.Seq)
[10, 23, 1, 53, 654, 54, 16, 646, 65, 3155, 546, 31]
A.BuddleSort_1()
[1, 10, 16, 23, 31, 53, 54, 65, 546, 646, 654, 3155]
A.BuddleSort()
[1, 10, 16, 23, 31, 53, 54, 65, 546, 646, 654, 3155]
A.QuickSort()
[1, 10, 16, 23, 31, 53, 54, 65, 546, 646, 654, 3155]
A.QuickSort_1()
[1, 10, 16, 23, 31, 53, 54, 65, 546, 646, 654, 3155]
A.InsertSort()
[1, 10, 16, 23, 31, 53, 54, 65, 546, 646, 654, 3155]
A.InsertSort_1()
[1, 10, 16, 23, 31, 53, 54, 65, 546, 646, 654, 3155]
A.HeapSort()
[1, 10, 16, 23, 31, 53, 54, 65, 546, 646, 654, 3155]
A.SelectSort()
[1, 10, 16, 23, 31, 53, 54, 65, 546, 646, 654, 3155]
A.ShellSort()
[1, 10, 16, 23, 31, 53, 54, 65, 546, 646, 654, 3155]
A.MergeSort()
[1, 10, 16, 23, 31, 53, 54, 65, 546, 646, 654, 3155]
B = SortMethods([10,23,1,53,654,26,111,108,50,22,666])
B.Seq
[10, 23, 1, 53, 654, 26, 111, 108, 50, 22, 666]
B.BuddleSort()
[1, 10, 22, 23, 26, 50, 53, 108, 111, 654, 666]
B.BuddleSort_1()
[1, 10, 22, 23, 26, 50, 53, 108, 111, 654, 666]
B.QuickSort()
[1, 10, 22, 23, 26, 50, 53, 108, 111, 654, 666]
B.QuickSort_1()
[1, 10, 22, 23, 26, 50, 53, 108, 111, 654, 666]
B.InsertSort()
[1, 10, 22, 23, 26, 50, 53, 108, 111, 654, 666]
B.InsertSort_1()
[1, 10, 22, 23, 26, 50, 53, 108, 111, 654, 666]
B.HeapSort()
[1, 10, 22, 23, 26, 50, 53, 108, 111, 654, 666]
B.SelectSort()
[1, 10, 22, 23, 26, 50, 53, 108, 111, 654, 666]
B.ShellSort()
[1, 10, 22, 23, 26, 50, 53, 108, 111, 654, 666]
B.MergeSort()
[1, 10, 22, 23, 26, 50, 53, 108, 111, 654, 666]