1.插入排序
从后向前,将待插入之保存起来,与前面的数相比较,若满足条件,依次向后搬移,最终将key插入满足的位置
- 时间复杂度:O(n^2)
- 稳定性:稳定
- 适应场景:接近有序
void InsertSort(int arr[], int size){
for (int i = 1; i < size; i++)
{
int key = arr[i];
int end = i - 1;
while (key < arr[end] && end >= 0)
{
arr[end + 1] = arr[end];
end--;
}
arr[end + 1] = key;
}
}
2.希尔排序
将待排序序列依据步长(增量)划分为若干组,对每组分别进行插入排序。
- 时间复杂度:O(N^1.25-N^2)空间复杂度O(1)
- 稳定性: 不稳定
void ShellSort(int* array, int size)
{
int gap = size;
while (gap > 1){
gap = gap / 3 + 1;
for (int i = gap; i < size; i++){
int key = array[i];
int end = i - gap;
while (end >= 0 && key < array[end]){
array[end + gap] = array[end];
end = end - gap;
}
array[end + gap] = key;
}
}
}
void Swap(int * left, int * right){
int t;
t = *left;
*left = *right;
*right = t;
}
3.选择排序
找出最大(小)元素与最后一位交换,指向数组下表的变量减减,故内层循环条件为j<size-i
void SelectSort(int * array, int size){
for (int i = 0; i < size-1; i++){
int maxPos = 0;
for (int j = 1; j < size-i; j++){
if (array[j]>array[maxPos]){
maxPos = j;
}
}
if (maxPos!=size-i-1)
Swap(array + maxPos, array + size -i- 1);
}
}
//优化代码,双向选择
void SelectSort_OP(int * array, int size){
int begin = 0;
int end = size - 1;
while (begin < end){
int maxPos = begin;
int minPos = begin;
int i = begin;
while ( i<=end ){
if (array[i]>array[maxPos])
maxPos = i;
if (array[i] < array[minPos])
minPos = i;
i++;
}
if (maxPos != size - 1)
Swap(array + maxPos, array + end);
//如果条件满足,end与maxPos交换了
if (minPos == end)
minPos = maxPos;
if (minPos != 0)
Swap(array + minPos, array + begin);
begin++;
end--;
}
}
4.堆排序
void HeapAdjust(int * array, int size, int parent){
//默认child标记左孩子
int child = parent * 2 + 1;
while (child<size){
//找左右孩子中最大的
if (array[child + 1] > array[child]&&child+1<size)
child += 1;
//检测双亲是否满足堆的性质
if (array[child] > array[parent]){
Swap(array + child, array + parent);
parent = child;
child = parent * 2 + 1;
}
else
return;
}
}
void HeapSort(int* array, int size){
//建堆---升序(大堆) 降序(小堆)
//建堆 从倒数第一个非叶子节点 使用向下调整
int last = (size - 2) / 2;
for (; last >= 0; last--){
HeapAdjust(array, size,last);
}
//排序 堆删除
int end = size - 1;
while (end)
{
Swap(array + 0, array + end);
HeapAdjust(array, end, 0);
end--;
}
}
5.冒泡排序
void BubbleSort(int * array, int size){
for (int i = 0; i < size; ++i){
for (int j = 1; j < size-i; j++){
if (array[j-1]>array[j ])
Swap(array + j, array + j - 1);
}
}
}
6.快速排序
//这只是一种分割方法
int Partion(int * array, int left, int right){
int key = array[right - 1];
int begin = left;
int end = right - 1;
while (begin < end){
while (begin < end && array[begin] < key)
begin++;
while (begin<end&&array[end]>key)
end--;
Swap(array + begin, array + end);
}
//中间位置和基准值交换
Swap(array + begin, & key);
//返回基准值所在位置
return begin;
}
void QuickSort(int* array, int left, int right){
if (right - left > 1){
int div = Partion(array, left, right);
QuickSort(array, left, div);
QuickSort(array, div + 1, right);
}
}
7.归并排序
//将两个连续空间的数据整合到一个连续空间
void MergeData(int * array, int left, int mid, int right,int * temp){
int begin1 = left, end1 = mid;
int begin2 = mid, end2 = right;
int index = left;
while (begin1 < end1 && begin2<end2){
if (array[begin1] < array[begin2])
temp[index++] = array[begin1++];
else
temp[index++] = array[begin2++];
}
while (begin1 < end1)
temp[index++] = array[begin1++];
while (begin2 < end2)
temp[index++] = array[begin2++];
}
void _MergeSort(int* array, int left, int right,int * temp){
if (right - left>1){
int mid = left + (right - left) / 2;
_MergeSort(array, left, mid, temp);
_MergeSort(array, mid, right, temp);
MergeData(array, left, mid, right, temp);
memcpy(array + left, temp + left, sizeof(array[left]) * (right - left));
}
}
void MergeSort(int * array, int size){
int *temp = (int *)malloc(sizeof(array[0])* size);
if (temp == NULL){
return;
}
_MergeSort(array, 0, size, temp);
free(temp);
}