רשימה מעגלית

erezsh

New member
רשום היעיל ביותר,

כלומר גם אם הפתרון היעיל ביותר הוא לא יעיל באופן כללי, הוא נכון כל עוד הוא היעיל ביותר. בכל מקרה, מספר האירטציות יהיה כסכום סדרה: (n/2)(n+1) כלומר, סיבוכיות ריבועית.
 

nadavb

New member
ניסיון לתשובה

ע"י רקורסיה: תוכנית לדוגמא: בהנחה שהנקסט של האיבר האחרון מצביע על NULL וכשהפונקציה נקראת אז הפרמטר שיינתן יהיה האיבר הראשון void reverse(node *p) { if (node->next==NULL) cout << p->data; else { reverse(p->next); cout << p->data; } } התוכנית סורקת את הרשימה עד שהיא מגיעה לאיבר האחרון, ברגע שהיא מגיעה לאיבר האחרון התכנית מתחילה להדפיס את האיברים, כאשר האיבר האחרון שיודפס יהיה האיבר הראשון
 

nadavb

New member
יצא קצת מבולגן

אז הנה זה בקובץ טקסט
 

אלדד28

New member
רקורסיה היא הפתרון הפשטני והמתבקש

אבל היא משתמשת בזכרון בסדר גודל N ולא בזכרון קבוע.
 

ChipsMan

New member
הערה..

האלגוריתם היעיל ביותר שאני מכיר פועל בסיבוכיות זמן נמוכה יותר מאו של n בריבוע, ומשתמש בכמות זיכרון קבועה.
 
אני אתמול בעיקרון חשבתי על משהו כזה

של למצוא את המקסימום ברשימה (O(N) כמובן, ואז להפוך את הרשימה למספר בבסיס max+1 (להוסיף את האיבר הנוכחי, להתקדם הלאה ולכפול בmax+1 את מה שיש לנו ולהוסיף את האיבר הבא וכן הלאה עד הסוף) ואחרי שסיימנו פשוט "לחזור אחורה" באמצעות פעולות של mod וdiv (באופן דומה לאלגוריתם שבודק את כמות הספרות במספר). זמן הריצה יהיה O(n) העניין הוא שכמות הזכרון לא ממש קבועה אלא בכמות לוגריתמית של זכרון... אוף...
 

ChipsMan

New member
אוקי, ניתן רמז ../images/Emo13.gif

האלגוריתם היעיל ביותר (לפחות היעיל ביותר שאני מכיר) רץ בסיבוכיות זמן או של n כפול שורש n. (n בחזקת 1.5).
 

1אברהם

New member
תשובה

גודל הרשימה הוא N . נחלק אותה ל K תתי רשימות שבכל אחד M אברים ( N=K*M ) . יש להגיע להתחלה של כל תת רשימה ( כאשר מתחילים מהתת רשימה האחרונה )ואז להפעיל שם את האלגוריתם של eresh רק על התת רשימה הזו. כלומר להגיע לסוף התת רשימה , להדפיס את האיבר, ללכת להתחלת התת רשימה , להגיע לסופ התת רשימה פחות איבר אחד להדפיסו וכך עד שמדפיסים את האיבר הראשון בתת רשימה. הסיבוכיות של הדפסת תת רשימה היא S1=(M+1)*N/2 הסיבוכיות של להגיע כל פעם להתחלת תת רשימה היא S2=(K-1)*N/2 סה"כ סיבוכיות היא S=S1+S2=(K+M)*N/2 נציב K=N/M S=(N/K+K)*N/2 על ידי גזירה אפשר להראות שמינימום מתקבל אם
K=sqrt(N) ואז S=N*(N/sqrt(N)+sqrt(N))/2=N*(sqrt(N)+sqrt(N))/2=N*sqrt(N)​
 

erezsh

New member
אבל

זה לא דורש בעצם זיכרון דינמי? (הרי אסור לשנות את הרשימה)
 

1אברהם

New member
לא צריך זיכרון דינמי

צריך מצביע להתחלת הרשימה, מצביע שני להתחלת תת רשימה , ואולי עוד מצביע אחד שמצביע על האיבר האחרון שהודפס בתת רשימה. כלומר אפשר להסתפק בזיכרון בעל גודל קבוע ללא תלות באורך הרשימה.
 
למעלה