preloader

लिंक्ड-लिस्ट मेमोरी क्रमबद्ध करें

शीर्षक:  लिंक्ड-लिस्ट मेमोरी क्रमबद्ध करें

भाषा:  C

लेखक:  फिलिप जे इर्ड्लेस्की

तारीख:  ३१ जुलाई १९९८

उपयोग:  पब्लिक डोमेन; उपयोग पर कोई प्रतिबंध नहीं

पोर्टेबिलिटी:  कोई सी संकलक

कीवर्ड: लिंक्ड सूची, सॉर्ट करें

सार:
एक सी फ़ंक्शन मेमोरी में लिंक्ड सूची को हल करने के लिए, एक मनमानी तुलना फ़ंक्शन और टेप-मर्ज एल्गोरिथम का उपयोग करके, जो सभी मामलों में हे (एन लॉग एन) है। फ़ंक्शन गैर-रिकर्सिव और पुन: प्रवेश किया जाता है, और केवल लिंक्स को बदलता है।

लिंक्ड सूचियां और सॉर्ट दिनचर्या प्रोग्रामिंग में बहुत आम हैं।

फ़ंक्शन सॉर्ट लिंक की गई सूची () कॉलिंग प्रोग्राम द्वारा प्रदान किए गए एक तुलना फ़ंक्शन का उपयोग करके, लगभग किसी भी प्रकार की एकल-लिंक की गई सूची को सॉर्ट करेगा। इसमें क्यूसॉर्ट () पर निम्न लाभ हैं:

  1. यह चर आकार केतत्वों को बनादेता है।
  2. शुरुआती आदेश की परवाह किए बिना, ओ (एन लॉग एन) तुलना की आवश्यकता है एक सूची को सॉर्ट करने का समय पूर्वानुमानित और सुसंगत है। यह प्रदर्शन सामान्य प्रकार के लिए अनुकूलतम माना जाता है।
  3. एल्गोरिथ्म पुनरावर्ती है, पुनरावर्ती नहीं है, इसलिए स्टैक अतिप्रवाह की कोई समस्या नहीं है। स्टैक की आवश्यकता पूर्वानुमानित, सुसंगत और छोटी है।
  4. यह लिंक्ड सूची को पॉइंटर्स बदलकर बदलती है, तत्वों को स्वयं नहीं ले जाकर।
  5. यह एक सरणी में फ़िट होने के लिए बहुत बड़ी सूची को सॉर्ट कर सकता है।

फ़ंक्शन केवल सिंगली लिंक से संबंधित सूची अगर एक सूची दुगुनी से जुड़ी हुई है, तो कोड की कुछ पंक्तियों के अनुसार पिछड़े संकेतों को बहाल किया जा सकता है।

एक लिंक्ड सूची के प्रत्येक तत्व को सॉर्ट किया जाना चाहिए जिसमें उसके पहले सदस्य, एक या एक से अधिक पॉइंटर्स होंगे। एक संकेतक, जो प्रत्येक तत्व में समान रिश्तेदार स्थिति में होना चाहिए, अगले तत्व के लिए एक सूचक है। यह सूचक अंतिम तत्व में नल है

सूचकांक प्रत्येक तत्व में इस सूचक की स्थिति है। यह पहली सूचक के लिए 0 है, 1 दूसरे सूचक के लिए, आदि।

चलो तुलना () एक तुलना समारोह है जो निम्न तत्वों की तुलना करता है:

n = compare(p, q, pointer);

void *p, *q;    pointers to two list elements

void *pointer;  user-defined pointer passed to compare() by

linked_list_sort()

int n;   result of comparing *p and *q

>0 if *p is to be after *q in sorted order

<0 if *p is to be before *q in sorted order

0 if the order of *p and *q is irrelevant

“पहले” सूची के पहले तत्व के लिए एक सूचक हो। फिर निम्नलिखित फ़ंक्शन कॉल सूची को क्रमबद्ध करता है और सॉर्ट किए गए सूची के पहले तत्व को एक सूचक देता है:

first_sorted =  sort_linked_list(first, index, compare, pointer, pcount);चौथे तर्क (संकेतक) को बिना बदलाव के () तुलना करने के लिए पारित किया गया है यहां दिया गया उदाहरण पॉइंटर का उपयोग नहीं करता है। हालांकि, यह एक अमूल्य सुविधा हो सकती है यदि दो या अधिक तुलनात्मक तरीकों का पर्याप्त मात्रा में कोड साझा होता है और केवल एक या अधिक पैरामीटर मूल्यों में अंतर होता है।

अंतिम तर्क (पीकाउंट) प्रकार का है (अहस्ताक्षरित लंबे *) अगर यह नल नहीं है, तो * पक्का सूची में रिकॉर्ड की संख्या के बराबर सेट है।

खाली सूची को सॉर्ट करने के लिए अनुमत है यदि पहले == नल, तो लौटा मूल्य भी शून्य होगा। उदाहरण के लिए, एक तत्व में एक नाम और एक संख्या दोनों हो सकती है:

struct element

{   struct element *next_in_alphabetical_order;      struct element *next_in_numerical_order;      char name[9];      int number;      /* other members, if any */    };

प्रारंभ में, प्रत्येक तत्व में दो बिंदु समान होते हैं, और यह सूची मनमानी क्रम में होती है, जहां “पहले” प्रथम तत्व का सूचक होता है निम्न दो फ़ंक्शन कॉल को दो बार सॉर्ट करता है:

first_in_alphabetical_order =  sort_linked_list(first, 0, compare_names, NULL);    first_in_numerical_order =      sort_linked_list(first, 1, compare_numbers, NULL);

यहां तुलना फ़ंक्शन हैं:

int compare_names(struct element *p, struct element *q,   void *pointer)    {      return strcmp(p->name, q->name);    }     int compare_numbers(struct element *p, struct element *q,      void *pointer)    {      return p->number > q->number ? 1 : -1;      /* NOTE: return p->number – q->number will suffice if there is      no danger of numeric overflow */    }

इस प्रकार का एक पिछले संस्करण, जो एक तकनीकी जर्नल में प्रकाशित हुआ था, को प्रत्येक तत्व की शुरुआत में आगे के लिंक की आवश्यकता थी हालांकि इस तरह से कुछ अधिक कुशल बना दिया गया है, इसके साथ ही यह गुणा लिंक से संबंधित सूचियों के साथ उपयोग करना मुश्किल हो गया है।

एल्गोरिदम काफी सरल है। लिंक्ड सूची (पुरानी चुंबकीय टेप को सादृश्य द्वारा “टेप” कहा जाता है) पहले समान या लगभग एक ही आकार के दो टेप में बांटा गया है। यह “लेखन” तत्वों द्वारा दो टेपों के लिए वैकल्पिक रूप से किया जाता है।

फिर दो टेप विलय कर दिए जाते हैं, तत्व द्वारा तत्व, दो तत्वों वाले सॉर्ट किए गए ब्लॉक में। ब्लॉक दो अन्य टेपों के लिए वैकल्पिक रूप से लिखे गए हैं।

दो टेप तब विलय कर दिए जाते हैं, ब्लॉक द्वारा ब्लॉक, प्रत्येक चार तत्वों के सॉर्ट किए गए ब्लॉक में, और ब्लॉक को दो अन्य टेपों के लिए वैकल्पिक रूप से लिखा जाता है।

प्रक्रिया जारी रहती है, प्रत्येक बार ब्लॉक आकार को दोहरी कर देती है, जब तक सभी तत्व एक टेप पर एक ही क्रमबद्ध ब्लॉक में नहीं होते। फ़ंक्शन उस टेप के पहले तत्व को एक सूचक देता है।

प्रत्येक विलय को ओ (एन) तुलना की आवश्यकता होती है, जहां एन तत्वों की संख्या होती है। विलय की संख्या ओ (लॉग एन) है इसलिए पूरी तरह से ओ (एन लॉग एन) की तुलना करती है।

अगर लिंक की गई सूची को छाँटें () फ़ंक्शन रीएन्ट्रेंट है, तो तुलना फ़ंक्शन रीएन्ट्रंट है।

सी प्रशंसक पता करने में खुशी होगी कि इस एल्गोरिथ्म एडा या पास्कल में आसानी से कोडित नहीं किया जा सकता क्योंकि यह टाइपकास्ट पर निर्भर करता है।

लिंक की गई सूची को छाँटें () फ़ंक्शन को C++ प्रोग्राम से आसानी से कहा जा सकता है, जिसमें टाइपिंग के प्रकार की जांच हो सकती है अगर हेडर फाइल एलएलएम सॉर्ट.एच शामिल है। इसमें सॉर्ट लिंक की गई सूची () पर कॉल की इनलाइन पीढ़ी के लिए एक टेम्पलेट शामिल है कॉल का प्रारूप निम्नानुसार है:

#include “llmsort.h”

first_sorted = sort_list(first, compare, pointer, pcount);

yourclass *first;

yourclass *first_sorted;

void *pointer;

unsigned long *pcount;

फ़ंक्शन की तुलना () को निम्नानुसार कहा जाता है:

n = compare(p, q, pointer);

const yourclass *p;

const yourclass *q;

void *pointer;

int n;

यहाँ “आपकी कक्षा ” किसी भी वर्ग है जिसे आप परिभाषित कर सकते हैं कंपाइलर तर्क प्रकार की निरंतरता की जांच करेगा और सॉर्ट लिंक की गई सूची () पर उचित कॉल उत्पन्न करेगा।

पाठ प्रारूप में स्रोत कोड:·

llmsort.c

llmsort.h

Source: http://www.efgh.com/software/llmsort.htm