之前看到过这样的一种说法,能正确的写出2分法的程序员不足10%.那时觉得自己应该是属于那个10%里面的.今天调试软件的时候正好碰到过这样的情况.想也没想,写了这样一段程序:
/*根据通道的NodeData值来找出通道列表中对应的通道*/
TChannelData *TChannelDataList::FindChannelNodeData(int AChannelNodeData)
{
int IBegin,IEnd,IMiddle;
IBegin = 0,IEnd = Count-1;
while(IBegin<IEnd)
{
IMiddle = (IEnd-IBegin)/2;
if(Items[IMiddle]->NodeDataID<AChannelNodeData)
IBegin = IMiddle;
else
if(Items[IMiddle]->NodeDataID>AChannelNodeData)
IEnd = IMiddle;
}
if(Items[IMiddle]->NodeDataID==AChannelNodeData)
return Items[IMiddle];
else
return NULL;
}
传进去以后发现返回的指针一直为NULL.有点不理解了.后来分析了TChannelDataList加载列表时已经指定了按照ChannelID的升序排列.不能通过这个来NodeData进行2分法查询,但是退一步讲,即使按照NodeData生序排列.程序还是不能获得正确的指针的.2分法写的不正确.
/*根据通道的NodeData值来找出通道列表中对应的通道*/
TChannelData *TChannelDataList::FindChannelNodeData(int AChannelNodeData)
{
int IBegin,IEnd,IMiddle,Itemp;
IBegin = 0,IEnd = Count-1;
while(IBegin<=IEnd)
{
IMiddle = (IEnd-IBegin)/2;
if(Items[IMiddle]->NodeDataID<AChannelNodeData)
IBegin = IMiddle;
else
if(Items[IMiddle]->NodeDataID>AChannelNodeData)
IEnd = IMiddle;
}
if(Items[IMiddle]->NodeDataID==AChannelNodeData)
return Items[IMiddle];
else
return NULL;
}
修改如下:
TChannelData *TChannelDataList::FindChannelNodeData(int AChannelNodeData)
{
if(Count==0)
return NULL;
int IBegin,IEnd,IMiddle;
IMiddle=IBegin = 0,IEnd = Count-1;
while(IBegin<IEnd)
{
IMiddle = IBegin+(IEnd-IBegin)/2;
if(Items[IMiddle]->NodeDataID<AChannelNodeData)
IBegin = IMiddle+1;
else if(Items[IMiddle]->NodeDataID>AChannelNodeData)
IEnd = IMiddle-1;
else
return Items[IMiddle];
}
if(Items[IMiddle]->NodeDataID == AChannelNodeDate)
return Items[IMiddle];
return NULL;
}
总结2点: 1.进行2分法查找时列表一定是以该关键字升序或者降序排列的.
2.需要考虑列表为空以及While循环防止进入死循环.