Sự khác biệt giữa SortedList và SortedDipedia là gì?


261

Có sự khác biệt thực tế nào giữa a SortedList<TKey,TValue>và a SortedDictionary<TKey,TValue>không? Có bất kỳ trường hợp nào bạn đặc biệt sử dụng một và không phải là khác?



13
Tôi bối rối. Tại sao SortedList có hai tham số loại SortedList<TKey,TValue>chứ không phải một SortedList<T>? Tại sao nó không thực hiện IList<T>?
Đại tá Panic

3
@ColonelPanic vì Sắp xếp theo chức năng là một bản đồ, không phải là một bộ sưu tập tuyến tính. Đừng để cái tên đánh lừa bạn. Giống như một từ điển, bạn chuyển vào một khóa, bạn nhận lại một giá trị. Trong khi từ điển không có thứ tự, SortedList được sắp xếp theo thứ tự tự nhiên được sắp xếp.
nawfal

Câu trả lời:


294

Có - đặc điểm hiệu suất của chúng khác nhau đáng kể. Có lẽ sẽ tốt hơn nếu gọi họ SortedListSortedTreevì điều đó phản ánh việc thực hiện chặt chẽ hơn.

Nhìn vào các tài liệu MSDN cho từng trong số chúng ( SortedList, SortedDictionary) để biết chi tiết về hiệu suất cho các hoạt động khác nhau trong các tình huống khác nhau. Đây là một bản tóm tắt hay (từ các SortedDictionarytài liệu):

Lớp SortedDictionary<TKey, TValue>chung là một cây tìm kiếm nhị phân với truy xuất O (log n), trong đó n là số phần tử trong từ điển. Trong đó, nó tương tự như SortedList<TKey, TValue>lớp chung. Hai lớp có các mô hình đối tượng tương tự nhau và cả hai đều có truy xuất O (log n). Trường hợp hai lớp khác nhau là về sử dụng bộ nhớ và tốc độ chèn và loại bỏ:

  • SortedList<TKey, TValue>sử dụng ít bộ nhớ hơn SortedDictionary<TKey, TValue>.

  • SortedDictionary<TKey, TValue>có các hoạt động chèn và xóa nhanh hơn cho dữ liệu chưa được sắp xếp, O (log n) trái ngược với O (n) cho SortedList<TKey, TValue>.

  • Nếu danh sách được điền tất cả cùng một lúc từ dữ liệu được sắp xếp, SortedList<TKey, TValue>sẽ nhanh hơn SortedDictionary<TKey, TValue>.

( SortedListthực sự duy trì một mảng được sắp xếp, thay vì sử dụng cây. Nó vẫn sử dụng tìm kiếm nhị phân để tìm các phần tử.)


Cảm ơn v rất nhiều cho tất cả các con trỏ. Tôi đoán tôi quá lười biếng với RTFM ... dễ dàng hơn nhiều khi hỏi những người tốt về SO ...;) Tôi đã bình chọn cho cả hai bạn cho câu trả lời; Jon nhận được câu trả lời tín dụng cho lần đầu tiên kích hoạt. :)
Shaul Behr

2
Tôi nghĩ định nghĩa SortedList nên được sửa vì tôi không tin đó là cây tìm kiếm nhị phân ...?
nchaud

1
Tôi đã xem xét bằng phản xạ và thấy rằng nó không sử dụng cây tìm kiếm nhị phân.
Daniel Imms

. Tôi nghĩ rằng SortedDictionary là một AVL-cây hoặc đỏ Blacktree (tất cả chi phí vận hành O (logn) Và SortedList là một nhị phân tìm kiếm (chi phí o (n) thời gian trong trường hợp xấu nhất) l
Ghoster

105

Đây là chế độ xem dạng bảng nếu nó giúp ...

Từ góc độ hiệu suất :

+------------------+---------+----------+--------+----------+----------+---------+
| Collection       | Indexed | Keyed    | Value  | Addition |  Removal | Memory  |
|                  | lookup  | lookup   | lookup |          |          |         |
+------------------+---------+----------+--------+----------+----------+---------+
| SortedList       | O(1)    | O(log n) | O(n)   | O(n)*    | O(n)     | Lesser  |
| SortedDictionary | n/a     | O(log n) | O(n)   | O(log n) | O(log n) | Greater |
+------------------+---------+----------+--------+----------+----------+---------+

* Insertion is O(1) for data that are already in sort order, so that each 
  element is added to the end of the list (assuming no resize is required).

Từ góc độ thực hiện :

+------------+---------------+----------+------------+------------+------------------+
| Underlying | Lookup        | Ordering | Contiguous | Data       | Exposes Key &    |
| structure  | strategy      |          | storage    | access     | Value collection |
+------------+---------------+----------+------------+------------+------------------+
| 2 arrays   | Binary search | Sorted   | Yes        | Key, Index | Yes              |
| BST        | Binary search | Sorted   | No         | Key        | Yes              |
+------------+---------------+----------+------------+------------+------------------+

Để diễn giải đại khái , nếu bạn yêu cầu hiệu năng thô SortedDictionarycó thể là một lựa chọn tốt hơn. Nếu bạn yêu cầu ít bộ nhớ hơn và truy xuất được lập chỉ mục SortedListphù hợp hơn. Xem câu hỏi này để biết thêm khi nào nên sử dụng.

Bạn có thể đọc thêm ở đây , ở đây , ở đây , ở đâyở đây .


Lưu ý rằng nếu bạn muốn hiệu năng tốt sử dụng bộ nhớ tương đối thấp truy xuất được lập chỉ mục, hãy xem xét BDictionary<Key,Value>trong LoycCore thay vì SortedDictionary.
Qwertie

1
Vâng, nhìn vào phần dưới cùng của bài viết này . Hóa ra BDictionarythường chậm hơn SortedDictionaryngoại trừ kích thước rất lớn, nhưng nó nhanh hơn SortedListnếu có hơn 700 mặt hàng. Việc sử dụng bộ nhớ chỉ nên cao hơn một chút so với SortedList(thấp hơn nhiều so với SortedDictionary), do sử dụng các mảng trong lá của cây.
Qwertie

22

Tôi bẻ khóa Reflector để có cái nhìn về điều này vì dường như có một chút nhầm lẫn về SortedList. Thực tế nó không phải là cây tìm kiếm nhị phân, nó là một mảng được sắp xếp (theo khóa) của các cặp khóa-giá trị . Ngoài ra còn có một TKey[] keysbiến được sắp xếp đồng bộ với các cặp khóa-giá trị và được sử dụng để tìm kiếm nhị phân.

Đây là một số nguồn (nhắm mục tiêu .NET 4.5) để sao lưu các khiếu nại của tôi.

Thành viên tư nhân

// Fields
private const int _defaultCapacity = 4;
private int _size;
[NonSerialized]
private object _syncRoot;
private IComparer<TKey> comparer;
private static TKey[] emptyKeys;
private static TValue[] emptyValues;
private KeyList<TKey, TValue> keyList;
private TKey[] keys;
private const int MaxArrayLength = 0x7fefffff;
private ValueList<TKey, TValue> valueList;
private TValue[] values;
private int version;

SortedList.ctor (IDadata, IComparer)

public SortedList(IDictionary<TKey, TValue> dictionary, IComparer<TKey> comparer) : this((dictionary != null) ? dictionary.Count : 0, comparer)
{
    if (dictionary == null)
    {
        ThrowHelper.ThrowArgumentNullException(ExceptionArgument.dictionary);
    }
    dictionary.Keys.CopyTo(this.keys, 0);
    dictionary.Values.CopyTo(this.values, 0);
    Array.Sort<TKey, TValue>(this.keys, this.values, comparer);
    this._size = dictionary.Count;
}

SortedList.Add (TKey, TValue): void

public void Add(TKey key, TValue value)
{
    if (key == null)
    {
        ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
    }
    int num = Array.BinarySearch<TKey>(this.keys, 0, this._size, key, this.comparer);
    if (num >= 0)
    {
        ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_AddingDuplicate);
    }
    this.Insert(~num, key, value);
}

Sắp xếp danh sách.RemoveAt (int): void

public void RemoveAt(int index)
{
    if ((index < 0) || (index >= this._size))
    {
        ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_Index);
    }
    this._size--;
    if (index < this._size)
    {
        Array.Copy(this.keys, index + 1, this.keys, index, this._size - index);
        Array.Copy(this.values, index + 1, this.values, index, this._size - index);
    }
    this.keys[this._size] = default(TKey);
    this.values[this._size] = default(TValue);
    this.version++;
}

13

Kiểm tra trang MSDN cho SortedList :

Từ phần Nhận xét:

Lớp SortedList<(Of <(TKey, TValue>)>)chung là một cây tìm kiếm nhị phân có O(log n)truy xuất, trong đó nsố lượng phần tử trong từ điển. Trong đó, nó tương tự như SortedDictionary<(Of <(TKey, TValue>)>)lớp chung. Hai lớp có mô hình đối tượng tương tự và cả hai đều có O(log n)truy xuất. Trường hợp hai lớp khác nhau là về sử dụng bộ nhớ và tốc độ chèn và loại bỏ:

  • SortedList<(Of <(TKey, TValue>)>)sử dụng ít bộ nhớ hơn SortedDictionary<(Of <(TKey, TValue>)>).
  • SortedDictionary<(Of <(TKey, TValue>)>)có các hoạt động chèn và xóa nhanh hơn cho dữ liệu chưa được sắp xếp, O(log n)trái ngược O(n)với SortedList<(Of <(TKey, TValue>)>).

  • Nếu danh sách được điền tất cả cùng một lúc từ dữ liệu được sắp xếp, SortedList<(Of <(TKey, TValue>)>)sẽ nhanh hơn SortedDictionary<(Of <(TKey, TValue>)>).


9
Văn bản được trích dẫn là sai (và đã được cập nhật trên MSDN): SortedList không phải là "cây tìm kiếm nhị phân", nó là một "mảng các cặp khóa / giá trị".
Câu hỏi hóc búa Eldritch

12

Đây là đại diện trực quan về cách các màn trình diễn so sánh với nhau.


Bạn lấy thông tin đó từ đâu? Từ sơ đồ này, chúng ta có thể thấy rằng Dictinary tốt hơn bằng mọi cách, vì vậy không có lý do gì để người khác tồn tại.
alex kostin

9

Đủ nói về chủ đề này, tuy nhiên để đơn giản, đây là cách tôi làm.

Từ điển được sắp xếp nên được sử dụng khi-

  • Cần thêm thao tác chèn và xóa.
  • Dữ liệu không theo thứ tự.
  • Truy cập khóa là đủ và không cần truy cập chỉ mục.
  • Bộ nhớ không phải là nút cổ chai.

Mặt khác, Danh sách được sắp xếp nên được sử dụng khi-

  • Yêu cầu nhiều tra cứu hơn và ít thao tác chèn và xóa hơn.
  • Dữ liệu đã được sắp xếp (nếu không phải tất cả, hầu hết).
  • Chỉ số truy cập là cần thiết.
  • Bộ nhớ là một chi phí chung.

Hi vọng điêu nay co ich!!


1

Chỉ số truy cập (được đề cập ở đây) là sự khác biệt thực tế. Nếu bạn cần truy cập người kế nhiệm hoặc người tiền nhiệm, bạn cần Sắp xếp danh sách. SortedDixi không thể làm điều đó vì vậy bạn khá hạn chế với cách bạn có thể sử dụng sắp xếp (đầu tiên / foreach).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.