实现循环单链表

来源:互联网 发布:2017网络电影 编辑:程序博客网 时间:2024/06/07 10:36
#include <iostream>#include <string> struct GwListNode{     int gwid;    InterConnectionGatewayContext gw;    GwListNode *next;};class GwCircleList{  private:     GwListNode *head, *end;                      GwListNode *flag_pos;//used to record polling positionpublic:    GwCircleList();                                     int length()const;                       bool IsEmpty()const;                       GwListNode  *findByGwid(int)const;           GwListNode  *findInsertPos(int)const;           void insertByGwid(InterConnectionGatewayContext gw);                            void deleteByGwid(int id);           GwListNode* getFlagPos();    void setFlagPos(GwListNode* newpos);    void printList();    static int GwCircleListIndex;                      };class GwAlgorithm{    public:        GwAlgorithm(void){}        ~GwAlgorithm(void){}        void insertGw(InterConnectionGatewayContext gw);                                 void deleteGw(int id);                  void ChangeGwWithBoolValue(int id, RELATE_PARE_CHANGE_T para_cat, bool& value);                void ChangeGwWithIntValue(int id, RELATE_PARE_CHANGE_T para_cat, int& value);        bool GwPollAlgorithm(int callervpn, InterConnectionGatewayContext& gw);     };#endif

#include "gw_choose.hpp"#include <iomanip>GwCircleList GwCircleListForChoose;int GwCircleList::GwCircleListIndex = 0;GwCircleList::GwCircleList()              {    head = new GwListNode;    head->gwid = -1;        end = new GwListNode;    end->gwid = -1;    head->next = end;    end->next = head;      flag_pos = NULL;}int GwCircleList::length()const{      return GwCircleListIndex;}bool GwCircleList::IsEmpty()const                               {     if(GwCircleListIndex == 0)    {        return true;    }    return false;}GwListNode* GwCircleList::getFlagPos(){    return flag_pos;}void GwCircleList::setFlagPos(GwListNode* newpos){    flag_pos = newpos;    return;}void GwCircleList::printList(){    if(IsEmpty())    {         return;    }    GwListNode *node = head->next;    while (node->next != head)      {          node = node->next;      }     return;} GwListNode* GwCircleList::findByGwid( int gwid)const
{      GwListNode *node;    if(IsEmpty())    {        return NULL;    }    node = head->next;     while(gwid != node->gwid && node->next!=head)    {        node = node->next;    }    if(gwid == node->gwid)    {        return node;    }    return NULL;}GwListNode* GwCircleList::findInsertPos( int gwid)const{     if(IsEmpty())    {          return NULL;    }    GwListNode *node,*prenode;    if(gwid< head->next->gwid)    {        return head;    }    node = head->next;     while(gwid > node->gwid && node->next != head)    {        prenode = node;        node = node->next;    }    return prenode;}void GwCircleList::deleteByGwid(int id){     GwListNode *node,*prenode;    node = head->next;    prenode = head;    if(GwCircleListIndex == 0)    {        return;    }    while(id != node->gwid && node->next != head)    {       prenode = node;       node = node->next;    }    if(id == node->gwid)    {        if(node->gwid == getFlagPos()->gwid && node->next != end)//its not the last one        {            setFlagPos(node->next);        }        prenode->next = node->next;        delete node;        GwCircleListIndex--;    }    printList();    return;} void GwCircleList::insertByGwid(InterConnectionGatewayContext gwinsert) {     int gwid = gwinsert.gwid_;    GwListNode* newnode = new GwListNode;    newnode->gwid = gwid;    newnode->gw = gwinsert;    if(IsEmpty())    {        newnode->next = head->next;        head->next = newnode;        setFlagPos(newnode);        GwCircleListIndex++;        printList();        return;    }    if(findByGwid(gwid) != NULL)  //delete old    {        deleteByGwid(gwid);    }    //insert new    GwListNode* frontnode = NULL;    frontnode = findInsertPos(gwid);    if(NULL != frontnode)    {        newnode->next = frontnode->next;        frontnode->next = newnode;    }        GwCircleListIndex++;    printList();    return;}void GwAlgorithm::insertGw(InterConnectionGatewayContext gw){    GwCircleListForChoose.insertByGwid(gw);    return;}void GwAlgorithm::deleteGw(int id){    GwCircleListForChoose.deleteByGwid(id);    return;}void GwAlgorithm::ChangeGwWithBoolValue(int id, RELATE_PARE_CHANGE_T para_cat, bool& value){    GwListNode* node = NULL;    node = GwCircleListForChoose.findByGwid(id);    if(node != NULL)    {        switch(para_cat)        {            case RELATE_PARE_MARK://bool                node->gw.setMark(value, false);                break;            case RELATE_PARE_CALL_IS_OUT://bool                node->gw.setOut(value, false);                break;            case RELATE_PARE_CALL_BPUNISH://bool                node->gw.setPunish(value, false);                break;            default:                break;        }    }    return;}void GwAlgorithm::ChangeGwWithIntValue(int id, RELATE_PARE_CHANGE_T para_cat, int& value){    GwListNode* node = NULL;    node = GwCircleListForChoose.findByGwid(id);    if(node != NULL)    {        switch(para_cat)        {            case RELATE_PARE_CALL_COUNT://int                node->gw.setCallCount(value, false);                break;            case RELATE_PARE_MAX_CAPABILITY://int                node->gw.setMaxCapability(value, false);                break;            case RELATE_PARE_STATUS://int                node->gw.setStatus(value, false);                break;            case RELATE_PARE_GW_STATUS://int                node->gw.setGwStatus(value, false);                break;            case RELATE_PARA_GW_ISDN:                node->gw.setIsdn(value, false);                break;            default:                break;        }    }    return;}bool GwAlgorithm::GwPollAlgorithm(int callervpn, InterConnectionGatewayContext& gwinfo)  
{    int minRate = 10000;    InterConnectionGatewayContext* minRateGwinfo = NULL;    InterConnectionGatewayContext* unpunishedPollGwinfo = NULL;    InterConnectionGatewayContext* punishedPollGwinfo = NULL;    if(GwCircleListForChoose.IsEmpty())    {          return false;    }        GwListNode * startpos = GwCircleListForChoose.getFlagPos();    bool bPollStop = false;    bool bStart = true;    GwListNode * node = startpos;    InterConnectionGatewayContext* currentgw = NULL;    if(startpos == NULL)    {      return NULL;    }    for(;bStart || node != startpos; node = node->next)//start from the    {        bStart = false;        if(node->gwid == -1)//head or end node        {            continue;        }        currentgw = &(node->gw);        if(DeviceManager_T::instance()->scc_check_gw_state(currentgw, callervpn) != BCC_SUCCESS)        {            continue;        }        //method 1: mini-rate prior, used for 2 types of gws        int rate = (10000*currentgw->getCallCount())/(currentgw->getMaxCapability());        if(rate < minRate)        {            minRate = rate;            minRateGwinfo = currentgw;        }        if(!bPollStop && (minRate < 10000 && minRate >= 0))        {            bPollStop = true;        }        //method 2:polling, used only for type capability unknown gw,         if(!bPollStop && !currentgw->isMark())//if found minrate usable, no need to polling        {            if(currentgw->isPunished() && (NULL == punishedPollGwinfo))            {                punishedPollGwinfo = currentgw; //find the first unnull punished gw            }            else if((!currentgw->isPunished()))            {                unpunishedPollGwinfo = currentgw;//find the first unnull unpushied gw                bPollStop = true;            }        }        if(bPollStop) //start from the next pos        {           GwCircleListForChoose.setFlagPos(node->next);        }    }     //1st priority    if(minRate < 10000 && minRate >= 0)    {          gwinfo = *minRateGwinfo;        return true;    }    //2nd priority    else if(NULL != unpunishedPollGwinfo)    {         gwinfo = *unpunishedPollGwinfo;        return true;    }    //3rd priority    else if(NULL != punishedPollGwinfo)    {         gwinfo = *punishedPollGwinfo;        return true;    }       return false;}

0 0