打印
[51单片机]

数据排序问题

[复制链接]
3203|20
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wang12zhe|  楼主 | 2013-7-24 15:08 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
liang7143| | 2013-7-24 15:33 | 只看该作者
100个数据,数据量不大
可以用简单的 比如选择法,冒泡法

使用特权

评论回复
板凳
原野之狼| | 2013-7-24 15:57 | 只看该作者
“要求每次只能获得10个”   

这句话怎么讲?

使用特权

评论回复
地板
ayb_ice| | 2013-7-24 16:01 | 只看该作者
排序是基本算法

使用特权

评论回复
5
wang12zhe|  楼主 | 2013-7-24 16:28 | 只看该作者
原野之狼 发表于 2013-7-24 15:57
“要求每次只能获得10个”   

这句话怎么讲?

由于我的数据是存在EEPROM里的,需要把这100个数据排序,但是由于单片机RAM空间限制,不能把这100个数据全部一次性取出排序(结构体数据,还一个数据13个字节,100个需要1300个字节),所以想一次取出几个数据排序,通过反复的类似操作实现100个数据排序

使用特权

评论回复
6
原野之狼| | 2013-7-24 16:45 | 只看该作者
wang12zhe 发表于 2013-7-24 16:28
由于我的数据是存在EEPROM里的,需要把这100个数据排序,但是由于单片机RAM空间限制,不能把这100个数据 ...

这需求有意思哈   
已近不仅仅是排序的问题了

你还是把其它的限制条件一并说了吧

比如  存储数据到EEPROM的频度 对排序的性能要求

使用特权

评论回复
7
wang12zhe|  楼主 | 2013-7-25 08:59 | 只看该作者
原野之狼 发表于 2013-7-24 16:45
这需求有意思哈   
已近不仅仅是排序的问题了

好的,那就不客气了
1 数据最大100个(可以小于100),在EEPROM里随机存储,当收到无线信号的时候数据增加一个,数据可以被手动随机删除某一个或者几个(删除方法此在屏幕上查找删除),
2 每个数据上有一个时间戳,想通过屏幕查看的时候能按照时间的先后顺序查看,所以需要根据时间的先后顺序排序
3 最大的问题,一个数据13个字节,最坏情况下全部读到RAM排序的话需要1300字节,而现在我可用的RAM,仅有700字节了,

使用特权

评论回复
8
joyme| | 2013-7-25 10:17 | 只看该作者
定义一个100字节的数据,用来存储数据位置的映射表,每次增加或删除数据时用二分法排序后更新此映射表
index_map[100],每次字节对应EEPROM里第i个数据的排序位置,删除的或没有排序的数据置0xff

使用特权

评论回复
9
原野之狼| | 2013-7-25 10:39 | 只看该作者
思路开阔点  700字节绰绰有余

使用特权

评论回复
10
原野之狼| | 2013-7-25 10:45 | 只看该作者
8楼已经开始为你铺了一段路了

使用特权

评论回复
11
e08610318| | 2013-7-25 11:41 | 只看该作者
开辟一段数组,数组坐标从小到大可以表示为时间由先到后,我不管你数据存到RAM哪个地方,只要你把这个RAM的地址按照顺序存到这个数组里面,不就可以实现按照顺序显示数据了。也就是建立一个映射

使用特权

评论回复
12
tergy2012| | 2013-7-25 11:58 | 只看该作者
路过学习

使用特权

评论回复
13
wang12zhe|  楼主 | 2013-7-25 13:25 | 只看该作者
joyme 发表于 2013-7-25 10:17
定义一个100字节的数据,用来存储数据位置的映射表,每次增加或删除数据时用二分法排序后更新此映射表
inde ...

我也想到了建立映射,一旦系统试点后第一次排序完成,之后的删除和增加数据就方便了,现在我的问题其实就是第一次这个排序,怎么排序,
比如:一次性读出10个,假设分别是:1、9、3、2、7、5、8、6、25、57,这是个排序完全没问题,但是之后读出的数据有可能在这是个数据中间,然后不会了,菜鸟一个,再指点一下,

使用特权

评论回复
14
原野之狼| | 2013-7-25 13:41 | 只看该作者
1
9 1
9 3 1
9 3 2 1
9 7 3 2 1
9 7 5 3 2 1
9 8 7 5 3 2 1
9 8 7 6 5 3 2 1
25 9 8 7 6 5 3 2 1
57 25 9 8 7 6 5 3 2 1
看懂没有?

使用特权

评论回复
15
wang12zhe|  楼主 | 2013-7-25 14:17 | 只看该作者
原野之狼 发表于 2013-7-25 13:41
1
9 1
9 3 1

看懂了,你这还是10个数的排序,假设先从EEprom里读出10个数1、9、3、2、7、5、8、6、25、57,存入A[10],然后对这10个元素排序,排好后存入建立的数组B[100],这样刚读出的10个已经排序57 25 9 8 7 6 5 3 2 1,假设存入B[0]到B[9],然后再从EEPROM读出10个,读到A[10]数组里如:4、12、87、65、15、11、17、20、18、,再次排序,但是这次的10个数据4在上次的数据3、5之间,这样顺序就不对了,

使用特权

评论回复
16
wang12zhe|  楼主 | 2013-7-25 14:21 | 只看该作者
原野之狼 发表于 2013-7-25 13:41
1
9 1
9 3 1

上边的回复有点需要补充:假设的数据值代码EEPROM的地址,我的数组B里存放的是排好序的数据的地址

使用特权

评论回复
17
原野之狼| | 2013-7-25 14:39 | 只看该作者
搞一个数组   一次读一个数据

使用特权

评论回复
18
wang12zhe|  楼主 | 2013-7-25 14:43 | 只看该作者
原野之狼 发表于 2013-7-25 14:39
搞一个数组   一次读一个数据

???????????,不懂

使用特权

评论回复
19
joyme| | 2013-7-25 14:43 | 只看该作者
简单写了一个增加的函数(从大大小排列),按上面我说的,每次只对一个数据排序(每次10个原理是一样的,程序比较复杂),删除应该更简单
#define   MAX_NUM         100
#define   BASE_ADDR       XXXX                           //数据在EE里的基址
BYTE   bInOrderNum = 0;
BYTE   bOrderMap[MAX_NUM] = {0xff};                //记录数据在EE里的偏移地址

void   insertdata(BYTE bOrderIndex,BYTE bEEIndex)
{
   BYTE i = 0;
   for(i = bInOrderNum; i > bOrderIndex; i--)
   {
       bOrderMap[i] = bOrderMap[i -1];
   }
   bOrderMap[bOrderIndex] = bEEIndex;   
   bInOrderNum++;
}

void   adddata(BYTE  bEEIndex)
{
   BYTE   bStart, bEnd, i;
   if(bInOrderNum == 0)
      bOrderMap[bInOrderNum++] = curIndex;
   else
   {     
      bStart = 0;
      bEnd = bInOrderNum;
          do                              //2分法
          {
             if(*(BASE_ADDR + bEEIndex) == *(BASE_ADDR + bEnd/2))    //如果相等插入到当前值前面
                 {       
                         bStart = bEnd/2;
                        break;
                 }
             else if(*(BASE_ADDR + bEEIndex) > *(BASE_ADDR + bEnd/2))
                     bEnd = bEnd/2;
             else
                     bStart = bEnd/2;
          }while(bStart != bEnd);
          insertdata(bStart,bEEIndex);
   }
}

使用特权

评论回复
20
joyme| | 2013-7-25 14:58 | 只看该作者
这个二分法的写法好像有点问题,你可以自己琢磨一下

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

101

主题

205

帖子

1

粉丝