算法动画
从小到大排序
1 冒泡排序
被动的将最大值送到最右边
1、比较相邻的元素。如果第一个比第二个大,就交换他们两个。
2、对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
3、针对所有的元素重复以上的步骤,除了最后一个。
4、持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
原地修改数组:
void bubbleSort(vector<int>& nums) {
int len = nums.size();
for (int i = 0; i < len - 1; ++i) { // 外层只需n-1
for (int j = 0; j < len - 1 - i; ++j) {
if (nums[j] > nums[j + 1]) // 最大的放在数组最右
swap(nums[j], nums[j + 1]);
}
}
}
优化:算是一种剪枝
假如从开始的第一对到结尾的最后一对,相邻的元素之间都没有发生交换的操作,这意味着右边的元素总是大于等于左边的元素,此时的数组已经是有序的了,我们无需再对剩余的元素重复比较下去了。
void bubbleSort2(vector<int>& nums) {
int len = nums.size();
bool flag = false;
for (int i = 0; i < len - 1; ++i) {
flag = false;
for (int j = 0; j < len - 1 - i; ++j) {
if (nums[j] > nums[j + 1]) {
flag = true;
swap(nums[j], nums[j + 1]);
}
}
if (!flag)//说明没有交换,则表明[0,len-i-1]已经是有序的了
break;
}
}
2 选择排序
主动将最小值送到最左边
void selectSort(vector<int>& nums) {
int len = nums.size();
int minIndex = 0;
for (int i = 0; i < len; ++i) {
minIndex = i;
for (int j = i + 1; j < len; ++j) {
if (nums[j] < nums[minIndex]) minIndex = j;
}
swap(nums[i], nums[minIndex]);
}
}
3 插入排序
与选择排序思路一致,从左到右排序
void insertionSort(vector<int>& nums) {
int len = nums.size();
for (int i = 1; i < len; ++i) {
int n = i;
while(n > 0){
if(nums[n-1] > nums[n])
swap(nums[n], nums[n-1]);
else
break; // 左边的数组都是有序的了
n--;
}
}
}
4 快速排序
时间复杂度:O(N*log(N))
nums = [15,19,2,18,24,4,20]
选择一个区间,将最左边的元素15作为中间点元素,然后将数组分成两个区间:
小于等于15的元素放其左侧,大于15的元素放其右侧
[2, 4]
,[15]
,[19, 18, 24, 20]
。
然后将这两个区间[2, 4]
与[19, 18, 24, 20]
按照相同的步骤(选最左侧元素。。。)
退出条件:
如果区间长度为1,直接归位