Vol7
排序:笔试和面试的重点.1.算法描述;2.实现;3.效率分析(时间复杂度,空间复杂度,稳定性)
稳定性:针对关键字相同的数据,排序前如果A在A"的前面,排序后还能保证A在A"的前面,则算法稳定,否则不稳定
稳定性判断依据:有没有跳跃的交换数据,没有则稳定
7.归并排序
代码思想:将两段有序的数据合并成一段有序的数据,直到所有的数据有序
时间复杂度:O(nlogn)
空间复杂度:O(n)
稳定性:稳定(没有交换)
//合并
void Merge(int* arr, int* tmpArr, int left, int mid, int right)
{
//标记左半区第一个未排序的元素下标
int l_pos = left;
//标记右半区第一个未排序的元素下标
int r_pos = mid + 1;
//临时数组的下标
int pos = left;
//合并
while(l_pos <= mid && r_pos <= rigth)
{
if (arr[l_pos] < arr[r_pos])
{
tmpArr[pos++] = arr[l_pos++];
}
else
{
tmpArr[pos++] = arr[r_pos++];
}
}
//合并左半区剩余的元素
while (l_pos <= mid)
{
tmpArr[pos++] = arr[l_pos++];
}
//合并右半区剩余的元素
while (r_pos <= right)
{
tmpArr[pos++] = arr[r_pos++];
}
//临时数组复制回原来的数组
while (left <= right)
{
arr[left] = tmpArr[left];
left++;
}
}
static void msort(int *arr, int* tmpArr,int left,int right)//O(n),O(n)
{
if (left < right)//至少有两个元素
{
//找中间点
int mid = (left + right) / 2;
//递归划分左半区域
msort(arr, tmpArr, left, mid);
//递归划分右半区域
msort(arr, tmpArr, mid + 1, right);
//合并
Merge(arr, tmpArr, left, mid, right);
}
}
//归并排序入口
void MergeSort(int *arr,int len)//O(nlogn),O(n),稳定(没有交换)
{
//分配一个辅助数组
int* tmpArr = (int*)malloc(len * sizeof(inrt));
if (tmpArr)
{
msort(arr, tmpArr, 0,len-1);
free(tmpArr);
}
else
{
printf("error:failed to allocate memory");
}
}```