0.
1.冒泡排序
'''
冒泡排序
'''
def BubbleSort(array:list) -> list:
'''
冒泡排序就是两两比较,大的沉底或者小的上浮,
一共比较len(array)次,每次比较只比较还未最终上浮(下沉)的
时间复杂度:O(n^2) 空间复杂度:O(1)
'''
for times in range(len(array)):
for idx in range(len(array) - times - 1):
if array[idx + 1] < array[idx]:
array[idx + 1],array[idx] = array[idx],array[idx + 1]
return array
template<typename T>
void bubbleSort(T arr[], int length){
for (int i = 0; i < length; ++i){
for (int j = 0; j < length - i - 1; ++j){
if (arr[j] > arr[j + 1])
std::swap(arr[j], arr[j + 1]);
}
}
}
2.快速排序
'''
快速排序
'''
def QuickSort(array:list,left_index:int,right_index:int) -> list:
'''
采用分治法
初始时对第一个元素视为基准元素,应当排成基准元素的左边都比基准元素小,右边都比基准元素大.
然后用两个头尾指针.头指针向后,尾指针向前.
如果尾指针遇到比基准数小的,就和头指针互换,之后头指针向后,遇到比基准值大的,和尾指针互换,
之后尾指针再向前,重复这个过程.
头指针等于尾指针时结束,并将这个位置放入基准值.
分:将基准值的左右分开处理
治:分别按照上述算法处理
时间复杂度O(nlogn),空间复杂度O(nlogn)(采用递归)
'''
left , right = left_index , right_index
temp = array[left]
if not left < right:
return array
while left != right:
while array[right] >= temp and right > left:
right -= 1
if right == left:
array[left] = temp
break
else:
array[left] = array[right]
while array[left] <= temp and left < right:
left += 1
if left == right:
array[right] = temp
break
else:
array[right] = array[left]
QuickSort(array,left_index,left - 1)
QuickSort(array,left + 1,right_index)
return array
'''
利用快指针和慢指针来选择基准值应该在的位置(上个方法是头指针和尾指针)
快指针快速遍历整个序列,慢指针保证所有小于慢指针的索引的值都小于等于基准值
'''
def partition(array:list,left:int,right:int) -> int:
'''
找出基准值应插入的点
'''
if left == right:
return left
p = left
index = p + 1
for i in range(index,right + 1):
if array[i] < array[p]:
array[index] , array[i] = array[i] , array[index]
index += 1
array[p] , array[index - 1] = array[index - 1] , array[p]
return index - 1
def QuickSort(array:list,left_index:int,right_index:int) -> list:
'''
同理 递归
'''
if left_index < right_index:
p = partition(array,left_index,right_index)
QuickSort(array,left_index,p - 1)
QuickSort(array,p + 1,right_index)
return array
template<typename T>
void quickSort(T arr[], int length){
if (length < 2) return;
int pLeft = 0, pRight = length - 1;
T tempValue = arr[pLeft];
while(pLeft != pRight){
while(pRight > pLeft && arr[pRight] > tempValue) pRight--;
if (pRight == pLeft) break;
else {
arr[pLeft] = arr[pRight]; pLeft++;}
while(pRight > pLeft && arr[pLeft] < tempValue) pLeft++;
if (pRight == pLeft) break;
else {
arr[pRight] = arr[pLeft]; pRight--;}
}
arr[pLeft] = tempValue;
quickSort<T>(arr, pLeft);
quickSort<T>(arr + pLeft + 1, length - pLeft - 1);
}
3.简单插入排序
'''
插入排序
'''
def InsertSort(array:list) -> list:
'''
插入排序:
跟选择排序很像,初始将第一个元素视为有序,其余视为无序.从无序中
选择第一个元素,将其插入有序序列,与有序序列元素逐个比较,找到它的位置.
时间复杂度:O(n^2) 空间复杂度:O(1)
不能用递归实现,因为新元素还要在有序序列中排序,而不是像选择排序那样有序之后不管了.
'''
ordered = 1
while ordered < len(array):
item = array[ordered:][0]
insert_pos = ordered
for _ in range(ordered):
if item <= array[insert_pos - 1]:
insert_pos -= 1
else:
break
array = array[:insert_pos] + [item] + array[insert_pos : ordered] + array[ordered + 1:]
ordered += 1
return array
def InsertSort(array:list) -> list:
'''
更简单的实现,取无序第一个元素,在有序序列后面开始逐一比较
和法1不同的是没有明显地区分有序和无序
'''
for item in range(1,len(array)):
pre_index , current = item - 1 , array[item]
while pre_index >=0:
if current < array[pre_index]:
array[pre_index + 1] = array[pre_index]
pre_index -= 1
else:
break
array[pre_index + 1] = current
return array
template<typename T>
void insertionSort(T arr[], int length){
if (length < 2) return;
insertionSort<int>(arr, length - 1);
for (int idx = length - 1; idx > 0; --idx){
if (arr[idx] < arr[idx - 1])
std::swap(arr[idx], arr[idx - 1]);
}
}
4.简单选择排序
'''
选择排序
'''
def SelectionSort(array:list) -> list:
'''
简单选择排序:
初始:将整个序列视为无序序列,将无序序列最小的数与第一个数进行交换,并将第一个数认为有序序列
重复
时间复杂度:O(n^2) 空间复杂度:O(1)(用递归就不是了)
'''
if len(array) == 1:
return array
min_idx = 0
for idx in range(len(array)):
if array[min_idx] > array[idx]:
min_idx = idx
array[0],array[min_idx] = array[min_idx],array[0]
return [array[0]] + SelectionSort(array[1:])
template<typename T>
void selectionSort(T arr[], int length){
if (length < 2) return;
int minIndex = 0;
for (int idx = 1; idx < length; ++idx){
if (arr[idx] < arr[minIndex]) minIndex = idx;
}
std::swap(arr[0], arr[minIndex]);
selectionSort<T>(++arr, --length);
}
5.堆排序
'''
堆排序
'''
def adjust(array:list,length:int,node:int) -> None:
'''
调整树的结构,让树保持最大堆结构,也即保证父节点大于等于两个子节点.
node为父节点标号,length为arr长度
'''
largest = node
left , right = 2 * node + 1 , 2 * node + 2
if left < length and array[left] > array[largest]:
largest = left
if right < length and array[right] > array[largest]:
largest = right
if largest != node:
array[largest] , array[node] = array[node] , array[largest]
adjust(array,length,largest)
def HeapSort(array:list) -> list:
'''
堆排序就是首先将数组变为堆结构(任一父节点都不小于其子节点)
然后将堆的根节点(最大值)和最末,次末,...节点互换 然后调整堆
直到所有的节点都被换(遍历)过
'''
for node in range(len(array),-1,-1):
adjust(array,len(array),node)
for idx in range(len(array) - 1,-1,-1):
array[0] , array[idx] = array[idx] , array[0]
adjust(array,idx,0)
return array
6.二路归并排序
'''
归并排序
'''
from math import floor
def merge(array1:list,array2:list):
'''
将list1和list2合并成有序序列
由于array1和array2已经是有序的,因此只要逐位比较.将小的放入结果数组,
且将对应的指针右移.
'''
result = []
p1,p2 = 0,0
while p1 < len(array1) and p2 < len(array2):
if array1[p1] <= array2[p2]:
result.append(array1[p1])
p1 += 1
else:
result.append(array2[p2])
p2 += 1
if p1 == len(array1):
result += array2[p2:]
else:
result += array1[p1:]
return result
def MergeSort(array:list) -> list:
if len(array) == 1:
return array
return merge(MergeSort(array[:floor(len(array) / 2)]),MergeSort(array[floor(len(array) /2 ):]))
template<typename T>
void mergeArr(T arr[], int length1, int length2){
int totalLength = length1 + length2;
int p1 = length1 - 1, p2 = totalLength - 1;
T arr_[totalLength];
int idxOfArr_ = totalLength - 1;
while(idxOfArr_ >= 0){
if (p1 < 0){
arr_[idxOfArr_] = arr[p2];
--p2;
}
else if (p2 < length1){
arr_[idxOfArr_] = arr[p1];
--p1;
}
else if (arr[p2] > arr[p1]){
arr_[idxOfArr_] = arr[p2];
--p2;
}
else{
arr_[idxOfArr_] = arr[p1];
--p1;
}
--idxOfArr_;
}
for (int i = 0; i < totalLength; ++i) arr[i] = arr_[i];
}
template<typename T>
void mergeSort(T arr[], int length){
if (length < 2) return;
int length1 = length / 2, length2 = length - length1;
mergeSort<T>(arr, length1);
mergeSort<T>(arr + length1, length2);
mergeArr<T>(arr, length1, length2);
}