2013-03-09 66 views
0

我努力讓我的腦海裏圍繞在C以下遞歸實現歸併的++歸併C++的遞歸實現的理解的一部分

什麼讓我的是,由於載體由參考,並vec.clear通過()正在被調用,即使在一些合併完成之後,它如何不消除矢量。例如,當基礎被擊中時,該函數返回堆棧中的頂部框架,並且繼續向下堆棧。然而,函數需要合併不止一次,並且在每次合併之前,矢量被清除,我認爲這意味着內存中的空間(因爲它是通過引用傳遞)被清除,我們失去了已經合併的東西?我可以理解這種方法如果通過價值傳遞將如何工作,但這是通過引用傳遞的,所以我感到困惑。

void merge(vector<int> &final, vector<int> &left, vector<int> &right) { 
    while (left.size() > 0 || right.size() > 0) { 
     if (right.size() == 0) { 
      final.push_back(left.at(0)); 
      left.erase(remove(left.begin(), left.end(), left.at(0)), left.end()); 
     } 
     else if (left.size() == 0) { 
      final.push_back(right.at(0)); 
      right.erase(remove(right.begin(), right.end(), right.at(0)), right.end()); 
     } else if (left.at(0) <= right.at(0)) { 
      final.push_back(left.at(0)); 
      left.erase(remove(left.begin(), left.end(), left.at(0)), left.end()); 
     } else if (right.at(0) < left.at(0)) { 
      final.push_back(right.at(0)); 
      right.erase(remove(right.begin(), right.end(), right.at(0)), right.end()); 
     } 
    } 
} 

void sort(vector<int> &vec) { 
    int n = vec.size(); 

    // BASE CASE 
    if (n <= 1) { 
     return; 
    } 

    // GENERAL CASE/RECURSIVE CASE 
    vector<int> leftVec; 
    vector<int> rightVec; 

    for (int i = 0; i < n; i++) { 
     if (i < n/2) { 
      leftVec.push_back(vec.at(i)); 
     } else { 
      rightVec.push_back(vec.at(i)); 
     } 
    } 

    sort(leftVec); 
    sort(rightVec); 
    vec.clear(); 
    merge(vec, leftVec, rightVec); 
} 

回答

2

vec內容已被複制到leftVecrightVecclear調用之前,所以沒有信息已經丟失。您尚未提供merge的來源,但我們可以假設它將內容複製回vec

+0

剛剛添加了合併的內容。 – eb80 2013-03-09 04:26:04

+0

所以我現在看到如何內容通過merge()複製回vec,謝謝。我想我仍然試圖圍繞這一切如何與遞歸一起工作,並通過引用傳遞。有什麼建議麼?我已經打開調試器並走過了,但我還沒有完成。 – eb80 2013-03-09 04:30:20

+0

@ eb80如果您不考慮合併步驟,則算法的遞歸步驟更容易理解。它應該相當簡單。 ['std :: merge()']幫了大忙。看到一個很有希望的簡單的基於迭代器的版本[here](http://ideone.com/bPT2HK)。 'std :: inplace_merge()'使整個算法變得虛擬[更加簡單](http://ideone.com/Ayt5jq),因爲你提供的全部*是分區。 – WhozCraig 2013-03-09 04:59:40