找回密码
 马上注册

QQ登录

只需一步,快速开始

查看: 4233|回复: 5

索引排序法

  [复制链接]
发表于 2019-7-31 18:33:37 | 显示全部楼层 |阅读模式
本帖最后由 小竹砸 于 2019-7-31 21:48 编辑

  之前有整理过冒泡排序和计数排序的思路,最近又想到一种新的排序思路,较前面那两种排序思路更简单,具体排序原理如下:(以5个0-9之间的随机整数为例进行说明)

   简单说,索引值是从零开始并且是不断增大的,它本身是一个有序的数组,可以将需要进行排序的随机数作为索引,进行相应处理就能实现随机数的排序。
   在随机数不重叠的情况下,往随机数对应的索引位置写入1,写完之后进行数组遍历,将组合数组内的数值和1进行比较,等于1时显示该数值对应的索引,遍历一次就能完成排序。
  从索引0开始遍历,完成从小到大排序,从最大索引(长度减1)开始遍历,则完成从大到小排序,这样的方法出现重复数值时,排序过程中只会显示一次,反过来想可以认为这种方法能够自动去重。这种情况下,随机数的最小值为顺序遍历时,等于1的数值对应的索引,最大值为数组长度减1。
  在随机数有重叠的情况下,计数排序法(或者比较排序法)比较难实现,但是用这种思路可以很好实现,具体如下:生成一个数值全0的数组,将随机数对应的索引位置的值读出并加1(相同的数值在同一索引处写入1多次并不能体现重复的效果,所以采用加1),写完之后将数组内的数字和0进行比较,不等于零时,显示该数值的索引一定次数,示例中索引7上对应的数值为2,就将索引7显示2次。这种情况下,从小到大遍历时,不等于0的数值对应的索引就为随机数的最小值,最大值为从大到小遍历时,不等于0的数值对应的索引。

如果看到这里你已经懂了,可以先自己写写程序,后面的程序解读主要方便初学者以及自己后续查看。下面我们来看看如何通过程序实现

第一类:数值重叠只需要显示一次的情况

1、将0到200之间的五个随机数从小到大排序

   程序解读:前面没做变量的初始化和数组的初始化,实测没啥问题。清除屏幕,循环索引存入n1(可以避免数值连接线交叉,后面的程序没有这样改),往数组zh中随机数对应的位置存入1(其余位置默认为0)并通过变量n1将随机数依次显示在屏幕上,重复执行5次。(思考:此时的数组长度为5吗?)



   程序解读:循环索引存入变量sx中,依次读取数组zh中的数值和1进行比较,等于1则将其显示在屏幕上,并将变量n加1,读取数组zh长度控制循环次数,循环外加个等待即可。
  变量n的功能是控制排序过程中的数值的显示位置,同时它也统计了遍历过程中数值为1的数值个数,它的最大值为5,循环也可在n等于5时结束。(思考:用n等于5控制循环次数能可以减少循环执行的次数吗?)
这种情况下,随机数的最大值为数组的长度减1,随机数的最小值为第一个等于1处的索引值。

2、将0到200之间的五个随机数从大到小排序
  从数组末尾开始进行数值比较就能变为从大到小排序,程序修改如下:
  数组长度减1得到最大索引,循环索引从0开始变化,做减法运算之后,得到的索引值是从大到小变化。


3、将-100到100之间的五个随机数从小到大排序
  因为数组的索引从0开始,如果直接按照上面的方法去做会出现错误,具体的解决办法是,先将随机数加上100,用得到的数值作为索引。


  进行数组遍历显示的时候,将数值为1处的索引减去100再显示出来即可。

  思考:如果排序的数组中涉及小数可以如何操作?

第二类:数值重叠,要求显示多次的情况
  如果出现数值重叠的情况,按照上面的方法重叠的数值只会显示1次,因为同样的数值意味着同样的索引,这个时候我们可以将写入1改为在原有数值的基础上加1。
   这种情况下需要先进行数组的初始化,不做这个操作运行程序时会报错(具体原因不知道,我猜想是空白数组可以写入,但是要进行运算的话需要先给初始值,有知道具体原因的大神麻烦留言告诉我哈)。


  程序解读:生成1个长度为201(0到200是201个数)数值全部为零的数组并且清除屏幕。

  为方便测试,我把随机数的范围调整为0到4,调整为0到200也没问题。
  程序解读:随机数存入变量sj中,将数组zh中索引为随机数的数值读出,加1之后重新写入同一位置。利用循环索引控制显示间隔,显示随机数,循环5次。

   程序解读:将循环索引值存入变量sx中,依次读取数组zh中的数值,存入变量num中,将读取的数值和0进行比较,如果变量sx的数值不等于0则将该数值显示在屏幕上num次,变量n用来控制数值显示时的横坐标,整体循环次数为数组长度(未截取),这个大循环外加个等待模块即可。

补充:
   使用这种思路进行排序也可以较快解决两组数值比较查找数值重叠次数的问题,具体思路如下:
      在两个数组内部都没有相同数值的情况下(比如:1、2、3、4、5和2、3、5、7、9),依次将这两个数组中的值读出,将对应的索引处的数值加1,得到组合数组(我自定的名称,应该没有这个概念),进行数组遍历的过程中,组合数组(得到的组合数组为:0、1、2、2、1、2、0、0、1、1)中数值为2的数值个数即为两个数组中存在相同数值的个数(2个),数值为2的数值对应的索引(2和3)即为两个数组中都有的值。

  在两个数组内部有相同数值的情况下(比如,数组A:1、5、0、4、4和数组B:3、5、2、0、3),分别利用这两个数组得到两个新的组合数组(数值A、B得到的组合数组为:1、1、0、0、2、1和1、0、1、2、0、1),然后使用同一索引进行数组遍历,在两个数组中的数值都不为0的情况下,取两者中较小的那个值进行累计,最后得到的结果就是两个数组中相同数值的个数(2个)。
  运行效果如下:

   感兴趣的老师可以尝试优化效果,将两个数组中都有的数值显示在屏幕上。
   各位老师可以关注一下我的个人公众号留言交流,也可以论坛留言交流。


c.jpg
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
发表于 2019-8-1 09:05:30 | 显示全部楼层
这个帖子棒棒。我在仔细阅读钟读了两遍。由于缺几个图片。读起来有点难。
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

 楼主| 发表于 2019-8-1 15:54:11 | 显示全部楼层
吖吖岁 发表于 2019-8-1 09:05
这个帖子棒棒。我在仔细阅读钟读了两遍。由于缺几个图片。读起来有点难。

嗯嗯 是有图片缺了,上传出错就没弄了,程序截图都有的
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

发表于 2019-8-2 11:05:27 | 显示全部楼层
非常好的帖子!
我在想怎么孩子讲呢,感觉蛮难的
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

 楼主| 发表于 2019-8-2 11:46:56 | 显示全部楼层
mulanhua 发表于 2019-8-2 11:05
非常好的帖子!
我在想怎么孩子讲呢,感觉蛮难的

数据重叠类比较简单,孩子理解起来比较快,后面那个建议自己玩玩就好
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

发表于 2019-8-3 14:24:24 | 显示全部楼层
小竹砸 发表于 2019-8-2 11:46
数据重叠类比较简单,孩子理解起来比较快,后面那个建议自己玩玩就好

恩恩,感谢感谢
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 马上注册

本版积分规则

QQ|手机版|中文乐高 ( 桂ICP备13001575号-7 )

GMT+8, 2024-4-19 12:52 , Processed in 0.092727 second(s), 20 queries .

Powered by Discuz! X3.5

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表