1. 程式人生 > >算法練習2之單鏈表求和

算法練習2之單鏈表求和

鏈表 next 意圖 節點 nis ads oss and nodelist

筆試題目:

1、用單向鏈表表示十進制整數,求兩個正整數的和。如下圖,1234+34=1268,
註意:單向鏈表的方向,不允許使用其他的數據結構
技術分享圖片

題目分析:

題目中提到了,數據結構只能使用單鏈表,所以數組不在考慮範圍之內。
因為將數字轉為單鏈表以後,最高位排在表頭,而我們進行整數加法的時候,是從個位開始的,與單鏈表的順序相反。所以我們考慮對鏈表進行反轉,然後再做加法。

其中反轉和求和的示意圖如下:
技術分享圖片

對求和以後的結果再進行反轉:
技術分享圖片

下面是C++的實現

代碼解讀

1.節點的數據結構定義如下:

//節點定義
struct Node_t
{
    int m_value;
    Node_t * m_pNext;
};

2. 將int轉為List

//int轉List
Node_t* IntToNodeList(int value)
{
    Node_t* pHead= new Node_t;
    pHead->m_pNext=nullptr;
    while(value > 0)
    {
        Node_t * pNewNode = new Node_t;
        pNewNode->m_value = value % 10;
        pNewNode->m_pNext = pHead->m_pNext;
        pHead->m_pNext = pNewNode; 
        value = value / 10;
    }

    Node_t * pResult = pHead->m_pNext;
    pHead->m_pNext=nullptr;
    delete pHead;
    return pResult;
}

3.將List轉為int

//List轉int
int NodeListToInt(Node_t* pList)
{
    Node_t * pHead = pList;
    int nResult = 0;
    while(( pHead != nullptr)){
        nResult = nResult*10+pHead->m_value;
        pHead = pHead->m_pNext;
    }
    return nResult;
}

4. 釋放節點內存

//釋放節點
void FreeNodeList(Node_t* pList)
{
    Node_t* pHead = pList;
    Node_t* pFree = nullptr;
    while(pHead)
    {
        pFree = pHead;
        pHead = pHead->m_pNext;
        delete pFree;
    }
}

5 .實現鏈表的反轉

//鏈表翻轉,使用傳入的鏈表的內存
Node_t* ReverseList(Node_t* pList)
{
    Node_t * pResult = nullptr;
    Node_t * pTem = nullptr;
    while(pList != nullptr)
    {
        pTem = pList->m_pNext;
        pList->m_pNext=pResult;
        pResult= pList;
        pList = pTem;   
    }
    return pResult;
}

6.將鏈表相加

//鏈表相加
Node_t * AddList(Node_t* pLeft,Node_t* pRight)
{
    Node_t * pRevLeft = ReverseList(pLeft);
    Node_t * pRevRight = ReverseList(pRight);
    Node_t * pResult=nullptr;
    int toUpValue = 0;//進位
    int nLeftValue = 0;
    int nRightValue = 0;

    while(pRevLeft != nullptr || pRevRight != nullptr)
    {
        Node_t * pNewNode = new Node_t;
        pNewNode->m_pNext = pResult;
        pResult = pNewNode;

        nRightValue = 0;
        nLeftValue = 0;

        if(pRevLeft)
        {
            nLeftValue = pRevLeft->m_value;
            pRevLeft = pRevLeft->m_pNext;
        }
        
        if(pRevRight)
        {
            nRightValue = pRevRight->m_value;
            pRevRight = pRevRight->m_pNext;
        }
        

        int curPosSum = nRightValue+nLeftValue;
        pNewNode->m_value = curPosSum%10+toUpValue;
        toUpValue = curPosSum/10;
    }
    return pResult;
}

主函數:

int main(int argc,char * argv[])
{
    int nLeftValue = rand();
    int nRightValue = rand();
    std::cout<<"Test Reverst"<<std::endl;
    Node_t * pLeftList = IntToNodeList(nLeftValue);
    Node_t * pRightList = IntToNodeList(nRightValue);
    Node_t * pSumList = AddList(pLeftList,pRightList);
    int nSum = NodeListToInt(pSumList);

    FreeNodeList(pLeftList);
    FreeNodeList(pRightList);
    FreeNodeList(pSumList);
    std::cout<<"TEST "<<nRightValue<<"   "<<nLeftValue <<"           "<<nSum<<std::endl;
    return 0;
}

算法練習2之單鏈表求和