内部排序
排序期间,元素全部存放在内存中的排序。并非所有内部排序都要基于比较操作,基数排序不基于比较。
关注时间复杂度、空间复杂度、稳定性
插入排序
- 直接插入排序
- 折半插入排序
- 希尔排序(缩小增量排序)
取一个递减数组 从中取步长 将需要排序的数组按步长分为子数组 进行插入排序 达到基本有序的状态 某些步长数组的平均时间复杂度可以达到1.3次方
交换排序
- 冒泡排序
- 快速排序
选择排序
- 简单选择排序
- 堆排序
注意建堆的两种方法,一个个插入的nlogn、满足完全二叉树后从根到底的perdown操作,复杂度为n
交换排序
- 冒泡排序
- 快速排序
归并排序
基数排序
按基数r(进制)和位数进行分配和收集过程的排序,可以从低位到高位,也可以从高位到低位 桶排序的思想和其近似 空间上需要r个“桶”,存放分配的元素 而分配过程的稳定性保证了排序结果的稳定性 分配和收集的过程不基于比较 时间复杂度为最长位数*r
外部排序
排序期间元素无法全部同时存放在内存中,必须得在排序的过程中根据要求不断在内外存中间移动的排序。
void bubbleSort(int *arr,int l,int r)
{
for (int i=l; i<r; i++) {
for (int j=i+1; j<r; j++) {
if (arr[i] > arr[j]) {
int t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}
}
}
}
int partition(int *arr,int l,int r)
{
int x = arr[l];
r--;
while (l<r)
{
while (arr[r]>=x && r>l)r--;
arr[l]=arr[r];
while (arr[l]<=x && r>l)l++;
arr[r]=arr[l];
}
arr[l]=x;
return l;
}
void quickSort(int *arr,int l,int r)
{
if (l >= r) {
return;
}
int pos = partition(arr, l, r);
quickSort(arr, l, pos);
quickSort(arr, pos+1, r);
}
int temp[N];
void merge(int *arr,int l, int r)
{
int mid = (l+r)>>1;
int p=l;
int q=mid;
int len=0;
while (p<mid && q<r)
{
if (arr[p]>arr[q])
{
temp[l+len]=arr[q++];
len++;
}
else
{
temp[l+len]=arr[p++];
len++;
}
}
while (p<mid)
{
temp[l+len]=arr[p++];
len++;
}
while (q<r)
{
temp[l+len]=arr[q++];
len++;
}
for (int i = l; i < r; ++i) {
arr[i] = temp[i];
}
}
void mergeSort(int *arr,int l, int r)
{
if (r-1==l)
return;
mergeSort(arr, l, (l+r)>>1);
mergeSort(arr, (l+r)>>1, r);
merge(arr,l,r);
}
class Heap {
public:
int heap[N];
int size;
void insert(int x)
{
size++;
int now = size;
for (; now/2 > 0; now/=2) {
if (heap[now/2] > x) {
heap[now] = heap[now/2];
} else {
break;
}
}
heap[now] = x;
}
int getMin()
{
return heap[1];
}
void deleteMin()
{
heap[1] = heap[size];
heap[size] = 0;
size--;
percDown(1);
}
void buildHeap()
{
//从有孩子结点的最大坐标往上,进行下滤操作
for (int i=size/2;i>0;i--)
{
percDown(i);
}
}
private:
/**
* 整理子堆 使其符合堆的性质 以下实现以小根堆为例
* @param p 子堆的根节点
*/
void percDown(int p)
{
int child;
int x = heap[p];
for (int parent = p; parent*2 <= size; parent = child) {
if (heap[parent*2] < heap[parent*2+1] || !heap[parent*2+1]) {
child = parent * 2;
} else {
child = parent * 2 + 1;
}
if (heap[child] < heap[parent]) {
heap[parent] = heap[child];
heap[child] = x;
} else {
break;
}
}
}
};