冒泡排序,选择排序,插入排序,归并排序,堆排序全解析

几种排序算法

欢迎访问我的新博客主页哦

冒泡排序

不多说,最简单的排序算法了

选择排序

选择排序就是,从一个序列中选择最小的一个与第一个进行交换,然后再剩下的序列中选择最小的与第二个进行交换,依次类推。

下面看代码实现

/*写在代码前面的是关于数组与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(n1)/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]+" ");
        }
    }
}

喜欢的话点个赞吧!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值