几种排序算法
冒泡排序
不多说,最简单的排序算法了
选择排序
选择排序就是,从一个序列中选择最小的一个与第一个进行交换,然后再剩下的序列中选择最小的与第二个进行交换,依次类推。
下面看代码实现
/*写在代码前面的是关于数组与auto,我们看这样一段代码*/
int arr[5]={1,2,3,4,5};
for(auto i:arr)
cout<<i<<endl;
//这里自动输出数组arr里面的数,不用考虑数组长度等问题
#include<iostream>
using namespace std;
void choose_sort(int array[], int len)//选择排序
{
//选择排序从第i个后面进行挑选,选到最小的进行与第i个进行交换
for (int i = 0; i < len - 1; i++)
{
for (int j = i + 1; j < len; j++)
{
if (array[i] > array[j])//当出现第j个比第i个小时,就进行交换,或者将这个最小值进行保存直到找到最小的那个数进行交换
{
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
}
int main()
{
int arr[10] = { 2,5,8,6,9,7,4,3,1,10 };
choose_sort(arr, sizeof(arr) / sizeof(arr[0]));
for (auto i: arr)
{
cout << i << " ";
}
return 0;
}
代码分析,先看main程序,给定一个有界测试数据,然后再choose_sort函数执行后进行输出;这里就分析choose_sort函数,当实现一个算法时,考虑一些边界情况。在这个选择排序中,首先第i个元素及前面的元素是已经排序好的,所以这里的循环i从0开始,也就是数组第一个元素。然后在i+1后面选择比第i个元素小的进行交换,这里检查最小的用j表示,j要一直遍历完整个数组。所以两层循环,
这里我们分析时间复杂度
当i=0时,我们的j需要遍历n-1次,这里n指的是数组长度。
当i=1时,我们的j需要遍历n-2次,这里n指的是数组长度。
…
当i=n-2时,我们的j需要遍历1次,这里n指的是数组长度。
所
以
总
共
遍
历
次
数
就
是
(
n
∗
(
n
−
1
)
/
2
)
,
时
间
复
杂
度
为
O
(
n
2
)
所以总共遍历次数就是(n*(n-1)/2),时间复杂度为O(n^2)
所以总共遍历次数就是(n∗(n−1)/2),时间复杂度为O(n2)
插入排序
在一个有序序列中,将后面的无序序列逐个插入到有序序列中.在某种程度上与选择排序相类似,但是这里并不是进行交换,而是空出一个进行插入,所以涉及到插入前需要将后面的元素整体后移一个位置.
下面看实现代码
#include<iostream>
using namespace std;
void insert_sort(int array[], int len)
{
/*
插入排序实现思路,给定一个数列,从第二个开始往后遍历,并于前面的进行比较,就能确保前面的都是有序的
当遇到后面的比前面某个小,就插入,并将数组后移
*/
for (int i = 0; i < len-1;i ++)//j x x x x x x i
{
int value = array[i + 1];
for (int j = i; j >= 0; j--)
{
if (array[j] <= value) {
break;//这时候排序完成了
}
else
{
array[j + 1] = array[j];
array[j] = value;
}
}
}
}
/*下面是main函数进行测试*/
int main()
{
int array[10] = { 3,1,4,6,8,12,5,3,78,32 };
insert_sort(array, sizeof(array) / sizeof(array[0]));
for (int i = 0; i < 10; i++)
{
cout << array[i] << " ";
}
return 0;
}
下面看源码分析,主要看insert_sort函数,对于一个数组,我们排序前,保留第一个元素,作为初始有序序列,也就是i=0从零开始,然后需要插入的元素就是i=1时的值,将其设置为value.这时候需要将value进行合理插入了,将value与j=i, j=i-1, …j=0进行比较,如果比array[j]大显然排序完成就break,否则,进行交换,继续比较
堆排序
归并排序
1、将序列中数组每个分成一组
2、将若干个组两两合并,保证合并后的组仍然有序
3、重复第二步直到只剩一个组,排序完成
例如:19 97 09 17 01 08
分析时间复杂度,
快排
参考博客 (5条消息) 快速排序(java实现)_王玉Student的博客-CSDN博客_java快速排序
快排核心思想就是二分后递归找某个(首个)元素的位置。
咱们看看一个数组 6、1、2、7、9、3、4、5、10、8
首先得找到6在这个数组中的正确位置,那么我们就这样进行,选择一个哨兵i在位置low(数组下标0),哨兵j在位置high(数组下标length-1)然后j从右往左寻找一个比arr[low] (这里就是6了)小的数,但是不能让j比i小了,也就是哨兵j不能和哨兵i相遇。找到后,哨兵i就要行动了,哨兵i从左往右寻找一个比arr[low]大的数,当然了也不能和j相遇了,如果相遇那就说明这个位置就是要找的位置了。好到此为止,i,j都找到了,那么将i,j进行交换。然后重复这个过程,知道i,j最后相遇,这个位置就是要找的arr[low]的归属地。然后再一次进行交换。结束后,我们就知道了arr[low]的左边就是比它小的数,右边就是比它大的数。然后递归执行左右两个子数组。结束后自然就排好序了。
看看参考代码
public class QuickSort {
public static void quickSort(int[] arr,int low,int high){
int i,j,temp,t;
if(low>high){
return;
}
i=low;
j=high;
temp = arr[low];
while (i<j) {
//先看右边,依次往左递减
while (temp<=arr[j]&&i<j) {
j--;
}
//再看左边,依次往右递增
while (temp>=arr[i]&&i<j) {
i++;
}
//如果满足条件则交换
if (i<j) {
t = arr[j];
arr[j] = arr[i];
arr[i] = t;
}
}
//最后将基准为与i和j相等位置的数字交换
arr[low] = arr[i];
arr[i] = temp;
//递归调用左半数组
quickSort(arr, low, j-1);
//递归调用右半数组
quickSort(arr, j+1, high);
}
public static void main(String[] args){
int[] arr = {10,7,2,4,7,62,3,4,2,1,8,9,19};
quickSort(arr, 0, arr.length-1);
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+" ");
}
}
}
喜欢的话点个赞吧!