簡體   English   中英

在 C++ 中對指針數組進行排序

[英]Sorting Array of Pointers in C++

希望我能得到一些關於我所做的排序方法的建議。

此代碼的目的是創建一個 int 指針數組,並按常規 int 數組的內容對該數組中的指針進行排序。 然后根據原始 int 數組的位置為不同的變量賦值。

我在這段代碼中遇到的奇怪之處在於,據我所知,測試代碼不應該影響任何東西......實際上影響了我的指針的內容。 也許這些值沒有改變,但我編寫測試代碼的方式導致了錯誤。

 //create array
 int c[8] = {3,1,5,7,8,2,6,4};
 //create pointer array
 int *newptr[8];
 for(int k = 0; k<8; k++)
 {
     newptr[k] = &c[k];
 }
//sort pointer array
for(int j = 0; j<8; j++)
{
    for(; j > -1 && *newptr[j] < *newptr[j+1]; j--)
    {
        int *temp = newptr[j+1];
        newptr[j+1] = newptr[j];
        newptr[j] = temp;
    }
}
//set lookuplocation
int lookuplocation;
for(int i = 0; i<8; i++)
{
    cout << *newptr[i];

    if(newptr[i] == &c[0])
    {
        cout << *newptr[i] << endl;

        //If I use endl or \n to test the pointers values I end up with only
        //a part of the correct data. 

        cout << "\nSuccess!\n";
        lookuplocation = 0;
    }
}
//Also for my last test sometimes the first element gets messed up as well
//test arrays
for(int k = 0; k<8; k++)
{
    cout << "Element " << k << ": " << *newptr[k] << endl;
    cout << "Element " << k << ": " << newptr[k] << endl;
}

我認為有人可能實際上需要以一種理智的方式對指針數組進行排序:

#include <iostream>
#include <array>
#include <algorithm>

int main() {
    std::array<int, 8> arr { 3, 5, 4, 1, 2, 7, 6, 8 };
    std::array<int*, 8> p_arr;

    for (unsigned i = 0; i < 8; ++i) {
        p_arr[i] = &arr[i];
    }

    std::sort(p_arr.begin(), p_arr.end(), [](int* a, int* b) { return *a < *b; });

    for (auto i : p_arr) 
        std::cout << *i;
}

丑陋的中間循環完全可以由范圍替換為超過zip pped 范圍,但我現在沒有自己的參考語義實現,而且我懶得檢查 Boost 一個。 1

這是關於 Coliru 的現場樣本

另外,因為我認為我們應該一遍又一遍地重復這個,直到新手理解它:

  • 不要重新發明分揀輪(除非它是一個玩具實現)
  • 如果可能的話,盡量避免在 C++ 中使用指針。

1這實際上很重要,以確保兩個范圍(在本例中為兩個數組)具有相同的長度。 不同的壓縮約定要么要求范圍具有相同的長度(否則會崩潰或拋出),或者如果范圍之一太短則填充空數據。 雖然在這樣一個簡單的程序中看起來很明顯,但在實際代碼中要小心。

如果您的數組c[n]的范圍為 [1 .. n ],您可以使用以下算法,該算法的時間復雜度為 O( n ):

for(int j = 0; j < n; j++)
    while(*newptr[*newptr[j] - 1] != *newptr[j])
        std::swap(newptr[*newptr[j] - 1], newptr[j]);

它背后的想法是將值 1 分配給指針newptr[0] ,將 2 分配給指針newptr[1] ,...,將n分配給指針newptr[n-1] 沒有更有效的算法(尤其是在 C++11 中,因為std::swap將使用std::move )。

所以對於int c[8] = {3,1,5,7,8,2,6,4} ,你得到(不考慮對值表的引用):

1233

成功!
45678


更新:如果你想要相反的順序:

for(int j = 0; j < n; j++)
    while(*newptr[n - *newptr[j]] != *newptr[j])
        std::swap(newptr[n - *newptr[j]], newptr[j]);

對於int c[8] = {3,1,5,7,8,2,6,4} ,你得到:

8765433

成功!
21

流行的方法是實現使用給定比較器sort元素進行sort通用sort函數,因此您可以對數組元素進行抽象。 有一些方法:

template<typename ElementType, typename CompType>
void sort(ElementType array[], size_t size, CompType cmp);
template<typename ElementType, typename CompType>
void sort(std::vector<ElementType> & array, CompType cmp);
template<typename IteratorType, typename CompType>
void sort(IteratorType first, IteratorType last, CompType cmp);

最后一種方法更可取,因為您也可以抽象容器類型。

先改這個:

for(; j > -1 && *newptr[j] < *newptr[j+1]; j--)

進入

for(int i=j; i > -1 && *newptr[i] < *newptr[i+1]; i--)

似乎效率更高。。

void sortList(int* list, const size_t &len)
{
    for(size_t i = 0; i < len; ++i)
    {
        for (size_t j = i+1; j < len; ++j)
        {
            if (list[i] > list[j])
            {
                std::swap(list[i], list[j]);
            }
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM