初等排序

初等排序

  • 插入排序
  • 冒泡排序
  • 选择排序

稳定排序

  • 所谓稳定排序,就是指在存在两个及以上相同的元素时,在排序处理前后,相对的前后位置不发生改变。

插入排序

  • 插入排序,顾名思义,核心思想就是把一个数插入到这个数组中它应该在的位置。从第二个数开始,将前面的看做已经排好序的数列,我们只需让它不断地向前比较,(以升序排列为例)只要找到第一个比它小的数,并将它插入在这个数的后面,然后重复这个过程直到所有的数都在它应该在的位置上,排序就完成了。

  • 动画演示 (图片取自VisuAlgo)
    插入排序

  • 代码

void insertionSort(int *array, int N){	//N为数组array的大小
	for (int i = 1; i < N; i++){	//从第二个数开始比较到N-1结束
		int temp = array[i];	//记录当前需要排序的数
		int j = i - 1;
		//当j大于等于0的时候,一直向前寻找直到找到比当前需要排序的数小的数
		while (j >= 0 && array[j] > temp){
			array[j+1] = array[j];		//将比要排序的数大的排到当前数之后
			j--;
		}
		array[j+1] = temp; 		//最后将要排序的数插入到它应该去的位置
	}
}
  • 很容易可以看出,插入排序是稳定的。在程序中只要遇到相等,即
    (array[ j ] == temp)的情况,while循环就会跳出,不会改变相等的元素的相对位置。
  • 对于插入排序来说,时间复杂度为O(n2),但是数据排列的顺序对排序的时间影响很大。对于降序排列的数列来说,时间复杂度为O(n2),但是对于已经升序排好的数列,时间复杂度为O(n),所以插入排序适合用在相对来说较为有序的数列上。

冒泡排序

  • 冒泡排序的核心思想就是从一列数中找出最大的那个,然后像冒泡一样上浮,将相邻两个数较大的放在后面,最终选出最大的数,将其放在最后,然后再对除了最后一个数的前面部分数列重复这个过程,依次找出第二大,第三大……的数,并将其依次排列,即可得到排序。

  • 动画演示 (图片取自VisuAlgo)
    冒泡排序

  • 代码

void bubbleSort(int *array, int N){
    for (int i = 0; i < N - 1; i++){	//长度为N的数组要至少循环N-1次
		for (int j = 0; j < N - i; j++){	//最后的i个数为已经排好的数,所以只排列前N-i个数
	   		if (array[j] > array[j+1]) //如果前面的数比后一个数大,就将他们交换
				swap(array[j], array[j+1]);
		}
    }
}
  • 和插入排序一样,因为没有交换两个相同的数,即条件为(array[ j ] > array[ j+1 ]),所以冒泡排序也是稳定排序。冒泡排序也为双循环,故时间复杂度应该为O(n2).

选择排序

  • 选择排序的思想和冒泡排序有点像,都是找出一列数中的最值,然后放到最前或者最后。但与冒泡排序不同的是,冒泡排序是两个相邻的数进行交换,而选择排序则是遍历选择出最值然后直接进行交换。
  • 动画演示 (图片取自VisuAlgo)
    在这里插入图片描述
  • 代码
void seletionSort(int *array, int N){
    for (int i = 0; i < N - 1; i++){	//和冒泡排序一样,交换N-1次
        int min = array[i], min_;	//用min记录当前数组最小值,用min_记录最小值下标
        for (int j = i; j < N; j++){	//对从i开始到结束的数组选择最小值
            if (array[j] < min){	//记录最小值及其下标
                min = array[j];
                min_ = j;
            }
        }
        swap(array[min_],array[i]);		//将选择出的最小值与这个数组的第一位交换
    }
}
  • 对于选择排序来说,因为是直接交换的最小值,可能存在两个及以上的相同元素没有按照相对位置来排序,所以选择排序是不稳定排序。同冒泡排序一样,选择排序的时间复杂度也是O(n2)。

返回目录

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值