আমি আগ্রহী যদি ও (এন লগ এন) লিঙ্কযুক্ত লিস্টটি করতে পারে তবে তা করতে পারে।
আমি আগ্রহী যদি ও (এন লগ এন) লিঙ্কযুক্ত লিস্টটি করতে পারে তবে তা করতে পারে।
উত্তর:
আপনি চলমান সময়ে ও (এন লগ এন) এর চেয়ে ভাল আর কিছু করতে পারবেন না এমন প্রত্যাশা করা যুক্তিসঙ্গত ।
যাইহোক, আকর্ষণীয় অংশটি হ'ল আপনি এটিকে স্থানে বাছাই করতে পারেন কিনা তা তদন্ত করা , স্টেবল , এর সবচেয়ে খারাপ পরিস্থিতি এবং এগুলি ।
পুট্টি খ্যাতির সাইমন তাতাম ব্যাখ্যা করেছেন যে কীভাবে সংযুক্তিযুক্ত তালিকার সাথে কোনও লিঙ্কযুক্ত তালিকাটি বাছাই করা যায় । তিনি নিম্নলিখিত মন্তব্যে সমাপ্ত:
যে কোনও স্ব-সম্মানজনক সাজানোর অ্যালগরিদমের মতো, এতে চলমান সময় হে (এন লগ এন) রয়েছে। কারণ এটি মার্জেসোর্ট, সবচেয়ে খারাপ চলমান সময় এখনও ও (এন লগ এন); কোনও প্যাথলজিকাল কেস নেই।
সহায়ক স্টোরেজ প্রয়োজনীয়তা ছোট এবং ধ্রুবক (যেমন বাছাই রুটিনের মধ্যে কয়েকটি ভেরিয়েবল)। অ্যারে থেকে লিঙ্কযুক্ত তালিকার অন্তর্নিহিত পৃথক আচরণের জন্য ধন্যবাদ, এই Mergesort বাস্তবায়ন সাধারণত অ্যালগরিদমের সাথে যুক্ত ও (এন) সহায়ক স্টোরেজ ব্যয়কে এড়িয়ে চলে।
সিতে একটি উদাহরণ বাস্তবায়নও রয়েছে যা একক এবং দ্বিগুণ লিঙ্কযুক্ত তালিকার জন্য কাজ করে।
যেমন @ জর্জেন ফোগ নীচে উল্লেখ করেছেন, বিগ-ও স্বরলিপি কিছু ধ্রুবক কারণগুলি লুকিয়ে থাকতে পারে যা একটি অ্যালগরিদমকে স্মৃতিশক্তির কারণে কম সংখ্যক আইটেম ইত্যাদির কারণে আরও ভাল সম্পাদন করতে পারে etc.
listsort
, আপনি প্যারামিটার ব্যবহার করে সুইচ করতে পারেন দেখতে পাবেন int is_double
।
listsort
কেবলমাত্র একা-সংযুক্ত তালিকাগুলি সমর্থন করে
বেশ কয়েকটি কারণের উপর নির্ভর করে তালিকাটি কোনও অ্যারেতে অনুলিপি করা এবং তারপরে একটি কুইকোর্ট ব্যবহার করা আসলে দ্রুততর হতে পারে ।
এটি দ্রুত হওয়ার কারণটি হ'ল লিঙ্কযুক্ত তালিকার চেয়ে অ্যারেতে আরও ভাল ক্যাশে পারফরম্যান্স রয়েছে। তালিকার নোডগুলি মেমরিতে বিচ্ছুরিত হলে আপনি পুরো জায়গা জুড়ে ক্যাশে মিস করতে পারেন। তারপরে আবার অ্যারে বড় হলে আপনি যেভাবেই ক্যাশে মিস করবেন।
মার্জর্ট সমান্তরালগুলি আরও ভাল, সুতরাং যদি এটি আপনি চান তবে এটি আরও ভাল পছন্দ হতে পারে। আপনি যদি সরাসরি লিঙ্কযুক্ত তালিকায় এটি সম্পাদন করেন তবে এটি আরও দ্রুত।
যেহেতু উভয় অ্যালগরিদমগুলি ও (এন * লগ এন) এ চালিত হয়, তাই একটি জ্ঞাত সিদ্ধান্ত নেওয়া উভয়কেই মেশিনে চালনা করতে চাইলে তাদের প্রোফাইল করা জড়িত।
--- সম্পাদনা
আমি আমার অনুমানটি পরীক্ষা করার সিদ্ধান্ত নিয়েছিলাম এবং সি-প্রোগ্রাম লিখেছিলাম যা ইনটগুলির clock()
একটি লিঙ্কযুক্ত তালিকা বাছাই করার জন্য নেওয়া সময় (ব্যবহার করে ) পরিমাপ করে । আমি একটি লিঙ্কযুক্ত তালিকার সাথে চেষ্টা করেছি যেখানে প্রতিটি নোড বরাদ্দ করা হয়েছিলmalloc()
এবং একটি লিঙ্কযুক্ত তালিকার সাথে যেখানে একটি অ্যারেতে নোডগুলি রৈখিকভাবে বিছানো হয়েছিল, তাই ক্যাশের কার্যকারিতা আরও ভাল হবে। আমি এগুলি বিল্ট-ইন কিউসোর্টের সাথে তুলনা করেছি, যার মধ্যে একটি খণ্ডিত তালিকা থেকে একটি অ্যারেতে সমস্ত কিছু অনুলিপি করা এবং ফলাফলটি আবার কপি করা অন্তর্ভুক্ত। প্রতিটি অ্যালগরিদম একই 10 ডেটা সেটে চালিত হয়েছিল এবং ফলাফলগুলি গড় হয়েছিল।
এগুলি ফলাফল:
এন = 1000:
মার্জ সাজানোর সাথে খণ্ডিত তালিকা: 0.000000 সেকেন্ড
কিউসোর্ট সহ অ্যারে: 0.000000 সেকেন্ড
মার্জ সাজানোর সাথে প্যাক করা তালিকা: 0.000000 সেকেন্ড
এন = 100000:
মার্জ সাজানোর সাথে খণ্ডিত তালিকা: 0.039000 সেকেন্ড
কিউসোর্ট সহ অ্যারে: 0.025000 সেকেন্ড
মার্জ সাজানোর সাথে প্যাক করা তালিকা: 0.009000 সেকেন্ড
এন = 1000000:
মার্জ সাজানোর সাথে খণ্ডিত তালিকা: 1.162000 সেকেন্ড
কিউসোর্ট সহ অ্যারে: 0.420000 সেকেন্ড
মার্জ সাজানোর সাথে প্যাক তালিকা: 0.112000 সেকেন্ড
এন = 100000000:
মার্জ সাজানোর সাথে ফ্রেগমেন্টযুক্ত তালিকা: 364.797000 সেকেন্ড
কিউসোর্ট সহ অ্যারে: 61.166000 সেকেন্ড
মার্জ সাজানোর সাথে প্যাক তালিকা: 16.525000 সেকেন্ড
উপসংহার:
কমপক্ষে আমার মেশিনে, ক্যাশে পারফরম্যান্সের উন্নতি করার জন্য একটি অ্যারে অনুলিপি করা ভাল since এটি লক্ষ্য করা উচিত যে আমার মেশিনটিতে একটি 2.8GHz ফেনম II রয়েছে তবে কেবল 0.6GHz র্যাম, তাই ক্যাশেটি খুব গুরুত্বপূর্ণ important
এটি এই বিষয় একটি দুর্দান্ত ছোট কাগজ। তাঁর অভিজ্ঞতামূলক উপসংহারটি হল ট্রাইসোর্ট সেরা, তার পরে কুইকোর্ট এবং মার্জেসোর্ট। পলি বাছাই, বুদ্বুদ সাজান, নির্বাচন বাছাই খুব খারাপভাবে সঞ্চালন।
চিং-কুয়াং শেনির লিঙ্কযুক্ত তালিকা অনুসারে বাছাইয়ের একটি সমন্বিত অধ্যয়ন
http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.31.9981
তুলনার ধরণ (যেমন উপাদানগুলির তুলনার উপর ভিত্তি করে) সম্ভবত এর চেয়ে দ্রুততর হতে পারে না n log n
। অন্তর্নিহিত ডেটা স্ট্রাকচার কী তা বিবেচ্য নয়। উইকিপিডিয়া দেখুন ।
তালিকায় প্রচুর পরিমাণে অভিন্ন উপাদান (যেমন গণনা বাছাই করা), বা তালিকার উপাদানগুলির কিছু প্রত্যাশিত বিতরণ থাকার সুবিধা গ্রহণ করা অন্যান্য ধরণের ক্রম দ্রুততর হয়, যদিও আমি বিশেষত ভালভাবে কাজ করে এমন কোনওটির কথা ভাবতে পারি না though একটি লিঙ্কযুক্ত তালিকায়।
যেমনটি বহুবার বলা হয়েছে, সাধারণ তথ্যের জন্য তুলনা ভিত্তিক বাছাইয়ের উপর নিম্ন সীমাটি O (n লগ এন) হতে চলেছে। সংক্ষেপে এই যুক্তি পুনরায় সংক্ষেপে, সেখানে এন আছে! একটি তালিকা বাছাই করা যায় বিভিন্ন উপায়ে। যে কোনও ধরণের তুলনা গাছের এন আছে! (যা হে (এন ^ n) এ রয়েছে) সম্ভাব্য চূড়ান্ত প্রকারের উচ্চতা হিসাবে কমপক্ষে লগ (এন!) প্রয়োজন হবে: এটি আপনাকে একটি হে (লগ (এন ^ n)) নীচে আবদ্ধ করবে যা হে (এন) লগ এন)।
সুতরাং, একটি লিঙ্কযুক্ত তালিকার সাধারণ ডেটার জন্য, সেরা সম্ভাব্য বাছাই করা যে কোনও ডাটা যা দুটি বস্তুর তুলনা করতে পারে তার উপর কাজ করবে ও (এন লগ এন) হতে চলেছে। তবে, যদি কাজ করার জন্য আপনার কাছে আরও সীমিত ডোমেন থাকে তবে আপনি যে সময়টি গ্রহণ করেন তা উন্নত করতে পারেন (কমপক্ষে n এর সাথে আনুপাতিক)। উদাহরণস্বরূপ, আপনি যদি পূর্ণসংখ্যার সাথে কোনও মানের চেয়ে বড় না হয়ে কাজ করে থাকেন তবে আপনি গণনা বাছাই বা রেডিক্স বাছাই করতে পারেন , কারণ এগুলি এন এর অনুপাতের সাথে জটিলতা হ্রাস করার জন্য নির্দিষ্ট বিষয়গুলি ব্যবহার করে। সতর্কতা অবলম্বন করুন, এগুলি জটিলতার সাথে আরও কিছু বিষয় যুক্ত করে যা আপনি বিবেচনা করবেন না (উদাহরণস্বরূপ, গণনা অনুসারে বাছাই করা এবং রেডিক্স উভয়ই এমন কারণগুলিকে যুক্ত করে যা আপনি যে সংখ্যাটি বাছাই করছেন তার আকারের উপর ভিত্তি করে, হে (এন + কে ) যেখানে k গণনা বাছাইয়ের জন্য বৃহত্তম সংখ্যার আকার, উদাহরণস্বরূপ)।
এছাড়াও, যদি আপনার কাছে একটি নিখুঁত হ্যাশযুক্ত বস্তু থাকতে পারে (বা কমপক্ষে একটি হ্যাশ যা সমস্ত মানকে আলাদাভাবে মানচিত্র করে) তবে আপনি তাদের হ্যাশ ফাংশনগুলিতে একটি গণনা বা রেডিক্স সাজানোর চেষ্টা করতে পারেন।
একটি Radix বাছাই বিশেষত একটি লিঙ্কযুক্ত তালিকার জন্য উপযুক্ত, যেহেতু একটি অঙ্কের প্রতিটি সম্ভাব্য মানের সাথে মিল রেখে প্রধান পয়েন্টারগুলির একটি টেবিল তৈরি করা সহজ।
মার্জ সাজানোর জন্য O (1) অ্যাক্সেসের প্রয়োজন হয় না এবং এটি O (n ln n)। সাধারণ ডেটা বাছাইয়ের জন্য কোনও অ্যালগরিদম ও (N ln n) এর চেয়ে ভাল নয়।
বিশেষ তথ্য অ্যালগরিদম যেমন র্যাডিক্স সাজ্ট (ডেটার আকার সীমাবদ্ধ করা) বা হিস্টোগ্রাম সাজানোর (পৃথক ডেটা গণনা করা) কোনও সংযুক্ত তালিকে কম বৃদ্ধি ফাংশন সহ বাছাই করতে পারে যতক্ষণ না আপনি অ (অ) অস্থায়ী স্টোরেজ হিসাবে অ্যাক্সেসের সাথে আলাদা কাঠামো ব্যবহার করেন as ।
আর একটি বিশেষ শ্রেণীর ডেটা হ'ল প্রায় উপাদান অনুসারে সাজানো তালিকার তুলনা বাছাই। এটি (না) অপারেশনে বাছাই করা যেতে পারে।
অ্যারে এবং পিছনে তালিকাটি অনুলিপি করা হবে ও (এন), সুতরাং কোনও স্থান বাছাই করা অ্যালগরিদম ব্যবহার করা যেতে পারে যদি স্থান কোনও সমস্যা না হয়।
উদাহরণস্বরূপ, যুক্ত লিঙ্কযুক্ত তালিকা দেওয়া uint_8
, এই কোডটি হিস্টোগ্রাম বাছাই করে ও (এন) সময়ে এটি সাজান:
#include <stdio.h>
#include <stdint.h>
#include <malloc.h>
typedef struct _list list_t;
struct _list {
uint8_t value;
list_t *next;
};
list_t* sort_list ( list_t* list )
{
list_t* heads[257] = {0};
list_t* tails[257] = {0};
// O(N) loop
for ( list_t* it = list; it != 0; it = it -> next ) {
list_t* next = it -> next;
if ( heads[ it -> value ] == 0 ) {
heads[ it -> value ] = it;
} else {
tails[ it -> value ] -> next = it;
}
tails[ it -> value ] = it;
}
list_t* result = 0;
// constant time loop
for ( size_t i = 255; i-- > 0; ) {
if ( tails[i] ) {
tails[i] -> next = result;
result = heads[i];
}
}
return result;
}
list_t* make_list ( char* string )
{
list_t head;
for ( list_t* it = &head; *string; it = it -> next, ++string ) {
it -> next = malloc ( sizeof ( list_t ) );
it -> next -> value = ( uint8_t ) * string;
it -> next -> next = 0;
}
return head.next;
}
void free_list ( list_t* list )
{
for ( list_t* it = list; it != 0; ) {
list_t* next = it -> next;
free ( it );
it = next;
}
}
void print_list ( list_t* list )
{
printf ( "[ " );
if ( list ) {
printf ( "%c", list -> value );
for ( list_t* it = list -> next; it != 0; it = it -> next )
printf ( ", %c", it -> value );
}
printf ( " ]\n" );
}
int main ( int nargs, char** args )
{
list_t* list = make_list ( nargs > 1 ? args[1] : "wibble" );
print_list ( list );
list_t* sorted = sort_list ( list );
print_list ( sorted );
free_list ( list );
}
O(n lg n)
তুলনায়-ভিত্তিক (উদাঃ, রেডিক্স সাজান) এর চেয়ে দ্রুততর কোনও ধরণের অ্যালগোরিদম । সংজ্ঞা অনুসারে, তুলনা বাছাই এমন কোনও ডোমেনের ক্ষেত্রে প্রযোজ্য যাতে মোট অর্ডার রয়েছে (যেমন, তুলনা করা যায়)।
আপনার প্রশ্নের সরাসরি উত্তর নয়, তবে আপনি যদি এড়িয়ে যান তালিকাটি ব্যবহার করেন তবে এটি ইতিমধ্যে বাছাই করা হয়েছে এবং ও (লগ এন) অনুসন্ধানের সময় রয়েছে।
O(lg N)
অনুসন্ধানের সময় - তবে গ্যারান্টিযুক্ত নয়, কারণ স্কিপ তালিকাগুলি এলোমেলোভাবে নির্ভর করে। আপনি যদি অবিশ্বস্ত ইনপুট পেয়ে থাকেন তবে নিশ্চিত হয়ে নিন যে ইনপুট সরবরাহকারী আপনার আরএনজি সম্পর্কে ভবিষ্যদ্বাণী করতে পারে না, বা তারা আপনাকে এমন ডেটা প্রেরণ করতে পারে যা তার সবচেয়ে খারাপ ক্ষেত্রে পারফরম্যান্সকে ট্রিগার করে
যেমনটি আমি জানি, সেরা বাছাই করা অ্যালগরিদম হ'ল (এন * লগ এন), যে পাত্রে যাই হোক না কেন - এটি প্রমাণিত হয়েছে যে শব্দের বিস্তৃত অর্থে বাছাই করা (একীকরণ / কুইকসোর্ট ইত্যাদি স্টাইল) কম যেতে পারে না। একটি লিঙ্কযুক্ত তালিকা ব্যবহার করা আপনাকে আরও ভাল সময় দেওয়ার সুযোগ দেয় না।
ও (এন) এ যে একমাত্র অ্যালগরিদম চলে তা হ'ল "হ্যাক" অ্যালগরিদম যা বাছাইয়ের পরিবর্তে গণনা মানগুলিতে নির্ভর করে।
O(n lg c)
। যদি আপনার সমস্ত উপাদানগুলি অনন্য c >= n
হয়, এবং তাই এটি এর চেয়ে বেশি সময় নেয় O(n lg n)
।
এখানে এমন একটি বাস্তবায়ন রয়েছে যা তালিকায় একবারে ট্র্যাভার করে, রান সংগ্রহ করে, তারপরে মার্জগুলিকে একইভাবে মার্জগুলির সময়সূচি দেয়।
জটিলতা হ'ল হে (এন লগ এম) যেখানে এন হল আইটেমের সংখ্যা এবং এম রানের সংখ্যা। সর্বোত্তম কেস হ'ল ও (এন) (যদি ডেটা ইতিমধ্যে সাজানো থাকে) এবং সবচেয়ে খারাপ ক্ষেত্রে O (n লগ এন) প্রত্যাশার মতো।
এটি ও (লগ এম) অস্থায়ী মেমরির প্রয়োজন; বাছাই তালিকাগুলি জায়গায় জায়গায় করা হয়।
(নীচে আপডেট হয়েছে com মন্তব্যকারী একটি ভাল পয়েন্ট তোলে যে আমার এটি এখানে বর্ণনা করা উচিত)
অ্যালগরিদমের सारটি হ'ল:
while list not empty
accumulate a run from the start of the list
merge the run with a stack of merges that simulate mergesort's recursion
merge all remaining items on the stack
রান সংগ্রহ করতে খুব বেশি ব্যাখ্যা প্রয়োজন হয় না, তবে আরোহী রান এবং উতরাই রান (বিপরীত) উভয়ই সংগ্রহ করার সুযোগটি নেওয়া ভাল। এখানে এটি রানের মাথার চেয়ে ছোট আইটেমগুলিকে সংযোজন করে এবং রানের শেষের চেয়ে বড় বা সমান আইটেম সংযোজন করে। (নোট করুন যে প্রিপেন্ডিংয়ের ক্ষেত্রে বাছাইয়ের স্থায়িত্ব সংরক্ষণের চেয়ে কম কঠোর ব্যবহার করা উচিত))
এখানে মার্জিং কোডটি আটকানো সবচেয়ে সহজ:
int i = 0;
for ( ; i < stack.size(); ++i) {
if (!stack[i])
break;
run = merge(run, stack[i], comp);
stack[i] = nullptr;
}
if (i < stack.size()) {
stack[i] = run;
} else {
stack.push_back(run);
}
তালিকাটি সাজানোর বিবেচনা করুন (দাগিবেফজহ) (রান উপেক্ষা করে)। স্ট্যাকের রাজ্যগুলি নিম্নরূপে অগ্রসর হয়:
[ ]
[ (d) ]
[ () (a d) ]
[ (g), (a d) ]
[ () () (a d g i) ]
[ (b) () (a d g i) ]
[ () (b e) (a d g i) ]
[ (c) (b e) (a d g i ) ]
[ () () () (a b c d e f g i) ]
[ (j) () () (a b c d e f g i) ]
[ () (h j) () (a b c d e f g i) ]
তারপরে, অবশেষে, এই সমস্ত তালিকাটি মার্জ করুন।
নোট করুন যে স্ট্যাকের আইটেমগুলির (রান) সংখ্যা হয় শূন্য বা 2 ^ i এবং স্ট্যাকের আকার 1 + লগ 2 (নরুনস) দ্বারা সীমাবদ্ধ। প্রতিটি উপাদান স্ট্যাক স্তর প্রতি একবার মার্জ করা হয়, সুতরাং ও (এন লগ এম) তুলনা। টিমসোর্টের সাথে এখানে একটি উত্তীর্ণের মিল রয়েছে, যদিও টিমসোর্ট ফিবোনাচি ক্রমের মতো কিছু ব্যবহার করে এটি স্ট্যাক বজায় রাখে যেখানে এটি দুটিয়ের শক্তি ব্যবহার করে।
সঞ্চয়ের রানগুলি যে কোনও ইতিমধ্যে সাজানো ডেটার সুবিধা গ্রহণ করে যাতে ইতিমধ্যে সাজানো তালিকার (এক রান) সেরা কেস জটিলতা হ'ল (এন) হয়) যেহেতু আমরা আরোহী এবং উতরাই রান উভয়ই সংগ্রহ করছি, রান সর্বদা সর্বনিম্ন দৈর্ঘ্য 2 হবে ((এটি সর্বনিম্ন এক দ্বারা স্ট্যাকের গভীরতা হ্রাস করে, প্রথম স্থানে রান সন্ধানের ব্যয়টি প্রদান করে)) সবচেয়ে খারাপ ক্ষেত্রে জটিলতা হ'ল O (n লগ এন), প্রত্যাশার মতো ডেটা যা অত্যন্ত র্যান্ডমাইজড।
(উম ... দ্বিতীয় আপডেট।)
অথবা কেবল নীচের অংশে একত্রীকরণের উইকিপিডিয়া দেখুন ।
O(log m)
অতিরিক্ত মেমরির প্রয়োজন হবে না - একটি খালি না হওয়া পর্যন্ত কেবল দুটি তালিকায় রান যোগ করুন।
আপনি এটি একটি অ্যারে অনুলিপি এবং তারপর এটি বাছাই করতে পারেন।
অ্যারে অনুলিপি করা (এন),
বাছাই O (nlgn) (আপনি যদি মার্জ সাজানোর মতো দ্রুত অ্যালগরিদম ব্যবহার করেন),
লিঙ্কযুক্ত তালিকায় আবার অনুলিপি করা প্রয়োজন (এন) যদি প্রয়োজন হয়,
সুতরাং এটি O (nlgn) হতে চলেছে।
মনে রাখবেন যে আপনি যদি লিঙ্কযুক্ত তালিকার উপাদানগুলির সংখ্যা না জানেন তবে আপনি অ্যারের আকার জানেন না। আপনি জাভাতে কোডিং দিচ্ছেন উদাহরণস্বরূপ আপনি একটি অ্যারেলিস্ট ব্যবহার করতে পারেন।
প্রশ্নটি লেটকোড # 148 , এবং সমস্ত বড় ভাষায় প্রচুর সমাধান দেওয়া হয়। খনিটি নিম্নরূপ, তবে আমি সময় জটিলতার বিষয়ে ভাবছি। মধ্যম উপাদানটি সন্ধান করার জন্য, আমরা প্রতিবার সম্পূর্ণ তালিকাটি অতিক্রম করি। প্রথমবারের n
উপাদানগুলি পুনরাবৃত্তি হয়, দ্বিতীয়বারের 2 * n/2
উপাদানগুলি পুনরাবৃত্তি হয়, এবং আরও অনেক কিছু। মনে হয় O(n^2)
সময় হয়েছে।
def sort(linked_list: LinkedList[int]) -> LinkedList[int]:
# Return n // 2 element
def middle(head: LinkedList[int]) -> LinkedList[int]:
if not head or not head.next:
return head
slow = head
fast = head.next
while fast and fast.next:
slow = slow.next
fast = fast.next.next
return slow
def merge(head1: LinkedList[int], head2: LinkedList[int]) -> LinkedList[int]:
p1 = head1
p2 = head2
prev = head = None
while p1 and p2:
smaller = p1 if p1.val < p2.val else p2
if not head:
head = smaller
if prev:
prev.next = smaller
prev = smaller
if smaller == p1:
p1 = p1.next
else:
p2 = p2.next
if prev:
prev.next = p1 or p2
else:
head = p1 or p2
return head
def merge_sort(head: LinkedList[int]) -> LinkedList[int]:
if head and head.next:
mid = middle(head)
mid_next = mid.next
# Makes it easier to stop
mid.next = None
return merge(merge_sort(head), merge_sort(mid_next))
else:
return head
return merge_sort(linked_list)