引言:
主要介绍几个排序以及各自的优缺点,方便大家更好理解排序算法
一、冒泡排序
1、概念:
就是通过相邻元素的比较和交换,将较小的元素逐步"冒泡"到数组前端。
2、步骤(升序为例):
a、遍历数组,从第一个元素开始比较,依次比较相邻的两个元素。
b、交换元素:如果前一个元素比后一个元素大的话,就交换。
c、重复步骤b直到整个数组都有序。
3、注意点:
循环的次数是n-1,因为每一次循环,都是将一个元素排到后面去,避免影响前面
的排序。那么你一共要排n-1个元素。因为你后面的元素都排好了,第一个元素也就正确了
啊。
4、代码:
cpp
#include<iostream>
#include<vector>
using namespace std;
BubbleSort(vector<int>& vec)
{
for (int i = vec.size()-1; i >= 1; i--)
{
bool flag = true;//优化
for (int j = 0; j < i; j++)
{
if (vec[j] > vec[j + 1])
{
swap(vec[j], vec[j + 1]);
flag = false;
}
}
if (flag) break;//如果flag执行一次循环还是为true,则说明已经排好序,直接跳出即可
}
}
int main()
{
vector<int> vec= { 10,12,2423,546,767,1,4,5,345,124 };
cout << BubbleSort(vec);
return 0;
}
为什么是从i=vec.szie()-1开始呢?因为你最先排好的最后一个呀。那么你后续的循环是
排序排除排好的数字了。
加flag进行判断是为了提前结束,避免浪费时间和空间。
二、选择排序
三、插入排序
1、概念:
就是将未排序好的元素逐个插入到已排序的序列中的合适位置。其实就跟你整理书籍一样,把书本放到已经排好序的书籍中的合适位置。
2、步骤:
a、选择数组的第一个元素作为已排序部分,剩余的就开始挨个插入。
b、从未排序的数组开始,逐个去除,跟已排序的部分从前往后开始比较。
c、重复步骤b直到数组有序。
3、注意:
就是需要替换,因为你排好序的数组的当前位置是有元素的,当这个位置有新元素
来,那么你从这个位置开始的后面元素都得往后移动。
4、代码:
cpp
#include<iostream>
#include<vector>
using namespace std;
void InsertSort(vector<int>& vec)
{
for (int j = 1; j < vec.size(); j++)//无序区间段
{
for (int i = 0; i < j; i++)//有序区间段
{
if (vec[i] > vec[j])
{
int temp = vec[j];
for (int k = j-1; k>=i; k--)
{
vec[k + 1] = vec[k];
}
vec[i] = temp;
}
}
}
}
int main()
{
vector<int> vec= { 10,12,2423,546,767,1,4,5,345,124 };
cout << InsertSort(vec);
return 0;
}
值得注意的就是你的后移,得把当前vec[j]空出来存放vec[i]。后移不会溢出是因为你的j最大
就是vec.size()-1。
四、希尔排序
1、概念:
改进的插入排序。插入是直接整个数组进行,而希尔排序则是分组进行排序,然后逐步缩短每个数组的长度,直到长度为1,
2、步骤:
a、首先选择一个间隔,就是每个子数组的长度。一般是n/2。
b、然后根据间隔,将数组分隔为多个子数组。
c、然后对每个子数组进行插入排序。
d、逐步减小间隔,直到间隔为1。
3、注意:
按照间隔是将数组分成若干个子数组,但是不是说均分,而是说按照间隔大小来
分。
比如数组长度是10,间隔是3。
那么分出的第一个数组:0,3,6,9
第二个数组:1,4,7
第三个数组:2,5,8
分的是下标,以及数组个数。而不是直接均分。
4、代码:
cpp
#include<iostream>
#include<vector>
using namespace std;
void InsertShell(vector<int>& vec, int start, int gap)
{
for (int i = gap + start; i < vec.size(); i += gap)
{
for (int j = start; j < i; j += gap)
{
if (vec[i] < vec[j])
{
int temp = vec[i];
for (int k = i - gap; k >= j; k-=gap)
{
vec[k + gap] = vec[k];
}
vec[j] = temp;
}
}
}
}
void ShellSort(vector<int>& vec)
{
for (int gap = vec.size() / 2; gap >= 1; gap /= 2)
{
for (int i = 0; i < gap; i++)
{
InsertShell(vec, i, gap);
}
}
}
int main()
{
vector<int> vec= { 10,12,2423,546,767,1,4,5,345,124 };
cout << ShellSort(vec);
return 0;
}
如果观察仔细的话,其实插入排序其实就是间隔为1的希尔排序。