কোনও তালিকাতে পুনরাবৃত্তি কেন এটির মাধ্যমে সূচকের চেয়ে দ্রুত হবে?


125

পড়া এডিটি তালিকার জন্য জাভা ডকুমেন্টেশন এটা বলেছেন:

তালিকা ইন্টারফেসটি তালিকার উপাদানগুলিতে অবস্থানিক (সূচিকৃত) অ্যাক্সেসের জন্য চারটি পদ্ধতি সরবরাহ করে। তালিকাগুলি (জাভা অ্যারেগুলির মতো) শূন্য ভিত্তিক। নোট করুন যে এই ক্রিয়াকলাপগুলি কিছু বাস্তবায়নের জন্য সূচক মানের সাথে সমানুপাতিক সময়ে কার্যকর করতে পারে (উদাহরণস্বরূপ লিংকডলিস্ট শ্রেণি)। সুতরাং, একটি তালিকার উপাদানগুলির উপর পুনরাবৃত্তি সাধারণত যদি কলার বাস্তবায়ন না জেনে থাকে তবে এর মাধ্যমে সূচীকরণ করা ভাল।

আসলে এটার অর্থ কি? আমি যে সিদ্ধান্তে আঁকতে পেরেছি তা বুঝতে পারছি না।


12
এর অন্য একটি সাধারণ উদাহরণ যা আপনাকে এর সাধারণ বিষয়টি বুঝতে সাহায্য করতে পারে তা হ'ল জোল স্পলস্কির নিবন্ধ "ব্যাক টু বেসিকস" - "চিত্রকের অ্যালগরিদম শ্লেমিয়েল" অনুসন্ধান করুন।
একটি সিভিএন

উত্তর:


211

একটি লিঙ্কযুক্ত তালিকায়, প্রতিটি উপাদানটির পরবর্তী উপাদানগুলির একটি পয়েন্টার থাকে:

head -> item1 -> item2 -> item3 -> etc.

অ্যাক্সেস করতে item3 , আপনি পরিষ্কারভাবে দেখতে পাচ্ছেন যে আইটেম 3 এ পৌঁছানো পর্যন্ত আপনাকে প্রতিটি নোড দিয়ে মাথা থেকে হাঁটাচলা করতে হবে, যেহেতু আপনি সরাসরি লাফাতে পারবেন না।

সুতরাং, আমি যদি প্রতিটি উপাদানটির মান মুদ্রণ করতে চাই, আমি যদি এটি লিখি:

for(int i = 0; i < 4; i++) {
    System.out.println(list.get(i));
}

এটি কি হয়:

head -> print head
head -> item1 -> print item1
head -> item1 -> item2 -> print item2
head -> item1 -> item2 -> item3 print item3

এটি মারাত্মকভাবে অক্ষম কারণ আপনি যতবার এটি সূচনা করছেন প্রতিটি সময় তালিকার শুরু থেকে পুনরায় আরম্ভ হয় এবং প্রতিটি আইটেমের মধ্য দিয়ে যায়। এর অর্থ হল যে আপনার জটিলতা কার্যকরভাবে O(N^2)কেবলমাত্র তালিকাটিকে অতিক্রম করতে পারে!

পরিবর্তে যদি আমি এটি করেছি:

for(String s: list) {
    System.out.println(s);
}

তাহলে যা ঘটে তা হ'ল:

head -> print head -> item1 -> print item1 -> item2 -> print item2 etc.

সমস্ত একক traversal, যা হয় O(N)

এখন, অন্য বাস্তবায়নের Listযা যা হয় ArrayList, যে এক একটি সহজ অ্যারে দ্বারা সমর্থিত। সেক্ষেত্রে উপরের ট্র্যাভারসালগুলি উভয়ই সমতুল্য, যেহেতু একটি অ্যারেটি সংবিঘত তাই এটি এলোমেলোভাবে লাফিয়ে স্বেচ্ছাসেবী অবস্থানগুলিতে অনুমতি দেয়।


29
গৌণ বিজ্ঞপ্তি: সূচকের তালিকার শেষার্ধে থাকলে লিঙ্কডলিস্ট তালিকার শেষে থেকে অনুসন্ধান করবে, তবে এটি সত্যিকারের মৌলিক অদক্ষতাকে পরিবর্তন করে না। এটি এটিকে কিছুটা কম সমস্যাযুক্ত করে তোলে।
জোছিম সউর

8
এটি মারাত্মকভাবে অদক্ষ । বৃহত্তর লিংকডলিস্ট-আইয়ের জন্য, আরও ছোটর জন্য এটি দ্রুত কাজ করতে পারে REVERSE_THRESHOLD18 এ সেট করা হয়েছে java.util.Collections, মন্তব্য ছাড়াই এতটা আপোভোটেড উত্তরটি দেখতে অদ্ভুত।
বেসসেস

1
@ ড্যানিডিপ্লো, যদি কাঠামোটি সংযুক্ত থাকে তবে হ্যাঁ এটি সত্য। লিঙ্কডএস স্ট্রাকচার ব্যবহার করা তবে একটি ছোট রহস্য। তারা প্রায় সর্বদা অ্যারে ব্যাকডের চেয়ে বেশি খারাপ সঞ্চালন করে (অতিরিক্ত মেমরি পদচিহ্ন, জিসি-বন্ধুহীন এবং ভয়ঙ্কর লোকালয়)। সি # তে স্ট্যান্ডার্ড তালিকাটি অ্যারে ব্যাকড হয়।
বেসসেস

3
গৌণ বিজ্ঞপ্তি: আপনি যদি কোন পুনরাবৃত্তির ধরণটি ব্যবহার করতে হবে তা পরীক্ষা করতে চান (ইন্ডেক্সড বনাম আইট্রেটার / ফোর্যাচ), আপনি সর্বদা পরীক্ষা করতে পারেন যদি কোনও তালিকা র্যান্ডমএ্যাক্সেস (একটি মার্কার ইন্টারফেস) প্রয়োগ করে :List l = unknownList(); if (l instanceof RandomAccess) /* do indexed loop */ else /* use iterator/foreach */
আফকিমিন

1
@ KK_07k11A0585: প্রকৃতপক্ষে আপনার প্রথম উদাহরণে লুপের জন্য বর্ধিত দ্বিতীয়টি উদাহরণের মতো পুনরাবৃত্তিতে সংকলিত হয়েছে, সুতরাং সেগুলি সমতুল্য।
টিউডর

35

উত্তরটি এখানে বর্ণিত হয়েছে:

নোট করুন যে এই ক্রিয়াকলাপগুলি কিছু বাস্তবায়নের জন্য সূচক মানের সাথে সমানুপাতিক সময়ে কার্যকর করতে পারে (উদাহরণস্বরূপ লিংকডলিস্ট শ্রেণি)

লিঙ্কযুক্ত তালিকার অন্তর্নিহিত সূচক নেই; কলিংয়ের .get(x)জন্য প্রথম এন্ট্রি সন্ধানের জন্য তালিকার প্রয়োগের প্রয়োজন হবে এবং .next()x-1 বার কল করুন (একটি ও (এন) বা লিনিয়ার সময় অ্যাক্সেসের জন্য), যেখানে অ্যারে-ব্যাকড লিস্টটি কেবলমাত্র সূচীতে প্রবেশ করতে পারেbackingarray[x] ও (1) এ বা ধ্রুবক সময়ে।

আপনি যদি জাভাডকেরLinkedList দিকে তাকান , আপনি মন্তব্যটি দেখতে পাবেন

দ্বিগুণ-লিঙ্কযুক্ত তালিকার প্রত্যাশার মতো অপারেশনগুলি সমস্তই সম্পাদন করে। তালিকাতে সূচকগুলি অপারেশনগুলি সূচনাকালীন সূচনার নিকটবর্তী বা সূচকগুলির কাছাকাছি থেকে শুরু থেকে শেষের দিকে তালিকাকে অতিক্রম করবে।

যদিও জাভাডকেরArrayList সাথে সংশ্লিষ্ট রয়েছে

তালিকা ইন্টারফেসের পুনরায় আকারযুক্ত-অ্যারে বাস্তবায়ন। সমস্ত alচ্ছিক তালিকার ক্রিয়াকলাপ কার্যকর করে এবং নাল সহ সমস্ত উপাদানকে অনুমতি দেয়। তালিকার ইন্টারফেস বাস্তবায়নের পাশাপাশি, এই শ্রেণিটি তালিকা সংরক্ষণের জন্য অভ্যন্তরীণভাবে ব্যবহৃত হয় এমন অ্যারের আকার ম্যানিপুলেট করার জন্য পদ্ধতি সরবরাহ করে। (এই শ্রেণিটি আনইনক্রোনাইজড বাদে মোটামুটি ভেক্টরের সমতুল্য))

size, isEmpty, get, set, iterator, এবং listIteratorঅপারেশন ধ্রুব সময় চালানো। অ্যাড অপারেশনটি amorised ধ্রুবক সময়ে চলে, অর্থাত্ n উপাদান যুক্ত করার জন্য ও (এন) সময় প্রয়োজন। অন্যান্য সমস্ত ক্রিয়াকলাপ রৈখিক সময়ে চলমান (মোটামুটি কথা বলার জন্য)। LinkedListবাস্তবায়নের জন্য তুলনায় ধ্রুবক ফ্যাক্টর কম ।

"জাভা সংগ্রহ ফ্রেমওয়ার্কের জন্য বিগ-ও সংক্ষিপ্তসার" শীর্ষক একটি সম্পর্কিত প্রশ্নের উত্তর রয়েছে এই সংস্থানটির দিকে ইঙ্গিত করে, "জাভা সংগ্রহগুলি জেডিকে 6" যা আপনাকে সহায়ক মনে হতে পারে।


7

যদিও গৃহীত উত্তরটি অবশ্যই সঠিক, তবে আমি কি কোনও ছোট্ট ত্রুটি চিহ্নিত করতে পারি। টিউডারের উদ্ধৃতি:

এখন, তালিকার অন্য প্রয়োগে যা অ্যারেলিস্ট, সেটিকে সাধারণ অ্যারে দ্বারা সমর্থন করা হয়। সেক্ষেত্রে উপরের ট্র্যাভারসালগুলি উভয়ই সমতুল্য , যেহেতু একটি অ্যারেটি সংবিঘত তাই এটি এলোমেলোভাবে লাফিয়ে স্বেচ্ছাসেবী অবস্থানগুলিতে অনুমতি দেয়।

এটি সম্পূর্ণরূপে সত্য নয়। সত্য হচ্ছে এটা

একটি অ্যারেলিস্ট সহ, একটি হাতে লিখিত গণনা লুপ প্রায় 3x দ্রুত

উত্স: পারফরম্যান্সের জন্য ডিজাইনিং, গুগলের অ্যান্ড্রয়েড ডক

মনে রাখবেন যে হাতের লিখিত লুপটি সূচকযুক্ত পুনরাবৃত্তিকে বোঝায়। আমি সন্দেহ করি কারণ এটির পুনরুক্তিগুলির জন্য যা লুপগুলির জন্য বর্ধিত সঙ্গে ব্যবহৃত হয় of এটি কাঠামোয় একটি সামান্য পারফরম্যান্স তৈরি করে যা কাঠামোগত অ্যারে সমর্থন করে। আমি ভেক্টর শ্রেণীর ক্ষেত্রে এটি সত্য হতে পারে সন্দেহও করি।

আমার নিয়মটি হল, যখনই সম্ভব লুপের জন্য বর্ধিত ব্যবহার করুন এবং আপনি যদি সত্যই পারফরম্যান্সের বিষয়ে যত্নশীল হন তবে কেবল অ্যারেলিস্ট বা ভেক্টর উভয়ের জন্যই সূচীকৃত পুনরাবৃত্তিটি ব্যবহার করুন। বেশিরভাগ ক্ষেত্রে, আপনি এটিকে উপেক্ষাও করতে পারেন- সংকলক পটভূমিতে এটি অনুকূল করতে পারে।

আমি কেবল উল্লেখ করতে চাই যে অ্যান্ড্রয়েডে উন্নয়নের প্রসঙ্গে, অ্যারেলিস্টগুলির উভয় ট্র্যাভারসালগুলি সমতুল্য নয় । চিন্তার জন্য শুধু খাবার।


আপনার উত্সটি কেবল অ্যানড্রয়েড। এটি কি অন্যান্য জেভিএমগুলির জন্যও ধারণ করে?
ম্যাটসেম্যান

পুরোপুরি নিশ্চিত না tbh, তবে আবার, লুপগুলির জন্য বর্ধিত ব্যবহারগুলি বেশিরভাগ ক্ষেত্রে ডিফল্ট হওয়া উচিত।
ধ্রুব গায়রোলা

এটি আমার কাছে বোধগম্য হয়, অ্যারে ব্যবহার করে এমন একটি ডেটা স্ট্রাকচার অ্যাক্সেস করার সময় সমস্ত পুনরাবৃত্তির যুক্তি থেকে মুক্তি পেয়ে দ্রুত কাজ করে। আমি জানি না 3x দ্রুত, তবে অবশ্যই দ্রুত।
সেটজার 22

7

লুকআপের জন্য অফসেটের সাথে তালিকার উপরে বিশিষ্ট হওয়া চিত্রকের অ্যালগরিদম শ্লেমিয়েলেরi সাথে সাদৃশ্য

শ্লিমিল রাস্তার চিত্রশিল্পী হিসাবে চাকরি পেয়েছে, রাস্তার মাঝখানে বিন্দুযুক্ত রেখাগুলি আঁকছে। প্রথম দিন তিনি রাস্তায় রঙিন ক্যানটি নিয়ে 300০০ গজ রাস্তাটি শেষ করেন। "বেশ ভালো!" তাঁর বস বলেছেন, "আপনি একজন দ্রুত কর্মী!" এবং তাকে একটি কোপেক দেয়।

পরের দিন শ্লিমিল কেবল 150 গজ সম্পন্ন করে। "আচ্ছা, এটি গতকালের মতো প্রায় ভাল নয়, তবে আপনি এখনও একজন দ্রুত কর্মী 150 150 গজ সম্মানজনক," এবং তাকে কোপেক প্রদান করে।

পরের দিন শ্লিমিল রাস্তার 30 গজ রঙে। "কেবল 30!" তার মনিব চিৎকার। "এটি অগ্রহণযোগ্য! প্রথম দিন আপনি দশবার এত বেশি কাজ করেছিলেন! কী হচ্ছে?"

"আমি এটিকে সাহায্য করতে পারি না," শ্লেমিল বলে। "প্রতিদিন আমি পেইন্টের হাত থেকে আরও দূরে এবং দূরে যেতে পারি!"

উত্স

এই ছোট্ট গল্পটি অভ্যন্তরীণভাবে কী চলছে এবং এটি এতটা অক্ষম কেন তা বুঝতে সহজ করে তুলতে পারে।


4

এর i-th উপাদানটি সন্ধান করতে LinkedListবাস্তবায়নের সমস্ত উপাদান আই-তম পর্যন্ত যায়।

সুতরাং

for(int i = 0; i < list.length ; i++ ) {
    Object something = list.get(i); //Slow for LinkedList
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.