方便自己复习。
一、冒泡排序
跳过。
二、插入排序
时间复杂度:o(n^2)
空间复杂度:o(1)
稳定
void insert_Sort(int* arr, int size)
{
for (int i = 1; i < size; i++) //一个元素一定是有序的,因此从第二个开始
{
int j = i - 1;
int temp = arr[i]; //记录第一个
while (j >= 0 && arr[j] > temp) //拿的第二个与第一个比较
{
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = temp; //把第二个插入
} //以此类推
}
三、希尔排序
插入排序的升级版,在数据量很大的情况下效率高于插入排序
时间复杂度:o(nlog n)
空间复杂度:o(1)
不稳定
void shell_Sort(int* arr, int size)
{
for (int gap = size >> 1; gap > 0; gap >>= 1)
{
for (int i = gap; i < size; i++)
{
int j = i - gap;
int temp = arr[i];
while (j >= 0 && temp <= arr[j])
{
arr[j + gap] = arr[j];
j -= gap;
}
arr[j + gap] = temp;
}
}
}
与插入排序思想一致,不过是先将数据进行等分,这里采用右移的速度高于除法
四、选择排序
时间复杂度:o(n^2)
空间复杂度:o(1)
不稳定
void select_Sort(int* arr, int size)
{
for (int i = 0; i < size; i++)
{
int min = i;
for (int j = i + 1; j < size; j++)
{
if (arr[j] < arr[min])
{
min = j;
}
}
swap(&arr[i], &arr[min]);
}
}
这里是从第二个数开始找到最小数的下标,记录下来,最后与前一个交换对应的元素,就得到从小到大的序列。
五、快速排序
时间复杂度:o(nlog n)
空间复杂度:o(log n)
不稳定
void quick_Sort(int* arr, int L, int R)
{
if (L >= R)
return;
int left = L;
int right = R;
int pivot = arr[left];
while (left < right)
{
while (left < right && arr[right] >= pivot)
right--;
if (left < right)
arr[left] = arr[right];
while (left < right && arr[left] <= pivot)
left++;
if (left < right)
arr[right] = arr[left];
if (left >= right)
arr[left] = pivot;
}
quick_Sort(arr, L, left);
quick_Sort(arr, left + 1, R);
}
分组 --> 挖坑 --> 填坑 --> 递归
六、堆排序
时间复杂度:o(nlog n)
空间复杂度:o(1)
不稳定
void heapify(int* arr, int size, int i)
{
int largest = i;
int lchild = i * 2 + 1;
int rchild = i * 2 + 2;
if (arr[largest] < arr[lchild] && lchild < size)
{
largest = lchild;
}
if (arr[largest] < arr[rchild] && rchild < size)
{
largest = rchild;
}
if (largest != i)
{
swap(&arr[largest], &arr[i]);
heapify(arr, size, largest);
}
}
void heap_Sort(int* arr, int size)
{
int i = 0;
for (i = size / 2 - 1; i >= 0; i--) //这里范围必须大于等于0
{
heapify(arr, size, i);
}
for (i = size - 1; i > 0; i--) //这里最后一个arr[0]不用做操作,
{
swap(&arr[0], &arr[i]);
heapify(arr, i, 0);
}
}
假定二叉树结点i,那么左子树为:2 * i + 1,右子树:2 * i + 1
七、归并排序
时间复杂度:o(nlog n)
空间复杂度:o(n)
稳定
void merge(int* arr, int* temparr, int left, int mid, int right)
{
int l_pos = left;
int r_pos = mid + 1;
int pos = left;
while (l_pos <= mid && r_pos <= right)//小组排序
{
if (arr[l_pos] <= arr[r_pos])
temparr[pos++] = arr[l_pos++];
else
temparr[pos++] = arr[r_pos++];
}
while(l_pos <= mid)
temparr[pos++] = arr[l_pos++];
while(r_pos <= right)
temparr[pos++] = arr[r_pos++];
while (left < right) //复制回原数组
{
arr[left] = temparr[left];
left++;
}
}
void msort(int* arr, int* temparr, int left, int right)
{
if (left < right) //递归将其分组直至无法再分
{
int mid = ((right - left) >> 1) + left;
msort(arr, temparr, left, mid);
msort(arr, temparr, mid + 1, right);
merge(arr, temparr, left, mid, right);
}
}
void merge_Sort(int* arr, int size)
{ //为了不破坏原数组
int* temparr = (int*)malloc(sizeof(int) * size);//定义临时数组保存元素
msort(arr, temparr, 0, size - 1);
free(temparr);
}