[英]Sorting a linked-list of ints in C++
我必須創建一種從最小到最大順序存儲整數的鏈接列表。 如果您具有或知道如何對鏈表進行排序,請在此處顯示是否關閉和/或教我如何使用C ++進行編碼。
我經常通過索引指針列表對鏈接列表進行排序。 要構建一個,需要的內存分配等於節點數(N)*節點指針的大小。 這個概念很簡單。
注:該算法是C,因為我不能完全肯定是否意味着這個類作為一個C ++的問題( 到底誰在使用您的處置??鏈接在C列出++與標准集裝箱)的OP
qsort()
因為它是標准配備的)。 您的鏈接列表已排序。
假設您的節點是這樣的:
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.