1、冒泡排序(Bubble Sort)
冒泡排序算法的原理:
- 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
- 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
- 针对所有的元素重复以上的步骤,除了最后一个。
- 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
动图演示:
代码实现:
import numpy
#产生随机10个1到100的数字
def loadData():
data = numpy.random.randint(1,100,10)
return data
#进行冒泡排序
def sort(data):
n = len(data)
for i in range(1,n):
for j in range(n-i):
if data[j] > data[j+1]:
data[j],data[j+1] = data[j+1],data[j]
return data
data = loadData()
print(data)
sortData = sort(data)
print(sortData)
2、选择排序(Selection Sort)
选择排序算法的原理:
- 简单选择排序的基本思想:第1趟,在待排序记录r[1]r[n]中选出最小的记录,将它与r[1]交换;第2趟,在待排序记录r[2]r[n]中选出最小的记录,将它与r[2]交换;以此类推,第i趟在待排序记录r[i]~r[n]中选出最小的记录,将它与r[i]交换,使有序序列不断增长直到全部排序完毕。
以下为简单选择排序的存储状态,其中大括号内为无序区,大括号外为有序序列:
- 初始序列:{49 27 65 97 76 12 38}
- 第1趟:12与49交换:12{27 65 97 76 49 38}
- 第2趟:27不动 :12 27{65 97 76 49 38}
- 第3趟:65与38交换:12 27 38{97 76 49 65}
- 第4趟:97与49交换:12 27 38 49{76 97 65}
- 第5趟:76与65交换:12 27 38 49 65{97 76}
- 第6趟:97与76交换:12 27 38 49 65 76 97 完成
动图演示
代码实现
import numpy
#产生随机10个1到100的数字
def loadData():
data = numpy.random.randint(1,100,10)
return data
#进行选择排序
def sort(data):
n = len(data)
for i in range(n-1):
minIndex = i
for j in range(i+1,n):
if data[j] < data[minIndex]:
minIndex = j
data[minIndex],data[i] = data[i],data[minIndex]
return data
data = loadData()
print(data)
sortData = sort(data)
print(sortData)
3、插入排序(Insertion Sort)
插入排序算法的原理:
- 从第一个元素开始,该元素可以认为已经被排序;
- 取出下一个元素,记为temp,判断是否小于前一个元素(已排序),否则重复步骤2,是则继续下一个步骤
- 在已经排序的元素序列中从后向前扫描,如果该元素(已排序)大于temp,将该元素移到它的下一位置
- 重复步骤3,直到找到已排序的元素小于或者等于temp的位置或者找到第一个元素的位置
- 将新元素插入到该位置后(如果temp小于第一个元素,则将temp插在第一的位置)
- 重复步骤2~5
动图演示
代码实现
import numpy
#产生随机10个1到100的数字
def loadData():
data = numpy.random.randint(1,100,10)
return data
#进行插入排序
def sort(data):
n = len(data)
for i in range(1,n):
j = i - 1
if data[i] < data[j]:
temp = data[i]
data[i] = data[j]
j = j - 1
while j >= 0 and data[j]>temp:
data[j+1] = data[j]
j -= 1
data[j+1] = temp
data = loadData()
print(data)
sort(data)
print(data)
4、希尔排序(Shell Sort)
希尔排序算法的原理:
- 将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的)。
- 每个子序列分别进行直接插入排序。
- 缩减增量再重复步骤1、2,直到增量为1(此时整个序列的元素已经基本有序,使用直接插入法效率也比较高)。
动图演示
代码实现
import numpy
#产生随机10个1到100的数字
def loadData():
data = numpy.random.randint(1,100,10)
return data
#进行希尔排序
def sort(data):
num = len(data)
gas = num // 2
while gas > 0:
for i in range(gas,num):
for j in range(i,0,-gas):
if data[j] < data[j-gas]:
data[j],data[j-gas] = data[j-gas],data[j]
gas //= 2
return data
data = loadData()
print(data)
sortData = sort(data)
print(sortData)
5、归并排序(Merge Sort)
归并排序算法的原理:
- 把长度为n的待排数据分成两个长度为n/2的子数据;
- 对这两个子数据分别采用归并排序;
- 将两个排序好的子数据合并成一个最终的排序好的数据。
动图演示
代码实现
import numpy
#产生随机10个1到100的数字
def loadData():
data = numpy.random.randint(1,100,10)
return data
def merge(listLeft,listRight):
temp = []
i = j =0
while i < len(listLeft) and j < len(listRight):
if listLeft[i] < listRight[j]:
temp.append(listLeft[i])
i += 1
else:
temp.append(listRight[j])
j += 1
if i == len(listLeft):
temp.extend(listRight[j:])
else:
temp.extend(listLeft[i:])
return temp
#进行归并排序
def sort(data):
if len(data) <= 1:
return data
middle = len(data) // 2
listLeft = sort(data[:middle])
listRight = sort(data[middle:])
return merge(listLeft,listRight)
data = loadData()
print(data)
sortData = sort(data)
print(sortData)
print(data)
6、快速排序(Mer Sort)
快速排序算法的原理:
- 选取一个数字作为基准,可选取末位数字
- 将数列第一位开始,依次与此数字比较,如果小于此数,将小数交换到左边,最后达到小于基准数的在左边,大于基准数的在右边,分为两个数组
- 分别对两个数组重复上述步骤
动图演示
代码实现
import numpy
#产生随机10个1到100的数字
def loadData():
data = numpy.random.randint(1,100,10)
return data
#进行快速排序
def sort(data,l,r):
if l < r:
divIndex = partition(data,l,r)
sort(data,l,divIndex-1)
sort(data,divIndex+1,r)
return data
def partition(data,l,r):
judgeValue = data[r]
i = l - 1
for j in range(l,r):
if data[j] < judgeValue:
i += 1
data[i],data[j] = data[j],data[i]
data[i + 1],data[r] = data[r],data[i + 1]
return i + 1
data = loadData()
print(data)
sortData = sort(data,0,len(data)-1)
print(sortData)
7、堆排序(Heap Sort)
堆排序算法的原理:
- 建立堆
- 得到堆顶元素,为最小元素
- 去掉堆顶,将堆最后一个元素放到堆顶,此时可通过一次调整重新使堆有序。
- 堆顶元素为第二小元素。
- 重复步骤3,直到堆变空。
动图演示
代码实现
import numpy
#产生随机10个1到100的数字
def loadData():
data = numpy.random.randint(1,100,10)
return data
def sift(data, low, high):
i = low
j = 2 * i + 1
tmp = data[i]
while j <= high: #
if j < high and data[j] < data[j + 1]:
j += 1
if tmp < data[j]:
data[i] = data[j]
i = j #
j = 2 * i + 1
else:
break
data[i] = tmp #
def sort(data):
n = len(data)
# 创建堆
for i in range(n//2-1, -1, -1):
sift(data, i, n-1)
# 挨个出数
for i in range(n-1, -1, -1): # 从大到小
data[0], data[i] = data[i], data[0] # 将最后一个值与父节点交互位置
sift(data, 0, i-1)
data = loadData()
print(data)
sort(data)
print(data)