天天看點

【對于單連結清單複制錯誤的反思】

原來錯誤的代碼:

view plaincopy to clipboardprint? 

SllNode *SllCopy( SllNode *const pTarget )    //拷貝單連結清單,若拷貝失敗或參數為空連結清單,傳回NULL,否則傳回新連結清單的首指針;函數并不破壞原連結清單        

{        

        if( NULL == pTarget )        

                return NULL;        

        SllNode *pCopy = new SllNode;        

        if( NULL == pCopy )        

        register SllNode *pTmpTar = pTarget;        

        register SllNode *pTmpCopy = pCopy;        

        while( NULL != pTmpTar )        

        {        

                pTmpCopy->Data = pTmpTar->Data;        

                pTmpCopy->pNext = pTmpTar->pNext;         

                pTmpTar = pTmpTar->pNext;        

                pTmpCopy = pTmpCopy->pNext;        

        }        

        return pCopy;        

}    

由于才起步,經驗不足,導緻以上錯誤。

用VS2008逐條跟蹤前期,并未發現此函數有錯。但發現其它函數在修改SllCopy函數傳回的“複制”的單連結清單後,原模闆連結清單也被修改,于是想到可能是指針無意間被修改,故将參數改為const并再次調試,問題依舊。

但排除了首指針被修改問題之後,依次隔離其餘各函數,發現隻要調用了SllCopy函數便會出現此問題,是以将調試重點放在了此函數。

逐條跟蹤局部變量,發現除模闆連結清單首指針pTarget 和 目标連結清單首指針pCopy 不一樣之外,其餘指針都相同,便發現了問題所在。我隻是簡單的将原連結清單的各節點的pNext指針複制了一遍到pCopy所指向的目标連結清單,是以,函數調用後,相當于建立了一個新首指針pCopy去指向模闆連結清單,那麼通過對“複制”後的連結清單進行操作也就修改了原模闆連結清單,導緻後期錯誤的産生。

現将函數修改如下:

                pTmpCopy->pNext = new SllNode;        

                if( NULL == pTmpCopy->pNext )        

                        return NULL;        

                pTmpCopy->pNext->pNext = NULL;        

        //Delete the useless rear node        

        pTmpCopy = pCopy;        

        while( NULL != pTmpCopy->pNext->pNext )        

        pTmpCopy->pNext = NULL;        

        delete pTmpCopy->pNext;        

最後删除了一個無用尾節點,但是始終覺得這幾行代碼應該可以不用,需要對連結清單複制進行怎樣的改動呢?希望能得聽聽大家的意見。

由于才起步,代碼一般很幼稚,望高手包含,更希望熱心人多多指點,非常感謝。

【注】下附沒有無用尾節點的SllCopy版本

SllNode *SllCopy( SllNode *const pTarget )  //拷貝單連結清單,若拷貝失敗或參數為空連結清單,傳回NULL,否則傳回新連結清單的首指針;函數并不破壞原連結清單 

  if( NULL == pTarget ) 

    return NULL; 

  SllNode *pCopy = new SllNode; 

  if( NULL == pCopy ) 

  register SllNode *pTmpTar = pTarget; 

  register SllNode *pTmpCopy = pCopy; 

  while( NULL != pTmpTar ) 

  { 

    SllNode *pTmp = new SllNode; 

    if( NULL == pTmp ) 

      return NULL; 

    pTmp->Data = pTmpTar->Data; 

    pTmp->pNext = NULL; 

    pTmpCopy->pNext = pTmp; 

    pTmpCopy = pTmpCopy->pNext; 

    pTmpTar = pTmpTar->pNext; 

  } 

  //Delete the useless rear node 

  //pTmpCopy = pCopy; 

  //while( NULL != pTmpCopy->pNext->pNext ) 

  //  pTmpCopy = pTmpCopy->pNext; 

  // 

  //pTmpCopy->pNext = NULL; 

  //delete pTmpCopy->pNext; 

  return pCopy->pNext; 

}

     本文轉自Bill_Hoo 51CTO部落格,原文連結:http://blog.51cto.com/billhoo/411476,如需轉載請自行聯系原作者

繼續閱讀