簡體   English   中英

在C ++中對整數的鏈表進行排序

[英]Sorting a linked-list of ints in C++

我必須創建一種從最小到最大順序存儲整數的鏈接列表。 如果您具有或知道如何對鏈表進行排序,請在此處顯示是否關閉和/或教我如何使用C ++進行編碼。

我經常通過索引指針列表對鏈接列表進行排序。 要構建一個,需要的內存分配等於節點數(N)*節點指針的大小。 這個概念很簡單。

注:該算法是C,因為我不能完全肯定是否意味着這個類作為一個C ++的問題( 到底誰在使用您的處置??鏈接在C列出++與標准集裝箱)的OP

  1. 確定列表中的節點數(N)
  2. 為N個節點指針分配一個指針數組。
  3. 使用列表中的每個節點指針加載指針數組。 即遍歷列表,然后將指針放在指針數組的每個插槽中,並隨您的增加而遞增。
  4. 將此節點指針數組發送到您的排序算法(我喜歡運行時庫qsort()因為它是標准配備的)。
  5. 排序后,遍歷整個指針數組(少一個),將每個節點的“下一個”指針設置為指向后面的指針。 最后一個將其“下一個”指針設置為NULL。
  6. 將頭指針設置為指針數組中的第一個指針[0]。
  7. 釋放指針數組的內存

您的鏈接列表已排序。


假設您的節點是這樣的:

struct node
{
   ..data fields..
   int keyField;  // << determines sort order
   struct node *next;
};

確定列表中的節點數。 我假設您有一個可以執行此操作的proc,這很簡單:

size_t list_count(struct node* head)
{
   size_t count = 0;
   while (head)
   {
      ++count;
      head = head->next;
   }
   return count;
}

分配一個列表大小的指針數組,其中nItems是列表節點計數大於1的列表(煩擾長度為零或一的列表是沒有意義的):

struct node **ptrs = malloc(sizeof(*ptrs)*nItems);

用列表中的所有項目填充指針數組:

struct node *ptr = head;
size_t i=0;
for (;i<nItems;++i,ptr = ptr->next)
    ptrs[i] = ptr;

現在,使用適當的比較函數將其發送到qsort() 下面是一個根據我們結構中的keyField進行排序的比較函數示例:

int compare_node_ptrs(const void* left, const void* right)
{
    struct node *l = *(struct node**)left;
    struct node *r = *(struct node**)right;
    return l->keyField - r->keyField;
}

調用qsort()如下所示:

qsort(ptrs, nItems, sizeof(*ptrs), compare_node_ptrs);

現在遍歷整個列表。 重新連接“下一個”指針:

for (i=0;i<(nItems-2);++i)
    ptrs[i]->next = ptrs[i+1];
ptrs[nItems-1] = NULL;

重新連接頭指針。

head = ptrs[0];

最后,釋放指針數組。

free(ptrs);

您的鏈接列表已排序。


邊欄合並排序是我所知道的唯一O(nlogn)算法,可以對鏈表進行排序,而無需增加空間。 可以原型為以下內容的通用解決方案是nutz:

mergesort_list(void **head, size_t offset_ptr, int(*comp)(void*,void*))

head: address of the head pointer.
offset_ptr: offset in bytes from a node ptr where the 'link' pointer can be found.
comp: comparison function.

如果僅向您顯示代碼,我們將對您造成極大的傷害。 相反,我將為您提供兩種不同的方法,您可以實施自己喜歡的一種方法。

第一種方法是在插入時進行“排序”:在插入值(例如7)時,請按照以下過程從列表中的第一個條目開始,直到用盡節點:

如果要檢查的節點的值大於7,則在要檢查的節點之前插入一個新節點並返回。 否則,您將查看下一個節點。 如果沒有下一個節點,則。 您在列表末尾插入一個新節點,因為這意味着7比列表中的其他條目大,然后返回。

第二種選擇是使用許多排序算法之一對整個列表進行排序。 我建議您使用BubbleSort,因為它易於理解和實施。 您可以在Wikipedia上閱讀有關Bubblesort(其他許多排序算法)的更多信息。

好的舊的quicksort可以解決問題(C ++ 03友好):

#include <algorithm>
#include <functional>
#include <iostream>
#include <iterator>
#include <list>

using namespace std;

void qsort(list<int>::iterator first, list<int>::iterator last)
{
    if (distance(first, last) < 2)
        return;
    int pivot = *first;

    list<int>::iterator it = partition(first, last, bind2nd(less<int>(), pivot));

    qsort(first, it);
    qsort(it, last);
}

int main()
{
    std::list<int> l;
    l.push_back(5);
    l.push_back(4);
    l.push_back(1);
    l.push_back(10);
    l.push_back(3);
    l.push_back(6);
    l.push_back(7);

    cout << "List:";
    copy(l.begin(), l.end(), std::ostream_iterator<int>(std::cout, " "));
    cout << endl;

    qsort(l.begin(), l.end());

    cout << "Sorted list:";
    copy(l.begin(), l.end(), std::ostream_iterator<int>(std::cout, " "));
    cout << endl;
    return 0;
}

檢查: http//ideone.com/OOGXSp

暫無
暫無

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

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