जब लिस्ट बनाम लिंक्डलिस्ट का उपयोग करना बेहतर होता है ?
जब लिस्ट बनाम लिंक्डलिस्ट का उपयोग करना बेहतर होता है ?
जवाबों:
कृपया इस उत्तर के लिए टिप्पणियों को पढ़ें। लोग दावा करते हैं कि मैंने उचित परीक्षण नहीं किया। मैं मानता हूं कि यह एक स्वीकृत उत्तर नहीं होना चाहिए। जैसा कि मैं सीख रहा था मैंने कुछ परीक्षण किए और उन्हें साझा करने की तरह महसूस किया।
मुझे दिलचस्प परिणाम मिले:
// Temporary class to show the example
class Temp
{
public decimal A, B, C, D;
public Temp(decimal a, decimal b, decimal c, decimal d)
{
A = a; B = b; C = c; D = d;
}
}
LinkedList<Temp> list = new LinkedList<Temp>();
for (var i = 0; i < 12345678; i++)
{
var a = new Temp(i, i, i, i);
list.AddLast(a);
}
decimal sum = 0;
foreach (var item in list)
sum += item.A;
List<Temp> list = new List<Temp>(); // 2.4 seconds
for (var i = 0; i < 12345678; i++)
{
var a = new Temp(i, i, i, i);
list.Add(a);
}
decimal sum = 0;
foreach (var item in list)
sum += item.A;
यहां तक कि अगर आप केवल आवश्यक रूप से डेटा का उपयोग करते हैं, तो यह बहुत धीमा है !! मैं कहता हूं कि लिंक्डलिस्ट का इस्तेमाल कभी न करें।
यहाँ बहुत सारी आवेषणों की तुलना की जा रही है (हम सूची के बीच में एक आइटम डालने की योजना बनाते हैं)
LinkedList<Temp> list = new LinkedList<Temp>();
for (var i = 0; i < 123456; i++)
{
var a = new Temp(i, i, i, i);
list.AddLast(a);
var curNode = list.First;
for (var k = 0; k < i/2; k++) // In order to insert a node at the middle of the list we need to find it
curNode = curNode.Next;
list.AddAfter(curNode, a); // Insert it after
}
decimal sum = 0;
foreach (var item in list)
sum += item.A;
List<Temp> list = new List<Temp>();
for (var i = 0; i < 123456; i++)
{
var a = new Temp(i, i, i, i);
list.Insert(i / 2, a);
}
decimal sum = 0;
foreach (var item in list)
sum += item.A;
list.AddLast(new Temp(1,1,1,1));
var referenceNode = list.First;
for (var i = 0; i < 123456; i++)
{
var a = new Temp(i, i, i, i);
list.AddLast(a);
list.AddBefore(referenceNode, a);
}
decimal sum = 0;
foreach (var item in list)
sum += item.A;
इसलिए केवल यदि आप कई वस्तुओं को सम्मिलित करने की योजना बनाते हैं और आपके पास कहीं न कहीं यह संदर्भ भी है कि आप आइटम कहाँ सम्मिलित करना चाहते हैं तो एक लिंक की गई सूची का उपयोग करें। सिर्फ इसलिए कि आपको बहुत सी वस्तुओं को सम्मिलित करना होगा क्योंकि यह तेजी से नहीं बनती है क्योंकि उस स्थान को खोजना जहां आप सम्मिलित करना पसंद करेंगे, इसमें समय लगता है।
list.AddLast(a);
पिछले दो लिंक्डलिस्ट उदाहरणों में इन-लूप क्यों ? मैं इसे एक बार लूप से पहले कर रहा हूं, जैसे list.AddLast(new Temp(1,1,1,1));
कि अगले लिंक्डलिस्ट में, लेकिन यह मुझे (मुझे) लगता है जैसे आप खुद लूप में कई टेंप ऑब्जेक्ट्स से दो बार जोड़ रहे हैं। (और जब मैं अपने आप को एक परीक्षण ऐप के साथ दोहराता हूं , तो निश्चित रूप से, लिंक्डलिस्ट में दो बार पर्याप्त रूप से।)
I say never use a linkedList.
त्रुटिपूर्ण है क्योंकि आपकी बाद की पोस्ट से पता चलता है। आप इसे संपादित करना चाह सकते हैं। 2) आप समय क्या कर रहे हैं? तात्कालिकता, जोड़ और गणना एक कदम में पूरी तरह से? अधिकतर, तात्कालिकता और अभिज्ञान वे नहीं हैं जो ppl के बारे में चिंतित हैं, वे एक समय के कदम हैं। विशेष रूप से आवेषण और परिवर्धन का समय बेहतर विचार देगा। 3) सबसे महत्वपूर्ण बात, आप किसी लिंकलिस्ट से आवश्यकता से अधिक जोड़ रहे हैं। यह एक गलत तुलना है। लिंक्डलिस्ट के बारे में गलत विचार फैलाता है।
ज्यादातर मामलों में, List<T>
अधिक उपयोगी है। LinkedList<T>
सूची के मध्य में वस्तुओं को जोड़ने / हटाने के दौरान कम लागत होगी, जबकि सूची List<T>
के अंत में केवल सस्ते में जोड़ / हटा सकते हैं ।
LinkedList<T>
यदि आप अनुक्रमिक डेटा (या तो आगे या पीछे) का उपयोग कर रहे हैं, तो यह केवल सबसे कुशल है - यादृच्छिक अभिगम अपेक्षाकृत महंगा है क्योंकि इसे प्रत्येक बार श्रृंखला चलना चाहिए (इसलिए इसमें अनुक्रमणिका क्यों नहीं है)। हालाँकि, क्योंकि एक List<T>
अनिवार्य रूप से सिर्फ एक सरणी (एक आवरण के साथ) यादृच्छिक पहुँच ठीक है।
List<T>
भी समर्थन के तरीकों का एक बहुत प्रदान करता है - Find
, ToArray
, आदि; हालाँकि, ये LinkedList<T>
.NET 3.5 / C # 3.0 एक्सटेंशन विधियों के माध्यम से भी उपलब्ध हैं - इसलिए यह एक कारक से कम नहीं है।
List<T>
और T[]
बहुत चंकी (सभी एक स्लैब) होने के लिए असफल हो जाएगा, LinkedList<T>
बहुत दानेदार (प्रति तत्व स्लैब) होने के लिए विलीन हो जाएगा।
एक सूची के रूप में एक लिंक की गई सूची के बारे में सोचना थोड़ा भ्रामक हो सकता है। यह एक श्रृंखला की तरह अधिक है। वास्तव में, .NET में, LinkedList<T>
लागू नहीं होता है IList<T>
। लिंक की गई सूची में सूचकांक की कोई वास्तविक अवधारणा नहीं है, भले ही ऐसा लगता है कि यह है। निश्चित रूप से कक्षा में प्रदान किए गए तरीकों में से कोई भी अनुक्रमणिका स्वीकार नहीं करता है।
लिंक की गई सूचियों को एकल रूप से जोड़ा जा सकता है, या दोगुना लिंक किया जा सकता है। यह संदर्भित करता है कि क्या श्रृंखला में प्रत्येक तत्व का लिंक केवल अगले एक (एकल रूप से जुड़ा हुआ) या दोनों पूर्व / अगले तत्वों (दोगुना जुड़ा हुआ) है। LinkedList<T>
दोगुना जुड़ा हुआ है।
आंतरिक रूप से, List<T>
एक सरणी द्वारा समर्थित है। यह स्मृति में एक बहुत कॉम्पैक्ट प्रतिनिधित्व प्रदान करता है। इसके विपरीत, LinkedList<T>
क्रमिक तत्वों के बीच द्विदिश लिंक को संग्रहीत करने के लिए अतिरिक्त मेमोरी शामिल है। इसलिए LinkedList<T>
वसीयत की स्मृति पदचिह्न आम तौर पर List<T>
(कैविट के साथ बड़ा हो List<T>
सकता है जो अप्रयुक्त आंतरिक सरणी तत्व हो सकते हैं जो परिशिष्ट संचालन के दौरान प्रदर्शन में सुधार करते हैं।)
उनकी विभिन्न प्रदर्शन विशेषताएँ भी हैं:
LinkedList<T>.AddLast(item)
निरंतर समयList<T>.Add(item)
amortized निरंतर समय, रैखिक सबसे खराब स्थितिLinkedList<T>.AddFirst(item)
निरंतर समयList<T>.Insert(0, item)
रैखिक समयLinkedList<T>.AddBefore(node, item)
निरंतर समयLinkedList<T>.AddAfter(node, item)
निरंतर समयList<T>.Insert(index, item)
रैखिक समयLinkedList<T>.Remove(item)
रैखिक समयLinkedList<T>.Remove(node)
निरंतर समयList<T>.Remove(item)
रैखिक समयList<T>.RemoveAt(index)
रैखिक समयLinkedList<T>.Count
निरंतर समयList<T>.Count
निरंतर समयLinkedList<T>.Contains(item)
रैखिक समयList<T>.Contains(item)
रैखिक समयLinkedList<T>.Clear()
रैखिक समयList<T>.Clear()
रैखिक समयजैसा कि आप देख सकते हैं, वे ज्यादातर समान हैं। व्यवहार में, एपीआई का LinkedList<T>
उपयोग करने के लिए अधिक बोझिल है, और इसकी आंतरिक आवश्यकताओं का विवरण आपके कोड में फैल जाता है।
हालाँकि, यदि आपको किसी सूची में से कई प्रविष्टि / निष्कासन करने की आवश्यकता है, तो यह निरंतर समय प्रदान करता है। List<T>
सूची में अतिरिक्त आइटम डालने / हटाने के बाद चारों ओर फेरबदल किया जाना चाहिए क्योंकि रैखिक समय प्रदान करता है।
लिंक की गई सूची बहुत तेजी से प्रविष्टि या सूची सदस्य को हटाने की सुविधा प्रदान करती है। लिंक की गई सूची में प्रत्येक सदस्य के पास सूची में अगले सदस्य के लिए एक पॉइंटर होता है ताकि मैं किसी सदस्य को पद पर सम्मिलित कर सकूँ:
एक लिंक की गई सूची का नुकसान यह है कि यादृच्छिक पहुंच संभव नहीं है। जब तक वांछित सदस्य नहीं मिल जाता, तब तक सदस्य तक पहुँचने के लिए सूची का पता लगाना आवश्यक है।
मेरा पिछला उत्तर पर्याप्त सटीक नहीं था। जैसा कि वास्तव में यह भयानक था: डी लेकिन अब मैं बहुत अधिक उपयोगी और सही उत्तर पोस्ट कर सकता हूं।
मैंने कुछ अतिरिक्त परीक्षण किए। आप इसे निम्न लिंक से प्राप्त कर सकते हैं और इसे अपने पर्यावरण पर अपने हिसाब से देख सकते हैं: https://github.com/ukushu/DataStructuresTestsAndOther.git
छोटे परिणाम:
सरणी का उपयोग करने की आवश्यकता है:
सूची का उपयोग करने की आवश्यकता है:
लिंक्डलिस्ट को उपयोग करने की आवश्यकता है:
अधिक जानकारी:
LinkedList<T>
आंतरिक रूप से .NET में एक सूची नहीं है। यह भी लागू नहीं होता है IList<T>
। और इसीलिए अनुक्रमणिका से संबंधित अनुपस्थित सूचकांक और विधियाँ हैं।
LinkedList<T>
नोड-पॉइंटर आधारित संग्रह है। .NET में यह दोगुना लिंक्ड इंप्लीमेंटेशन है। इसका अर्थ है कि पूर्व / अगले तत्वों का वर्तमान तत्व से लिंक है। और डेटा खंडित है - विभिन्न सूची ऑब्जेक्ट्स रैम के विभिन्न स्थानों में स्थित हो सकते हैं। इसके अलावा या ऐरे की LinkedList<T>
तुलना में अधिक मेमोरी का उपयोग किया जाएगा List<T>
।
List<T>
.Net में जावा का विकल्प है ArrayList<T>
। इसका मतलब है कि यह सरणी आवरण है। तो यह डेटा के एक सन्निहित ब्लॉक के रूप में मेमोरी में आवंटित किया जाता है। यदि आवंटित डेटा आकार 85000 बाइट्स से अधिक है, तो इसे बड़े ऑब्जेक्ट हीप में ले जाया जाएगा। आकार के आधार पर, यह ढेर विखंडन (स्मृति रिसाव का एक हल्का रूप) हो सकता है। लेकिन एक ही समय में यदि आकार <85000 बाइट्स - यह स्मृति में एक बहुत ही कॉम्पैक्ट और तेज़-पहुंच प्रतिनिधित्व प्रदान करता है।
एकल सन्निहित ब्लॉक को यादृच्छिक अभिगम प्रदर्शन और स्मृति की खपत के लिए पसंद किया जाता है, लेकिन संग्रह के लिए जिन्हें आकार को नियमित रूप से बदलने की आवश्यकता होती है जैसे कि एक सरणी को आम तौर पर एक नए स्थान पर कॉपी करने की आवश्यकता होती है जबकि एक लिंक की गई सूची को केवल नए सम्मिलित किए गए मेमोरी को प्रबंधित करने की आवश्यकता होती है / हटाए गए नोड्स।
सूची और लिंक्डलिस्ट के बीच अंतर उनके अंतर्निहित कार्यान्वयन में निहित है। सूची सरणी आधारित संग्रह (ArrayList) है। LinkedList नोड-पॉइंटर आधारित संग्रह (LinkedListNode) है। एपीआई स्तर के उपयोग पर, दोनों बहुत अधिक समान हैं, क्योंकि दोनों समान इंटरफेस जैसे कि ICollection, IEnumerable, आदि को लागू करते हैं।
प्रदर्शन के मामले में महत्वपूर्ण अंतर आता है। उदाहरण के लिए, यदि आप उस सूची को लागू कर रहे हैं जिसमें "INSERT" ऑपरेशन भारी है, लिंक्डलिस्ट आउटपरफॉर्म लिस्ट। चूंकि लिंक्डलिस्ट इसे ओ (1) समय में कर सकता है, लेकिन सूची में अंतर्निहित सरणी के आकार का विस्तार करने की आवश्यकता हो सकती है। अधिक जानकारी / विवरण के लिए आप लिंक्डलिस्ट और एरे डेटा संरचनाओं के बीच एल्गोरिथम अंतर पर पढ़ना चाह सकते हैं। http://en.wikipedia.org/wiki/Linked_list और Array
उममीद है कि इससे मदद मिलेगी,
Add
हमेशा मौजूदा सरणी के अंत में होता है। List
उस पर "काफी अच्छा" है, भले ही ओ (1) न हो। गंभीर समस्या तब होती है जब आपको कई Add
एस की आवश्यकता होती है जो अंत में नहीं होती हैं । मार्क इशारा कर रहा है कि आपके द्वारा डाले जाने पर हर बार मौजूदा डेटा को स्थानांतरित करने की आवश्यकता है (न कि केवल जब रिसाइज की आवश्यकता हो) अधिक प्रदर्शन लागत है List
।
सरणियों से जुड़ी सूचियों का प्राथमिक लाभ यह है कि लिंक हमें वस्तुओं को कुशलता से पुनर्व्यवस्थित करने की क्षमता प्रदान करते हैं। सेडगेविक, पी। 91
लिंक्डलिस्ट का उपयोग करने के लिए एक सामान्य परिस्थिति इस प्रकार है:
मान लीजिए कि आप एक बड़े आकार के साथ तार की एक सूची से कई निश्चित तारों को निकालना चाहते हैं, 100,000 का कहना है। हटाने के लिए तार को हाससेट डिक में देखा जा सकता है, और माना जाता है कि तार की सूची में 30,000 से 60,000 के बीच के तार शामिल हैं।
फिर 100,000 स्ट्रिंग्स के भंडारण के लिए सबसे अच्छी प्रकार की सूची क्या है? जवाब है लिंक्डलिस्ट। यदि वे एक ऐरेलिस्ट में संग्रहीत होते हैं, तो उस पर पुनरावृत्ति करना और मिलान किए गए स्ट्रिंग्स को हटा देना, अरबों परिचालनों तक ले जाता है, जबकि एक इटेरेटर और निष्कासन () विधि का उपयोग करके केवल लगभग 100,000 ऑपरेशन होते हैं।
LinkedList<String> strings = readStrings();
HashSet<String> dic = readDic();
Iterator<String> iterator = strings.iterator();
while (iterator.hasNext()){
String string = iterator.next();
if (dic.contains(string))
iterator.remove();
}
RemoveAll
वस्तुओं को हटाने के लिए उपयोग कर सकते हैं List
, या Where
दूसरी सूची बनाने के लिए LINQ से उपयोग कर सकते हैं। LinkedList
हालांकि यहाँ उपयोग करने से अन्य प्रकार के संग्रहों की तुलना में नाटकीय रूप से अधिक मेमोरी का उपभोग होता है और मेमोरी लोकलिटी के खो जाने का अर्थ है कि यह इरीटेट करने के लिए काफी धीमा होगा, जिससे यह काफी खराब हो जाएगा List
।
RemoveAll
जावा में एक बराबर है।
RemoveAll
इसके लिए उपलब्ध नहीं है List
, तो आप एक "संघनन" एल्गोरिथ्म कर सकते हैं, जो टॉम के लूप की तरह दिखेगा, लेकिन दो सूचकांकों के साथ और आइटम को सूची के आंतरिक सरणी में एक बार में रखने के लिए स्थानांतरित करने की आवश्यकता है। दक्षता ओ (एन) है, टॉम के एल्गोरिथ्म के लिए समान है LinkedList
। दोनों संस्करणों में, स्ट्रिंग्स के लिए हाशसेट कुंजी की गणना करने का समय हावी है। यह कब उपयोग करना है इसका अच्छा उदाहरण नहीं है LinkedList
।
जब आपको अंतर्निहित अनुक्रमणित पहुंच की आवश्यकता होती है, तो छंटनी (और इस बाइनरी खोज के बाद), और "ToArray ()" विधि, आपको सूची का उपयोग करना चाहिए।
अनिवार्य रूप से, एक List<>
.NET एक सरणी पर एक आवरण है । A LinkedList<>
लिंक की गई सूची है । तो यह सवाल नीचे आता है कि किसी सरणी और लिंक की गई सूची में क्या अंतर है, और लिंक की गई सूची के बजाय किसी सरणी का उपयोग कब किया जाना चाहिए। संभवतः आपके निर्णय के दो सबसे महत्वपूर्ण कारक जिनका उपयोग करना नीचे आता है:
यह टोनो नाम से अनुकूलित है के स्वीकृत उत्तर इसमें कुछ गलत माप को सही किया गया है।
कसौटी:
static void Main()
{
LinkedListPerformance.AddFirst_List(); // 12028 ms
LinkedListPerformance.AddFirst_LinkedList(); // 33 ms
LinkedListPerformance.AddLast_List(); // 33 ms
LinkedListPerformance.AddLast_LinkedList(); // 32 ms
LinkedListPerformance.Enumerate_List(); // 1.08 ms
LinkedListPerformance.Enumerate_LinkedList(); // 3.4 ms
//I tried below as fun exercise - not very meaningful, see code
//sort of equivalent to insertion when having the reference to middle node
LinkedListPerformance.AddMiddle_List(); // 5724 ms
LinkedListPerformance.AddMiddle_LinkedList1(); // 36 ms
LinkedListPerformance.AddMiddle_LinkedList2(); // 32 ms
LinkedListPerformance.AddMiddle_LinkedList3(); // 454 ms
Environment.Exit(-1);
}
और कोड:
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
namespace stackoverflow
{
static class LinkedListPerformance
{
class Temp
{
public decimal A, B, C, D;
public Temp(decimal a, decimal b, decimal c, decimal d)
{
A = a; B = b; C = c; D = d;
}
}
static readonly int start = 0;
static readonly int end = 123456;
static readonly IEnumerable<Temp> query = Enumerable.Range(start, end - start).Select(temp);
static Temp temp(int i)
{
return new Temp(i, i, i, i);
}
static void StopAndPrint(this Stopwatch watch)
{
watch.Stop();
Console.WriteLine(watch.Elapsed.TotalMilliseconds);
}
public static void AddFirst_List()
{
var list = new List<Temp>();
var watch = Stopwatch.StartNew();
for (var i = start; i < end; i++)
list.Insert(0, temp(i));
watch.StopAndPrint();
}
public static void AddFirst_LinkedList()
{
var list = new LinkedList<Temp>();
var watch = Stopwatch.StartNew();
for (int i = start; i < end; i++)
list.AddFirst(temp(i));
watch.StopAndPrint();
}
public static void AddLast_List()
{
var list = new List<Temp>();
var watch = Stopwatch.StartNew();
for (var i = start; i < end; i++)
list.Add(temp(i));
watch.StopAndPrint();
}
public static void AddLast_LinkedList()
{
var list = new LinkedList<Temp>();
var watch = Stopwatch.StartNew();
for (int i = start; i < end; i++)
list.AddLast(temp(i));
watch.StopAndPrint();
}
public static void Enumerate_List()
{
var list = new List<Temp>(query);
var watch = Stopwatch.StartNew();
foreach (var item in list)
{
}
watch.StopAndPrint();
}
public static void Enumerate_LinkedList()
{
var list = new LinkedList<Temp>(query);
var watch = Stopwatch.StartNew();
foreach (var item in list)
{
}
watch.StopAndPrint();
}
//for the fun of it, I tried to time inserting to the middle of
//linked list - this is by no means a realistic scenario! or may be
//these make sense if you assume you have the reference to middle node
//insertion to the middle of list
public static void AddMiddle_List()
{
var list = new List<Temp>();
var watch = Stopwatch.StartNew();
for (var i = start; i < end; i++)
list.Insert(list.Count / 2, temp(i));
watch.StopAndPrint();
}
//insertion in linked list in such a fashion that
//it has the same effect as inserting into the middle of list
public static void AddMiddle_LinkedList1()
{
var list = new LinkedList<Temp>();
var watch = Stopwatch.StartNew();
LinkedListNode<Temp> evenNode = null, oddNode = null;
for (int i = start; i < end; i++)
{
if (list.Count == 0)
oddNode = evenNode = list.AddLast(temp(i));
else
if (list.Count % 2 == 1)
oddNode = list.AddBefore(evenNode, temp(i));
else
evenNode = list.AddAfter(oddNode, temp(i));
}
watch.StopAndPrint();
}
//another hacky way
public static void AddMiddle_LinkedList2()
{
var list = new LinkedList<Temp>();
var watch = Stopwatch.StartNew();
for (var i = start + 1; i < end; i += 2)
list.AddLast(temp(i));
for (int i = end - 2; i >= 0; i -= 2)
list.AddLast(temp(i));
watch.StopAndPrint();
}
//OP's original more sensible approach, but I tried to filter out
//the intermediate iteration cost in finding the middle node.
public static void AddMiddle_LinkedList3()
{
var list = new LinkedList<Temp>();
var watch = Stopwatch.StartNew();
for (var i = start; i < end; i++)
{
if (list.Count == 0)
list.AddLast(temp(i));
else
{
watch.Stop();
var curNode = list.First;
for (var j = 0; j < list.Count / 2; j++)
curNode = curNode.Next;
watch.Start();
list.AddBefore(curNode, temp(i));
}
}
watch.StopAndPrint();
}
}
}
आप देख सकते हैं कि परिणाम सैद्धांतिक प्रदर्शन के अनुसार हैं जो अन्य लोगों ने यहां प्रलेखित किए हैं। काफी स्पष्ट - LinkedList<T>
सम्मिलन के मामले में बड़ा समय। मैंने सूची के मध्य से हटाने के लिए परीक्षण नहीं किया है, लेकिन परिणाम समान होना चाहिए। बेशक List<T>
अन्य क्षेत्रों में यह O (1) यादृच्छिक पहुँच की तरह बेहतर प्रदर्शन करता है।
LinkedList<>
कब का उपयोग करें
Token Stream
।बाकी सभी चीजों के लिए, इसका उपयोग करना बेहतर है List<>
।
LinkedListNode<T>
अपने कोड में वस्तुओं का ट्रैक रखते हैं, तो आपको प्रविष्टि / विलोपन के लिए सूची को स्कैन करने की आवश्यकता नहीं है । यदि आप ऐसा कर सकते हैं, तो यह उपयोग करने से बेहतर है List<T>
, विशेष रूप से बहुत लंबी सूचियों के लिए जहां आवेषण / निष्कासन अक्सर होते हैं।
node.Value
मैं ऊपर दिए गए अधिकांश बिंदुओं से सहमत हूं। और मैं यह भी मानता हूं कि अधिकांश मामलों में सूची एक अधिक स्पष्ट विकल्प की तरह दिखती है।
लेकिन, मैं सिर्फ यह जोड़ना चाहता हूं कि ऐसे कई उदाहरण हैं जहां लिंक्डलिस्ट बेहतर दक्षता के लिए सूची से बेहतर विकल्प हैं।
आशा है कि कोई व्यक्ति इन टिप्पणियों को उपयोगी पाएगा।
इतने सारे औसत उत्तर यहाँ ...
कुछ लिंक किए गए सूची कार्यान्वयन पूर्व आवंटित नोड्स के अंतर्निहित ब्लॉक का उपयोग करते हैं। यदि वे निरंतर समय / रेखीय समय की तुलना में ऐसा नहीं करते हैं तो कम प्रासंगिक है क्योंकि मेमोरी प्रदर्शन खराब होगा और कैश प्रदर्शन भी बदतर होगा।
लिंक की गई सूचियों का उपयोग करें जब
1) आप थ्रेड सुरक्षा चाहते हैं। आप बेहतर थ्रेड सेफ एल्गो बना सकते हैं। लॉकिंग लागत एक समवर्ती शैली सूची पर हावी होगी।
2) यदि आपके पास संरचनाओं की तरह एक बड़ी कतार है और हर समय कहीं भी हटाना या जोड़ना चाहते हैं। > 100K सूचियां मौजूद हैं लेकिन ये आम नहीं हैं।
मैंने लिंक्डलिस्ट संग्रह के प्रदर्शन से संबंधित एक समान प्रश्न पूछा , और स्टीवन क्लीरी के सी # को लागू करने की खोज की, जो एक समाधान था। कतार संग्रह के विपरीत, Deque आगे और पीछे की ओर वस्तुओं को स्थानांतरित करने की अनुमति देता है। यह लिंक्ड सूची के समान है, लेकिन बेहतर प्रदर्शन के साथ।
Deque
है "लिंक्ड सूची के समान है, लेकिन बेहतर प्रदर्शन के साथ" । कि बयान अर्हता प्राप्त करें: Deque
तुलना में बेहतर प्रदर्शन है LinkedList
, अपने विशिष्ट कोड के लिए । आपके लिंक के बाद, मैं देखता हूं कि दो दिन बाद आपने इवान स्टोव से सीखा कि यह लिंक्डलिस्ट की अक्षमता नहीं थी, बल्कि आपके कोड में एक अक्षमता थी। (और यहां तक कि अगर यह लिंक्डलिस्ट की अक्षमता थी, तो यह एक सामान्य कथन को उचित नहीं ठहराएगा कि डी अधिक कुशल है; केवल विशिष्ट मामलों में।)