常见简单排序算法(选择,冒泡,插入)

选择排序

原理

每一次从待排序的数据元素中选出最大(小)的,将其放在前面已排好序的数据后面,然后又从剩下的数据中选出最大(小)的,重复操作,以此类推。


C代码
#include<stdio.h>
void main()
{
    int a[10] = { 7,8,5,4,3,2,6,9,0,1 };
    int i, j,k, temp;
    for (i = 0; i < 10; i++)
    {
        k = i;//将每一次第i的元素下标记为最值初始值
        for (j = i+1; j < 10; j++)
        {
            if (a[k] > a[j])//降序if(a[k]<a[j])
            {
                k= j;//满足条件的数据就将下标值记录下来,以便后面的比较和交换
            }
        }
        temp = a[i];//找到了就开始交换位置
        a[i] = a[k];
        a[k] = temp;
    }
    for (i = 0; i < 10; i++)
    {
        printf("%d ",a[i]);//打印
    }
}

详解

第一轮比较,从第一个元素7开始,即i=0时,j=1, j从第i个元素的后一个元素开始遍历,用7与其他元素比较,7<8,继续遍历,7>5,满足条件就将5的下标赋值给K记录下来,这时k=j=2, 然后5>4,满足则k=j=3, 然后4>3,满足则k=j=4,然后3>2,满足则k=j=5,然后2>0满足则k=j=8,最终k记录下来的j值8就是这一次遍历中数据最小的元素的数组下标值,然后根据这个下标将这个值与第i个元素交换,即7与0交换,则最小的值就被放在了开头,除了这个值其他的值仍为乱序,然后将i值增加,又从剩下的数中找最值并将其移到前面排好序的数后面来,以此类推。注意每次i值增加重新查找时将k值初始化为i值。


1.移动数据的次数已知为(n-1)次。
2.比较次数多不稳定。


冒泡排序

原理

将一组无序数据a[0],a[1],a[2]……a[n-1],a[n],从第一个开始a[0]与a[1]比较,然后a[1]与a[2]比较,然后a[3]与a[4]比较,以此类推,到a[n-1]与a[n]比较,每一次比较,满足条件前者更大(小)就交换两者的位置,否则就不交换,每一轮从第一个元素比较到后面,就会将剩下的元素中最大(小)的元素交换到最后面。


C代码
#include<stdio.h>
void main()
{
    int a[10] = { 7,8,5,4,3,2,6,9,0,1 };
    int i, j, temp;
    for (i = 0; i < 10-1; i++)//两两比较,共只需要比较n-1轮
    {
        for (j = 0; j < 10-i-1; j++)//比较了几轮j就可以少遍历几个,因为比较好了的已经放在数组最后
        {
            if (a[j] > a[j+1])//降序  if(a[j]<a[j+1])满足条件就将两个值交换
            {
                temp = a[j+1];
                a[j + 1] = a[j];
                a[j] = temp;
            }
        }
    }
    for (i = 0; i < 10; i++)
    {
        printf("%d ",a[i]);//打印
    }
}

详解

第一轮比较,7与8相比,7<8,不满足条件不交换,然后8>5,交换,序列变成7 5 8 4 3 2……,然后继续从原来5的位置(交换后即为8)开始比较,8>4,交换,序列变成754832……然后8>3,交换,然后8>2,交换,然后8>6,交换,此时序列已经变成了7543268901,然后8<9,不满足不交换,9>0,满足交换,序列变成7543268091,最后9>1,交换,序列变成7543268019,即最大的数就被交换到最后了,然后又从第一个元素开始新的一轮遍历,第二轮遍历后序列变成5432670189,即除9外的最大元素8又被交换到后面来了,第三轮遍历后序列又变成4325601789,以此类推。


1.稳定。
2.理论上总共进行n(n-1)/2次交换。
3.慢,每次只能移动两个数据。


插入排序

原理(摘自百度百科)

已知一组升序排列数据a[1]、a[2]、……a[n],一组无序数据b[1]、b[2]、……b[m],需将二者合并成一个升序数列。首先比较b[1]与a[1]的值,若b[1]大于a[1],则跳过,比较b[1]与a[2]的值,若b[1]仍然大于a[2],则继续跳过,直到b[1]小于a数组中某一数据a[x],则将a[x]~a[n]分别向后移动一位,将b[1]插入到原来a[x]的位置这就完成了b[1]的插入。b[2]~b[m]用相同方法插入。(若无数组a,可将b[1]当作n=1的数组a)。


C代码
#include<stdio.h>
void main()
{
    int a[10] = { 7,8,5,4,3,2,6,9,0,1 };
    int i, j, temp;
    for (i = 1; i < 10; i++)//将a[0]看成是有序数组,从a[1]开始遍历
    {
        for (j = i; j >0; j--)//i遍历了几次,有序数组中元素就需要两两比较几次
        {
            if (a[j] < a[j-1])//降序  if(a[j]>a[j-1])
            {
                temp = a[j-1];//即将无序数组的第一个从有序数组的尾部开始向前比较
                a[j -1] = a[j];
                a[j] = temp;
            }
        }
    }
    for (i = 0; i < 10; i++)
    {
        printf("%d ",a[i]);//打印
    }
}

详解

对于只有一个无序数组时,将这个无序数组的第一个元素看成有序数组的元素,剩下的元素就是无序数组,则循环i从i=1开始,此时有序数组中只有7,然后循环j每一次从j=i开始,因为i之前的元素都是有序数组中的数,则第i个元素为无序数组中将要插入有序数组中的数,第一轮比较时,8是将要插入的数,这是相当于8的位置已经算入了有序数组,8与7比较,不满足条件,则8放在7之后,即位置不变,但此时有序数组已经变成了7,8,接下来又开始第二轮比较,5是将要插入的数,5与8比较,满足条件,本来按照插入的规则,这时应将8向后移一位,而在这里是通过8与5的位置交换来达到8向后移一位的目的,然后继续让8与7比较,满足条件,7也向后移一位,此时有序数组就变成了5,7,8。以此类推,间接的使用插入法实现了升序排列。每一轮有序数组的数都将增加一个,无序数组的数都将减少一个,但其实至始至终都只有一个数组,只是巧妙的使用了他的空间。


1.稳定,快。
2.较次数不一定,比较次数越多,插入点后的数据移动越多,特别是当数据总量庞大的时候,但用链表可以解决这个问题。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值