【排序】选择排序&冒泡排序&插入排序

博客初体验 ⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)

今天是我注册CSDN账号的第106天,终于要写第一篇博客辣!!
大一刚开学时被一位学长安利这个网站,本菜鸡 在C语言考试之前 经常溜上来查我遇到的问题,从未有过写博客的想法。直到寒假时参加了学校集训的第一天,听cy老师讲到了,又看了ljw学长的博客,才有了写博客记录学习的想法。同时向大佬们学习!!

~~~正文

本次主要复习我学过的两种排序方法——选择排序冒泡排序
当时就没有学透(emmm现在也未必
为了加深印象,特此捞一下。

选择排序

若数组a中有n个数, a[0],a[1],…a[n-1],要从小到大排序后输出。

排序过程: 共比较n-1轮

  1. 第一轮从第一个数开始,让第一个数a[0] 依次与它后面的数进行两两比较,若前面的数大于后面的数,则交换它俩的顺序,当第一个数与最后一个比完时,最小数已经被放到了第一位(a[0])上。第一轮结束。
  2. 第二轮比较从第二个数a[1]开始,它只需和它后面的数两两比较,同上,当a[1]与最后一个比完时,倒数第二小的数已经被放到了第二位(a[1])上,第二轮结束。
  3. 第三轮比较从第三个数a[2]开始 ……
  4. ……
  5. 第n-1轮比较只比a[n-2]与a[n-1]。
    排序完成!

代码实现:

for(i=0;i<n-1;i++)
         for(j=i+1;j<n;j++)
         {
             if(a[i]>a[j])
             {
                 t=a[i];
                 a[i]=a[j];
                 a[j]=t;
             }
         }

冒泡排序

若数组a中有n个数, a[0],a[1],…a[n-1],要从小到大排序后输出。

排序过程: 从前往后,相邻的两个数相比。共(n-1)轮。

  1. 第一轮从a[0]和a[1]的比较开始,若前面的数比后面的大,就交换顺序,把大的放后面。再比 a[1]和a[2]、a[2] 和 a[3]、……、a[n-2] 和 a[n-1],第一轮比完后最大的数已经“ 沉底 ”,到了a[n-1]。
  2. 第二轮仍旧从a[0]和a[1]的比较开始,若前面的数比后面的大,就交换顺序,把大的放后面。这一轮只比到a[n-3]和a[n-2],第二轮比完后,第二大的数到了a[n-2]。
  3. ……
  4. 第(n-1)轮只比较a[0]和a[1],若前面的数比后面的大,就交换顺序。此时最小数就是a[0]了。

代码实现:

for(i=0;i<n-1;i++)
          for(j=0;j<n-i-1;j++)
        {
            if(a[j]>a[j+1])//相邻的数两两比较
            {
                t=a[j];
                a[j]=a[j+1];
                a[j+1]=t;
            }
        }

zai啰嗦几句: 为什么j<n-i-1

这是我初学时没懂的地方。。。

从上面的排序过程来看,每一轮都在反复比较a[ j ]和a[ j+1],当第 i+1轮时,后面的 i 个数已经“沉底”,只要比到j+1=n-i-1

  1. 第一轮 ------ i=0 ------比到a[n-2]和a[n-1] (最后一个数)------比较后a[n-1]“沉底”,下一轮无须参加比较
  2. 第二轮 ------ i=1 ------比到a[n-3]和a[n-2] -------------------------比较后a[n-2]“沉底”,下一轮无须参加比较
  3. 第三轮 ------ i=2 ------比到a[n-4]和a[n-3] -------------------------比较后a[n-3]“沉底”,下一轮无须参加比较
  4. 。。。。。。(假省略号
  5. 第n-1轮------ i=n-------比到a[0]和a[1] -------------------------------比较后a[1]“沉底”。

所以每一轮最后比的a[ j ]和a[j+1], j+1=n-i-1;____这不就是j<=n-i-2 -----也是j<n-i-1辣~
呼——
终于推出来了(没啥技术含量也比较笨2333

在这里插入图片描述
啊那么我滴第一篇博客就这样从头水到尾了。撒花花✿(ノ≧∀≦)ノ✿ ✿

插入排序(3.4更

这是我们生活中最常用的排序方法,例如打扑克牌时要整理手中的牌,本强迫症就习惯摸一张,插一张。将新元素逐个插入到已排好的序列中,当所有元素都插入完毕时,排序完毕。
初始的“已排好的序列”只有1张牌,第二张插入时要找到它应该插入的位置,若它比第一张小,就插在第一张的前面;后面要加入序列的每张牌都是这样,首先要找到第一张比自身大的牌,然后插到这张牌前面,对“第一张比自身大的牌”的解释就是假如你手里有4,7,9,Q。摸到了4,当然要插在7(第一张比4大的牌)前面。这时,后续的7,9,Q都要往后移一位给新4腾出位置。

还是那道题:若数组a中有n个数, a[0],a[1],…a[n-1],要从小到大排序后输出

[将a[i]插到有序序列a[0],a[1]… …,a[i-1]中 の伪代码]
1.备份要插入的数据a[i]到某 ¥%@,记下来 :¥%@=a[i]
2.找到插入的位置k;
3.将a[k]~a[i-1]的元素逐个后移一格,以前的a[i]被覆盖;
4.新值入位a[k]=¥%@;

完整代码:

#include <stdio.h>
#include <stdlib.h>
int main()
{
    int n,a[100];
    while(~scanf("%d",&n))
    {
        for(int p=0; p<n; p++)
            scanf("%d",&a[p]);
        int i,j,k,tmp;
        for(i=1; i<n; i++)
        {
            tmp=a[i];
            for(j=0; j<i; j++) //有序序列是a[0]~a[i-1]
                if(a[j]>tmp)
                    break;//a[j]就是第一个大于a[i]的
            k=j;//要插到位置k
            for(j=i-1; j>=k; j--)
                a[j+1]=a[j];//后移.a[k+1]变成以前的a[k],原a[i]被原a[i-1]覆盖;
            a[k]=tmp;//tmp就是最初备份的待插入的原a[i]
        }
        for(i=0; i<n-1; i++)
            printf("%d ",a[i]);
        printf("%d\n",a[i]);//要注意多组输入题的输出格式
    }
}

一定要用tmp“备份”是因为元素向后移动会覆盖a[i],这样移动完就找不到本来要插入的a[i]了,因此事先用tmp备份一下。
小结:
插入排序法的结构主要是一个大for循环中嵌套两个小for循环,
这两个小for是并列关系。
共计两层循环。
大for 用来循环待插入的新元素a[i];
俩小for 一个用于找到插入位置k,另一个用于使a[k]及后元素逐个后移。

                                           2020.3.4      2:17再次撒花花✿(ノ≧∀≦)ノ✿ ✿
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值