Merge Sort(归并排序)
- 总的来说,归并排序算是一种比较难的排序方法了,先分组再合并,合并的时候还要考虑很多种情况。
- 归并排序的时间复杂度是o(NlogN)
- 每一层归并的时间复杂度为O(N)
- 划分的最大层数为O(logN+1)
- 空间复杂度为O(N)。
void merge_sort(vector &nums, int l, int r, vector &temp)
{
//递归结束条件:划分到只有一个元素为止。
if(l+1>=r)
return;
int m = l+ (r-l)/2;
//以m为分界点进行划分,
//划分左区间
merge_sort(nums,l,m,temp)
//划分右区间
merge_sort(nums,m,r,temp)
//划分结束开始组合
//左区间开始端点给p,中点给q
int p = l,q = m,i=1;
//当左区间中的点被都合并完或者右区间的点都被合并完
while(p
//如果左区间第一个数小于右区间第一个数,则把左区间第一个放在temp第一位,然后temp的指针和左区间指针都+1
//多考虑一种情况是虽然根据 m = l+(r-l)/2的取法,左区间肯定是数量小的那个,但如果右边区间都被放在temp里了,左区间还没有划分完,考虑这种情况必须加一个q>=r
if(q>=r || p
temp[i++] = nums[p++]
}
//否则把右区间第一个放在temp第一位,然后temp的指针和右区间指针都+1
else{
temp[i++] = nums[q++]
}
}
//一般情况下,右区间数量多,所以被划分完的可能性小,这里是把右区间剩余的数都合并进来。
for(i=1;i
nums[i] = temp[i];
}
}
插入排序(Insertion Sort)
- 插入排序的思想比较简单,最好情况时间复杂度是O(n),最坏情况时间复杂度是O(n^2)
void insertion_sort(vecttor &nums, int n)
{
for (int i = 0; i < n; i++) {
//比较第j个数和第j-1个数,只要第j个数<第j-1个数,就swap
for (int j = i; j >= 0 && nums[j] < nums[j - 1]; --j)
swap(nums[j], nums[j - 1]);
}
}
冒泡排序(Bubble Sort)
- 冒泡排序的思路是,最大遍历的轮数为n轮,第一轮就是找最大的数放在末尾,第二轮就是找次大的数放在末尾的前一个位置,以此类推。方法就是前后两个数比较,如果前面的数大就放到后面一个位置。除此之外,为了增加冒泡排序的速度,还要设置一个标志位,swapped,如果某一轮发现,没有数被交换,因为每一轮都是从第一个数开始一直比,如果这个过程中没有发生交换,则说明数组已经被排好序了,结束就行了。
void Bubble_sort(vecttor &nums, int n)
{
for (int i = n; i > 1; --i) {
bool swapped = false;
for (int j = 0; j < i; ++j)
{
if (nums[j - 1] > nums[j]) {
swap(nums[j - 1], nums[j]);
swapped = true;
}
}
if (!swapped)
break;
}
}
选择排序(Selection Sort)
- 选择排序就是每次找到最小值放在最前面或者每次找到最大值放在最后面
void selection_sort(vecttor &nums, int n)
{
int mid;
for (int i = 0; i < n - 1; i++)
{
mid = i;
for (int j = i + 1; j < n; ++j)
if (nums[j] < nums[mid])
mid = j;
swap(nums[mid], nums[i]);
}
}