目录
冒泡排序
void BubbleSort(int arr[],int _size)
{
int i = 0;
for (; i < _size-1; ++i)
{
int j = 0;
for (; j < _size-1-i; ++j)
{
if (arr[j]>arr[j + 1])
{
Swap(&arr[j], &arr[j + 1]);
}
}
}
}
选择排序
/*
每一轮循环都把最小的数放在数组的前半部分
*/
void SelectSort(int arr[], int _size)
{
int i = 0;
int j = 0;
int min = 0;
for (i = 0; i < _size - 1; i++)//i之前为已排序数组
{
min = i;//min为已排序的后一位下标
for (j = i + 1; j < _size; j++)
{
if (arr[j] < arr[min])
{
min = j;//更新最小值的下标
}
}
if (arr[min] != arr[i])//如果min已被更新
{
Swap(&arr[min], &arr[i]);
}
}
}
插入排序
/*
插入排序
1.从第二个元素开始,标记该元素
2.逐个与前面的数比较
3.最后再把标记的元素放入合适位置
时间复杂度O(N^2)
*/
void InsertionSort(int arr[], int _size)
{
for (int i = 1; i < _size; i++)//从第二个开始
{
int key = arr[i];//标记即将插入的数字
int j = i - 1;//从key的前一位开始比较
while (j >= 0 && arr[j]>key)//在已排序队列中倒着找到比自己小那位
{
arr[j + 1] = arr[j];//比key大的往后挪
j--;
}
arr[j + 1] = key;
}
}
shell排序
1.先定好步长step * 3 + 1
2.以当前步长逐个向后比较
3.缩步长
void ShellSort(int arr[], int _size)
{
int i = 0;
int j = 0;
int key = 0;
int step = 0;
while (step < _size)
{
step = step * 3 + 1;//定步长
}
while (step>0)
{
for (i = step; i < _size; ++i)
{
key = arr[i];//先标记要交换的位置
j = i - step;//步长向前一位
while (j>=0&&arr[j]>key)//如果步长前面的数大于key
{
arr[j + step] = arr[j];//往后挪
j -= step;//步长往前踏
}
//当把步长内大于key的全部元素放到后面,再安置key
arr[j + step] = key;
}
step = (step - 1) / 3;//一轮挪完后
}
}
归并排序
1.定义一个第三方
2.一边从起始位置开始,一边从中间开始,比较小的先加入第三方
3.如果数组个数为奇数,看最后哪一方还剩下一个
4.把剩下的加进去
void Merge(int arr[], int start, int end, int mid)
{
int len = end - start + 1;
int* tmp = (int*)malloc(sizeof(int)*len);
int index = 0;
int i= start;
int j = mid + 1;
while (i<=mid&&j<=end)//任何一边到了末尾结束
{
tmp[index++] = (arr[i] <= arr[j] ? arr[i++]:arr[j++]);
}
while (i <= mid)//如果j先结束
{
tmp[index++] = arr[i++];
}
while (j <= end)//如果i先结束
{
tmp[index++] = arr[j++];
}
for (i = 0; i < len; i++)
{
arr[start++] = tmp[i];
}
}
//递归
void MergeSortRecur(int arr[], int start,int end)
{
if (start==end){
return;
}
int mid = (start + end) >> 1;
MergeSortRecur(arr, start, mid);
MergeSortRecur(arr, mid+1, end);
Merge(arr, start, end, mid);
}
//非递归
void MergeSortIter(int arr[], int size)
{
int left, mid, right;
//int i;
for (int i = 1; i < size; i *= 2)
{
left = 0;
while (left+i < size)
{
mid = left + i - 1;
right = mid + i < size ? mid + i : size - 1;
Merge(arr, left, right, mid);
left = right + 1;
}
}
}
快速排序
void QuickSort(int arr[], int start, int right)//先全体找出index
{
if (start>right)
{
return;
}
int index = arr[start];//将最左边的数作为基准值,这点要求了必须从右边开始
int i = start;
int j = right;
while (i != j) {
while (arr[j] >= index&&i < j)//从右往左找,知道找到比index小的为止
{
j--;
}
while (arr[i] <= index&&i < j)
{
i++;
}
if (i<j)//要是大于则不交换
Swap(&arr[i], &arr[j]);
}
arr[start] = arr[i];//走到这里因为是j先走,所以j可能先跳出循环,而i还停留在上一个小于index的位置上,即保
证arr[i]肯定是小于index的,所以才能交换
arr[i] = index;
QuickSort(arr, start, i - 1);//再找左半区的
QuickSort(arr, i + 1, right);//右半区
}
堆排序
void AdjustUp(int arr[],int index, int size)
{
int left = index * 2 + 1;
int right = index * 2 + 2;
int max = index;
if (left < size&&arr[left]>arr[max])//找较大的子节点
{
max = left;
}
if (right < size&&arr[right]>arr[max])//找较大的子节点
{
max = right;
}
if (max != index)
{
Swap(&arr[max], &arr[index]);
AdjustUp(arr, max, size);
}
}
void AdjustDown(int arr[], int index, int size)
{
int child = index * 2 + 1;//子节点
while (child<size)
{
if (child + 1<size && arr[child] > arr[child + 1])//子节点中找较小的
{
child++;
}
if (arr[index] < arr[child])//因为是从底层往上把那个较小值上调的,所以这时候的index往下之
前已经调整过了
{
break;//一旦发现父节点比子节点小的话,直接结束这次的调整
}
Swap(&arr[index], &arr[child]);//走到这里说明没有进入上一个if,此时的根节点比子节点大
index = child;//子节点做根节点继续往下调整
child = index * 2 + 1;
}
}
void MakeHeap(int arr[], int size)//建堆
{
int i = 0;
for (i = size / 2 - 1; i >= 0; i--)//把所有的非叶子节点都要调整
{
AdjustDown(arr, i, size);
//AdjustUp(arr, i, size);
}
}
void HeapSort(int arr[], int size)
{
int end = 0;
MakeHeap(arr, size);//小堆创建完,此时的根节点为整个数组中最小的节点
for (end = size - 1; end >= 0; end--)//每次把根节点和最末尾的end节点交换,end--
{
Swap(&arr[end], &arr[0]);
AdjustDown(arr, 0, end);//现在从根节点开始调整,不同于上面的倒数第一个非叶子节点
//AdjustUp(arr, 0, i);
}
}