目录
排序算法 | 平均时间复杂度 | 空间复杂度 | 稳定性 | 备注 |
直接插入排序 | O(n^2) | O(1) | 1 | 小规模数据 |
冒泡排序 | O(n^2) | O(1) | 1 | 小规模数据 |
简单选择排序 | O(n^2) | O(1) | 0 | 小规模数据 |
希尔排序 | O( | O(1) | 0 | 中等大小规模数据 |
快速排序 | O( | O(logn) | 0 | n 很大时,且有序程度高时 |
堆排序 | O( | O(1) | 0 | n 很大时,且有序程度低时 |
归并排序 | O( | O(n) | 1 | n 比较小时选取 |
基数排序 | O( | O( | 1 | R为0-9,B为基数(个十百) |
计数排序(桶排序) | O(n) | O(n) | 0 | 范围比较小 |
一、插入排序
从无序区中选取第一个元素,按关键字大小,插入有序区适当位置。
1、直接插入排序
将无序区中的元素,通过顺序查找,依次和有序区的元素进行比较,并插入适当位置。
Java 版本
public static int[] InsertSort(int[] nums) {
for(int i=1; i<nums.length; i++) {
int temp = nums[i], j = 0;
for(j=i; temp < nums[j-1] && j>0; j--)
nums[j] = nums[j-1];
nums[j] = temp;
}
return nums;
}
Python 版本
def sortArray(self, nums):
for i in range(1, len(nums)):
temp = nums[i]
index = i
for j in range(i, 0, -1):
if temp < nums[j-1]:
nums[j] = nums[j-1]
index = j - 1
nums[index] = temp
return nums
2、二分插入排序
插入的位置,采用二分查找确定。
Java 版本
public static int[] BinaryInsertSort(int[] nums) {
for(int i=1; i<nums.length; i++) {
int temp = nums[i], j = 0;
int left=0, right=i-1;
while(left <= right){
int mid=(left+right)/2;
if (temp > nums[mid])
left = mid+1;
else
right = mid-1;
}
for(j=i; j>left; j--)
nums[j] = nums[j-1];
nums[j] = temp;
}
return nums;
}
Python 版本
def function(nums):
for i in range(1, len(nums)):
temp = nums[i]
index = i
low = 0
high = i-1
while low <= high:
mid = int((low + high) / 2)
if nums[mid] < temp:
low = mid + 1
else:
high = mid - 1
for j in range(i, low, -1):
nums[j] = nums[j - 1]
index = j - 1
nums[index] = temp
3、希尔排序
将代拍数组分成若干小组,间隔为步长 d 的元素在同一组,每个小组内部进行直接插入排序。逐步减少步长,重复,直至步长为1,并且数组有序。
public static int[] sort(int[] nums){
int n = nums.length;
for(int gap=n/2; gap>0; gap = gap/2){
for(int j = gap; j < n; j++){
for(int i=j; i >= gap && nums[i-gap] > nums[i]; i -= gap){
int temp = nums[i-gap];
nums[i-gap] = nums[i];
nums[i] = temp;
}
}
}
return nums;
}
二、交换排序
1、冒泡排序
将待排数组从后往前两两比较相邻元素,逆序交换,直到数组有序。
Java 版本
public static int[] BubbleSort(int[] nums) {
for(int i=0; i<nums.length; i++) {
for(int j=nums.length-1; j>i; j--) { // for(int j=i; j>0; j--) {
if(nums[j-1] > nums[j]) {
int temp = nums[j];
nums[j] = nums[j-1];
nums[j-1] = temp;
}
}
}
return nums;
}
Python 版本
def sortArray(self, nums):
for i in range(0, len(nums)):
for j in range(len(nums)-1, i-1, -1):
if nums[j] < nums[j-1]:
nums[j], nums[j-1] = nums[j-1], nums[j]
return nums
2、快速排序
从数组中选取一个元素为基准元素,让每个元素依次和基准元素比较,比基准元素大的,交换到基准元素之后,比基准元素小的,交换到基准元素之前。
再分别对基准元素前后的两组元素,重复上述操作,直到有序。
Java 版本
// 递归快排
public static void RecursiveSort(int[] nums, int low, int high) {
if(low >= high)
return;
int mid = partition(nums, low, high);
RecursiveSort(nums, low, mid-1);
RecursiveSort(nums, mid+1, high);
}
// 栈快排
public static void StackSort(int[] nums, int low, int high) {
Stack<Integer> stack = new Stack<Integer>();
stack.push(high);
stack.push(low);
while(!stack.isEmpty()) {
int left = stack.pop();
int right = stack.pop();
int mid = partition(nums, left, right);
if(left < mid) {
stack.push(mid-1);
stack.push(left);
}
if(mid < right) {
stack.push(right);
stack.push(mid+1);
}
}
}
public static int partition(int[] nums, int low, int high) {
int index = low;
for(int i=low; i<high; i++) {
if(nums[i] < nums[high]) {
int temp = nums[i];
nums[i] = nums[index];
nums[index++] = temp;
}
}
int temp = nums[high];
nums[high] = nums[index];
nums[index] = temp;
return index;
}
Python 版本
def stack_sort(nums, low, high):
stack = []
stack.append(high)
stack.append(low)
while len(stack) > 0:
left = stack.pop()
right = stack.pop()
mid = partition(nums, left, right)
if left < mid:
stack.append(mid - 1)
stack.append(left)
if mid < right:
stack.append(right)
stack.append(mid + 1)
def recursive_sort(nums, low, high):
if low >= high:
return
mid = partition(nums, low, high)
recursive_sort(nums, low, mid-1)
recursive_sort(nums, mid+1, high)
def partition(nums, low, high):
index = low
for i in range(low, high):
if nums[i] < nums[high]:
nums[index], nums[i] = nums[i], nums[index]
index += 1
nums[index], nums[high] = nums[high], nums[index]
return index
三、选择排序
1、简单选择排序
每次从无序区中选择最小的元素,和数组的第 i 个元素进行交换,直到全部有序。
Java 版本
public static int[] SelectSort(int[] nums) {
for(int i=0; i<nums.length; i++) {
int index = i;
for(int j=i; j<nums.length; j++) {
if(nums[index] > nums[j]) {
index = j;
}
}
int temp = nums[index];
nums[index] = nums[i];
nums[i] = temp;
}
return nums;
}
Python 版本
def sortArray(self, nums):
for i in range(0, len(nums)):
temp = nums[i]
index = i
for j in range(i+1, len(nums)):
if temp > nums[j]:
temp = nums[j]
index = j
nums[i], nums[index] = nums[index], nums[i]
return nums
2、堆排序
将待排数组,看成完全二叉树,每次都通过比较父节点和左右子结点的大小,将最大/小的元素调整到根节点。重复,直到数组有序。
Java 版本
public static void heapSort(int[] nums) {
for (int i = (nums.length - 1)/2; i >= 0; i--)
adjustHeap(nums, i, nums.length);
for (int i = nums.length - 1; i > 0; i--) {
int temp = nums[i];
nums[i] = nums[0];
nums[0] = temp;
adjustHeap(nums, 0, i);
}
}
private static void adjustHeap(int[] nums, int parent, int length) { // 小根堆
int temp = nums[parent];
int maxlChild = 2 * parent + 1;
while (maxlChild < length) {
if (maxlChild+1 < length && nums[maxlChild] < nums[maxlChild+1])
maxlChild++;
if (temp >= nums[maxlChild])
break;
nums[parent] = nums[maxlChild];
parent = maxlChild;
maxlChild = 2 * maxlChild + 1;
}
nums[parent] = temp;
}
Python 版本
def adjust_heap(self, nums, parent, length):
temp = nums[parent]
max_child = 2 * parent + 1
while max_child < length:
if max_child + 1 < length and nums[max_child] < nums[max_child+1]:
max_child += 1
if temp >= nums[max_child]:
break
nums[parent] = nums[max_child]
parent = max_child
max_child = max_child * 2 + 1
nums[parent] = temp
def sortArray(self, nums):
half = len(nums) // 2
for i in range(half, -1, -1):
adjust_heap(nums, i, len(nums))
for i in range(len(nums)-1, 0, -1):
nums[0], nums[i] = nums[i], nums[0]
adjust_heap(nums, 0, i)
return nums
四、归并排序
通过递归思想,将数组分成两半,然后,递归合并两个有序子数组合。
Java 版本
public static int Merge(int[] nums, int left, int right) {
if(left == right) return 0;
int mid = (left + right) / 2;
int count = Merge(nums, left, mid) + Merge(nums, mid+1, right);
count = megerSort(nums, left, mid, right, count);
return count;
}
private static int megerSort(int[] nums, int left, int mid, int right, int count) {
int len_l = mid - left + 1, len_r = right - mid;
int[] l = new int[len_l];
int[] r = new int[len_r];
for(int i=0, k=left; i<len_l; i++)
l[i] = nums[k++];
for(int i=0, k=mid+1; i<len_r; i++)
r[i] = nums[k++];
int i, j, k;
for(i=len_l-1,j=len_r-1,k=right; i>=0 && j>=0; k--) {
if(l[i] > r[j]) {
count += j + 1; // 求逆序对,只多了这一行代码
nums[k] = l[i--];
}
else
nums[k] = r[j--];
}
for(int x=i; x>=0; x--)
nums[k--] = l[x];
for(int x=j; x>=0; x--)
nums[k--] = r[x];
return count;
}
Python 版本
def merge_sort(nums, low, mid, high):
left = []
right = []
for i in range(low, mid+1):
left.append(nums[i])
for i in range(mid+1, high+1):
right.append(nums[i])
index_l = 0
index_r = 0
index_nums = low
while index_l < len(left) and index_r < len(right):
if left[index_l] > right[index_r]:
nums[index_nums] = right[index_r]
index_r += 1
else:
nums[index_nums] = left[index_l]
index_l += 1
index_nums += 1
if index_l < len(left):
nums[index_nums] = left[index_l]
index_l += 1
index_nums += 1
if index_r < len(right):
nums[index_nums] = right[index_r]
index_r += 1
index_nums += 1
print(nums)
def merge(nums, low, high):
if low == high:
return
mid = int((low + high) / 2)
merge(nums, low, mid)
merge(nums, mid + 1, high)
merge_sort(nums, low, mid, high)
五、编程题
问题描述:在一组字符串中,找到所有具有某个字符串前缀字符串,比如application、apple、eyes、cats等。如果要匹配的字符串是app,则符合匹配条件的有application、apple。