السلام عليكم ورحمة الله وبركاته :
هل من الممكن شرح هذا الكود لي ومالذي تضيفه كلمة proc عند وضعها في ال return ومالذي تستدعيه .
وعليكم السلام , بوضع الداله في الريتيرن تقوم الداله باستدعاء نفسها ويعاد تنفيذها في تكرارات داخل بعضها البعض حسب الرقم n اذا اردت مشاهدة التنفيذ ادخل علي الرابط التالي و اكتب الكود و شاهد تنفيذه خطوة بخطوة , يفضل اختيار رقم صغير لل n للتجربة
http://www.pythontutor.com/live.html#mode=edit
شكرا للتوضيح
جزاك الله خيرا
جزانا و اياك
وعليكم السلام
الأمر سهل صديقي محيي الدين… الدالة التي لديك تسمى recursive function
أي أن الـ loops لديها طريقتين اما iterative أو recursive
-
ماهو recursive ؟
يعني أن الدالة تستدعي نفسها أكثر من مرة, لحساب شيء معين, هذا مثال سهل:
def sum(n):
return n + sum(n-1)
لو أدخلت الرقم 5 باستدعاء sum(5)
ستقوم الدالة بحساب:
5 + 4
5 + 4 + 3
5 + 4 + 3 + 2
5 + 4 + 3 + 2 + 1
5 + 4 + 3 + 2 + 1 + 0 = 15
سنحصل على 15… لكن يوجد مشكلة في الدالة بالأعلى أنها ستسمر للأبد (endless loop) أي أنها ستتابع:
5 + 4 + 3 + 2 + 1 + 0
5 + 4 + 3 + 2 + 1 + 0 + (-1)
5 + 4 + 3 + 2 + 1 + 0 + (-1) + (-2)
...
يجب أن نضيف ما يسمى بالشرط الأولى base condition, أي أنه حينما يصل للصفر يخرج بهذا الشكل:
def sum(n):
if n == 0:
return 0;
return n + sum(n-1)
أعتقد أنك تستطيع تحليل الدالة التي سألت حولها بما أنك تعرف كيفية كتابة recursive loop
-
بقي شيء, ماهي iterative loop ؟
هي استعمال الطريقة العادية for أو while لعمل loop بهذا, هذه نفس الدالة بالأعلى:
def sum(n):
result = 0
while n > 0:
result += n
n -= 1
return result
شكراً جزيلاً لك أخي ياسر للتوضيح الممتاز
ولكن في الحياة العملية ماذا يمكن الاستفادة من recursive function
ولك الشكر
تسهل لنا recursive function كتابة الدوال بطريقة التفكير
فمثلاً لو قلت في مجال بنيات البيانات Data Structures, لدينا شيء اسمه binary tree وهي تسهل علينا ترتيب العناصر وادخالها
نفترض أننا نريد المرور على كل العناصر بالترتيب بهذا الشكل:
تكتب الخوارزمية بهذا الشكل:
def printInorder(root):
if not root:
return
printInorder(root.left)
print(root.val)
printInorder(root.right)
لاحظ أنها تستدعي نفسها للدخول لليسار printInorder(root.left)
وستتابع الدخول ليسار الأب root حتى لا يكون معه أي طفل child, ويتحقق الـ base condition الذي بالأعلى if not root
لايقاف الـ loop.
يعني أول شيء ادخل لأقصى اليسار وبعدين اطبع وبعدين ادخل لليمين, خوارزمية لديها العديد من الشروط كتبت في أسطر قليلة والفضل للتفكير بشكل recursive.
في حال أردت كتابة الخوارزمية بشكل iterative (باستعمال while أو for) ستكون بهذا الشكل:
def inOrder(root):
current = root
s = []
done = 0
while(not done):
if current is not None:
s.append(current)
current = current.left
else:
if(len(s) >0 ):
current = s.pop()
print current.data,
current = current.right
else:
done = 1
-
من أفضل recursive أم iterative ؟
كما شاهدت, recursive أحياناً تجعل كتابة الكود أسهل بكثير, لكن كل شيء لديه ثمن, يأتي على ثمن أن recursive function أبطأ بكثير وتستهلك الـ stack لأنها عبارة عن function داخل function تستدعي نفسها مرات عديدة.
وستحفظ نتائج كل دخول على الدالة في الذاكرة حتى تنتهي الدالة الرئيسية من التنفيذ:
أي أن iterative أسرع بكثير من ناحية الـ performance.
-
مصدر الصورة:
https://stackoverflow.com/questions/20957023/flattening-a-binary-tree-to-an-array-in-java -
مصدر الكود recrursive (بتصرف):
https://stackoverflow.com/questions/41622174/inorder-binary-tree-traversal-using-python -
مصدر الكود iterative:
https://www.geeksforgeeks.org/inorder-tree-traversal-without-recursion/ -
مصدر صورة call stack:
https://medium.com/@gaurav.pandvia/understanding-javascript-function-executions-tasks-event-loop-call-stack-more-part-1-5683dea1f5ec
شرح مفيد استاذ ياسر ,مشكور ^^