算法理解
获取数组中第一个空闲的块
比如 array 为 1111111…111000000…0
问题就变成 寻找array中第一个出现的0
算法一:遍历数组找到第一个0 O(n)
算法二:二分查找
二分查找成功条件:array[i]=t; 失败条件:l>u
对于本问题来说,成功条件则是array[i]=0 array[i-1]=1,失败条件要提前测试 全1的情况
static int _GetBlockFfp()
{
int ret = 0;
byte nPage = 0;
int nMaxUsed = 0;
int nMinFree = SIZE-1;
byte nCase = SIZE;
int array[SIZE]={0};
int i,j;
for(j=0;j<=SIZE;j++)
{
printf("j %d/n",j);
for(i=0;i<SIZE;i++)
{
array[i]=0;
}
for(i=0;i<j;i++)
array[i]=1;
//读第0页
if(array[0]==0)
{
printf("find ffp %d/n",0);
//return 0;
continue;
}
else
{
nMaxUsed=0;
}
//读最后一页
if(array[SIZE-1]==1)
{
printf("find ffp %d/n",SIZE);
// return 0;
continue;
}
else
{
nMinFree=SIZE-1;
}
//以上处理了 全空 全满,不存在First free page的情况
//以下则是 非0 最后一页 肯定存在 First free page的情况
while(1)
{
nPage=(nMinFree+nMaxUsed)/2;
/* if(array[nPage]==0)
{
nMinFree=nPage;
}
else
{
nMaxUsed=nPage;
}
*/
if(array[nPage]==0)
{
if(array[nPage-1]==1)
{
printf("find ffp %d/n",nPage);
break;
}
nMinFree=nPage-1;
}
else
{
if(array[nPage+1]==0)
{
printf("find ffp %d/n",nPage+1);
break;
}
nMaxUsed=nPage+1;
}
/* if( (nMinFree == (nMaxUsed+1 )))
{
printf("find ffp %d/n",nMinFree);
// return 0;
break;
}*/
}
}
}
算法三:
二分查找的变形,每次循环少一次 访问数组
利用两个变量 nMinFree nMaxUsed ,算法成功条件 nMinFree== nMaxUsed+1
Version 1:逻辑清晰版
#define SIZE 64
static int _GetBlockFfp()
{
int ret = 0;
byte nPage = 0;
int nMaxUsed = -1;
int nMinFree = SIZE;
byte nCase = SIZE;
int array[SIZE]={0};
int i,j;
for(i=0;i<56;i++)
array[i]=1;
//读第0页
if(array[0]==0)
{
printf("find ffp %d/n",0);
//return 0;
continue;
}
else
{
nMaxUsed=0;
}
//读最后一页
if(array[SIZE-1]==1)
{
printf("find ffp %d/n",SIZE);
// return 0;
continue;
}
else
{
nMinFree=SIZE-1;
}
//以上处理了 全空 全满,不存在First free page的情况
//以下则是 非0 最后一页 肯定存在 First free page的情况
while(1)
{
nPage=(nMinFree+nMaxUsed)/2;
if(array[nPage]==0)
{
nMinFree=nPage;
}
else
{
nMaxUsed=nPage;
}
if( (nMinFree == (nMaxUsed+1 )))
{
printf("find ffp %d/n",nMinFree);
// return 0;
break;
}
}
}
Version 2:更加优化版
#include <stdio.h>
#include <stdlib.h>
#define SIZE 64
typedef unsigned char byte;
static int _GetBlockFfp()
{
int ret = 0;
byte nPage = 0;
int nMaxUsed = -1;
int nMinFree = SIZE;
byte nCase = SIZE;
int array[SIZE]={0};
int i,j;
int l,u;
l=0;
u=SIZE-1;
for(i=0;i<56;i++)
array[i]=1;
while(1)
{
printf("npage:%d/n",nPage);
if(array[nPage]==0)
{/*自由块-------------------------------------------------------------*/
nMinFree = nPage;
if (nMinFree == (nMaxUsed + 1))
{ printf("find ffp %d/n",nMinFree);
return 0;
}
/*未确定,重新定位,先算case减半*/
nPage = (byte)((nMinFree + nMaxUsed) >> 1);
printf("free blk/n");
printf("nMinFree : %d,nMaxUsed : %d/n",nMinFree,nMaxUsed);
printf("nCase : %d,newnPage : %d/n",nCase,nPage);
printf("/n");
}
else
{/*在用块-------------------------------------------------------------*/
nMaxUsed = nPage;
if (nMinFree == (nMaxUsed + 1))
{/*已确定*/
printf("find ffp %d/n",nMinFree);
return 0;
}
/*未确定,重新定位,减半*/
if(0==nPage)
{/*第一次,在用,专门优化直接读最末页*/
nPage = (byte)(nCase - 1);
}
else
{/*其它,先算case后定位*/
nPage = (byte)((nMinFree + nMaxUsed) >> 1);
printf("used blk/n");
printf("nMinFree : %d,nMaxUsed : %d/n",nMinFree,nMaxUsed);
printf("nCase : %d,newnPage : %d/n",nCase,nPage);
printf("/n");
}
}
}
}