[C语言]选择排序算法学习(随记仅用于个人学习的记录)(使用Dev-C++ 6.3和vs2022)

⚠️图片使用拍摄方式且主要用于个人学习记录   小白记录贴  如果有大神能够指出我的错误点

感激不尽

学习资料:左神网课视频

(当时电脑没有网络所以使用手机编辑本文章)不介意可以继续食用

原思路来自左神的网课(原代码使用java)

想尝试用c语言实现

问题:有一个无序的数组,需要将其按照从小到大的排序输出,由此写出一个程序实现这种功能。

总体的算法思路是:依次将数字与后面所有数字进行比较,并且找出其中最小的数字与前面的数字进行交换,已经实现交换的数字不在处理的范围之内。

以下是算法雏形:

一.创建这样一个数组

ee2a08a4e47444c38a33fff1ee2033d7.jpg

想要实现一个输入任意数量元素的数组(暂时不考虑内存溢出的情况),都能排序成功之后输出。

(其实这样还需要获取输入,等到精细化的时候我们再来改进。)

于是使用了sizeof函数进行数组长度的计算。

二.实现数字之间的比较:使用了if语句进行比较

但是没有将x,y与数组中的数字联系起来,如何实现呢?将比较量改成array。

由此就牵涉到数组元素的引用,这里使用下标法。

先定义有最小值,再假设这个值在第零个位置,然后我们再把这个定义的最小值与后面所有值比大小,如果后面有值比它小,就讲小的值更新到这个最小值里面存储,再实现最小值与其他某个跟他比较的数字的交换。

56bd9bd977404602b8b4976287245d39.jpg

下一步寻找最小数的位置在哪里,如果需要交换位置就交换位置。f8e99a0f7db148838b2d550d737102b0.jpg

-交换实现:需要一个临时变量来存储实现交换

11946edc9f60469587ba20e71407fecc.jpg

 第一步实现之后的整体代码:3b33bcd17198459b8f9cdff56d6a395d.jpg

运行结果:c7f2a9c4dae145188febfebde944a312.jpg

算法雏形实现后进行下一步:循环处理实现算法。

f8f038c5d30f4ad4acc83119f84e3ccc.jpg

 结果:12534

问题出在哪里?

我没有将int min放入循环之中。尝试将其放入循环之中。

输出变成了15234 问题在于不清晰min是什么下标,混淆了min了array[min]

错误的地方在于范围画错 以及使用了变量min而不是数组形式进行交换,那么结果就不会是数组间元素的交换而是min和数组间元素的交换,就无法实现想要的结果。

修改之后及输出结果:

后来在查阅资料后,另一种写法:

注明:对于循环的理解,在本代码中外for循环一次,内for循环九次。

想实现打印出来每次交换后的数组,且美观该怎么做呢?多使用printf函数。

新问题:为什么定义min=0在外面的结果会有问题?

问题代码

#include<stdio.h>

int main()
{
    int arr[5] = {5,4,3,2,1};//定义数组长度
    int i,min,j,k,t,u;
     j = i = k = 0;
     min = 0;//问题所在
    for (i = 0; i < 5; i++)//从第一个元素开始
    {
        
        /*!!!!假设最小的位置就是i处,
        为什么只能是i而不是0?
        涉及到定义变量的范围,
        因为下一次循环还是在这一步开始,
        然后最后的结果是min和i的值相等所以得是它,
        倘若这个式子拿出来在外面定义为0,
        会发现结果是12463原因是什么?*/
        for (j = i+1; j < 5 ; j++)//i之后的元素之间遍历
        {
            if (arr[j] < arr[min]) //找出最小值然后标记它的位置
            {
                min = j;//发现最小的位置为j
            }
            
        }   
        t = arr[i];
        arr[i] = arr[min];
        arr[min] = t;
        /*!!!重点在于交换的理解,
        这个交换基于外循环存在的,
        因为是外循环的数和内循环的数进行比较,
        最后的结果呈现在外循环交换。*/
        printf("第%d次循环:",i+1);//打印结果帮助发现问题
             for (u = 0; u < 5; u++)
            {
                printf("%d", arr[u]);//打印出排序之后的数组
             }
             printf("\n");
     }
    printf("最终结果: ");
    for (k = 0; k < 5; k++)
      {
        printf("%d", arr[k]);//打印出排序之后的数组
       }
    }

运行结果

再看正确代码

#include<stdio.h>

int main()
{
    int arr[5] = {5,4,3,2,1};//定义数组长度
    int i,min,j,k,t,u;
     j = i = k = 0;
    for (i = 0; i < 5; i++)//从第一个元素开始
    {
        min = i;
        /*!!!!假设最小的位置就是i处,
        为什么只能是i而不是0?
        涉及到定义变量的范围,
        因为下一次循环还是在这一步开始,
        然后最后的结果是min和i的值相等所以得是它,
        倘若这个式子拿出来在外面定义为0,
        会发现结果是12463原因是什么?*/
        for (j = i+1; j < 5 ; j++)//i之后的元素之间遍历
        {
            if (arr[j] < arr[min]) //找出最小值然后标记它的位置
            {
                min = j;//发现最小的位置为j
            }
            
        }   
        t = arr[i];
        arr[i] = arr[min];
        arr[min] = t;
        /*!!!重点在于交换的理解,
        这个交换基于外循环存在的,
        因为是外循环的数和内循环的数进行比较,
        最后的结果呈现在外循环交换。*/
        printf("第%d次循环:",i+1);//打印结果帮助发现问题
             for (u = 0; u < 5; u++)
            {
                printf("%d", arr[u]);//打印出排序之后的数组
             }
             printf("\n");
     }
    printf("最终结果: ");
    for (k = 0; k < 5; k++)
      {
        printf("%d", arr[k]);//打印出排序之后的数组
       }
    }

如果没有min = i,那么交换就会持续进行下去,知道循环结束。

而设置了min = i,最小值就变更为交换之后的arr[i](也是实际结果上的最小值)

看代码可以发现没有进行条件判断arr[min]就和arr[i]进行交换了,因为前面,min = i 保证了每一项都比较到了,所以不需要条件判断,去掉之后就相当于少了条件判断,所以会一直交换下去。

证明选择排序不稳定

总结:

时间复杂度O(n2)

估计时间复杂度只用把最耗时间的语句估计出来即可。

空间复杂度:额外使用的空间,题目和变量不在考虑范围。

选择排序不稳定:相等的两个数可能进行位置交换。

——————————————————以下是体会————————————————————

在初看这个算法的时候感觉很好理解,但还是出现了一些问题,问题主要出在我c语言的使用上不熟悉导致没能实现精准实现想法。不过没关系,正是经过这一次的训练,我加深了对于for循环的理解和对于赋值运算的理解。实践出真知!继续加油!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值