logo

תור מעגלי

מדוע הוצג הרעיון של התור המעגלי?

הייתה מגבלה אחת ביישום המערך של

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

מהו תור מעגלי?

תור מעגלי דומה לתור ליניארי שכן הוא מבוסס גם על עקרון ה-FIFO (First In First Out) אלא שהמיקום האחרון מחובר למיקום הראשון בתור מעגלי שיוצר מעגל. זה ידוע גם בתור א מאגר טבעת .

פעולות על תור מעגלי

להלן הפעולות שניתן לבצע על תור מעגלי:

rj12 לעומת rj11
    חֲזִית:הוא משמש כדי לקבל את האלמנט הקדמי מהתור.חלק אחורי:הוא משמש כדי לקבל את האלמנט האחורי מהתור.enQueue(value):פונקציה זו משמשת להכנסת הערך החדש בתור. האלמנט החדש מוכנס תמיד מהקצה האחורי.deQueue():פונקציה זו מוחקת רכיב מהתור. המחיקה בתור מתרחשת תמיד מהקצה הקדמי.

יישומים של תור מעגלי

ניתן להשתמש בתור המעגלי בתרחישים הבאים:

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

פעולת תור

השלבים של פעולת התור ניתנים להלן:

  • ראשית, נבדוק אם התור מלא או לא.
  • בתחילה הקדמי והאחורי מוגדרים ל-1. כאשר אנו מכניסים את האלמנט הראשון בתור, הקדמי והאחורי שניהם מוגדרים ל-0.
  • כאשר אנו מכניסים אלמנט חדש, החלק האחורי מתגבר, כלומר, אחורי=אחורי+1 .

תרחישים להכנסת אלמנט

ישנם שני תרחישים שבהם התור אינו מלא:

    אם אחורי != מקסימום - 1, ואז האחורי יוגדל ל mod(maxsize) והערך החדש יוכנס בקצה האחורי של התור.אם קדמי != 0 ואחורי = מקסימום - 1, זה אומר שהתור אינו מלא, ואז הגדר את הערך של rear ל-0 והכנס שם את האלמנט החדש.

ישנם שני מקרים בהם לא ניתן להכניס את האלמנט:

  • מתי קדמי ==0 && אחורי = מקסימום-1 , כלומר הקדמי נמצא במיקום הראשון של התור והאחורי הוא במיקום האחרון של התור.
  • קדמי== אחורי + 1;

אלגוריתם להכנסת אלמנט בתור מעגלי

שלב 1: IF (REAR+1)%MAX = FRONT
כתוב ' OVERFLOW '
עבור לשלב 4
[סוף אם]

שלב 2: IF FRONT = -1 ו- REAR = -1
SET FRONT = REAR = 0
אחרת אם אחורי = MAX-1 וחזית! = 0
SET REAR = 0
אַחֵר
SET REAR = (REAR + 1) % MAX
[סוף אם]

ג'אווה hashable

שלב 3: SET QUEUE[REAR] = VAL

שלב 4: יְצִיאָה

תפעול תור

השלבים של פעולת העמדת התור ניתנים להלן:

  • ראשית, אנו בודקים אם התור ריק או לא. אם התור ריק, לא נוכל לבצע את פעולת התור.
  • כאשר הרכיב נמחק, הערך של front מופחת ב-1.
  • אם נשאר רק רכיב אחד שיש למחוק, אז החזית והחלק האחורי מאופסים ל-1.

אלגוריתם למחיקת אלמנט מהתור המעגלי

שלב 1: IF FRONT = -1
כתוב ' UNDERFLOW '
עבור לשלב 4
[END of IF]

שלב 2: SET VAL = תור[FRONT]

שלב 3: IF FRONT = REAR
SET FRONT = REAR = -1
אַחֵר
IF FRONT = MAX -1
SET FRONT = 0
אַחֵר
SET FRONT = FRONT + 1
[END of IF]
[סוף אם]

שלב 4: יְצִיאָה

מחרוזת לצ'אר ב-java

בואו נבין את פעולת התור והתור באמצעות הייצוג הדיאגרמטי.

תור מעגלי
תור מעגלי
תור מעגלי
תור מעגלי
תור מעגלי
תור מעגלי
תור מעגלי
תור מעגלי

יישום תור מעגלי באמצעות Array

 #include # define max 6 int queue[max]; // array declaration int front=-1; int rear=-1; // function to insert an element in a circular queue void enqueue(int element) { if(front==-1 && rear==-1) // condition to check queue is empty { front=0; rear=0; queue[rear]=element; } else if((rear+1)%max==front) // condition to check queue is full { printf('Queue is overflow..'); } else { rear=(rear+1)%max; // rear is incremented queue[rear]=element; // assigning a value to the queue at the rear position. } } // function to delete the element from the queue int dequeue() { if((front==-1) && (rear==-1)) // condition to check queue is empty { printf('
Queue is underflow..'); } else if(front==rear) { printf('
The dequeued element is %d', queue[front]); front=-1; rear=-1; } else { printf('
The dequeued element is %d', queue[front]); front=(front+1)%max; } } // function to display the elements of a queue void display() { int i=front; if(front==-1 && rear==-1) { printf('
 Queue is empty..'); } else { printf('
Elements in a Queue are :&apos;); while(i<=rear) { printf('%d,', queue[i]); i="(i+1)%max;" } int main() choice="1,x;" variables declaration while(choice<4 && choice!="0)" while loop printf('
 press 1: insert an element'); printf('
press 2: delete 3: display the printf('
enter your choice'); scanf('%d', &choice); switch(choice) case printf('enter element which is to be inserted'); &x); enqueue(x); break; dequeue(); display(); }} return 0; < pre> <p> <strong>Output:</strong> </p> <img src="//techcodeview.com/img/ds-tutorial/14/circular-queue-10.webp" alt="Circular Queue"> <h3>Implementation of circular queue using linked list</h3> <p>As we know that linked list is a linear data structure that stores two parts, i.e., data part and the address part where address part contains the address of the next node. Here, linked list is used to implement the circular queue; therefore, the linked list follows the properties of the Queue. When we are implementing the circular queue using linked list then both the <strong> <em>enqueue and dequeue</em> </strong> operations take <strong> <em>O(1)</em> </strong> time.</p> <pre> #include // Declaration of struct type node struct node { int data; struct node *next; }; struct node *front=-1; struct node *rear=-1; // function to insert the element in the Queue void enqueue(int x) { struct node *newnode; // declaration of pointer of struct node type. newnode=(struct node *)malloc(sizeof(struct node)); // allocating the memory to the newnode newnode-&gt;data=x; newnode-&gt;next=0; if(rear==-1) // checking whether the Queue is empty or not. { front=rear=newnode; rear-&gt;next=front; } else { rear-&gt;next=newnode; rear=newnode; rear-&gt;next=front; } } // function to delete the element from the queue void dequeue() { struct node *temp; // declaration of pointer of node type temp=front; if((front==-1)&amp;&amp;(rear==-1)) // checking whether the queue is empty or not { printf(&apos;
Queue is empty&apos;); } else if(front==rear) // checking whether the single element is left in the queue { front=rear=-1; free(temp); } else { front=front-&gt;next; rear-&gt;next=front; free(temp); } } // function to get the front of the queue int peek() { if((front==-1) &amp;&amp;(rear==-1)) { printf(&apos;
Queue is empty&apos;); } else { printf(&apos;
The front element is %d&apos;, front-&gt;data); } } // function to display all the elements of the queue void display() { struct node *temp; temp=front; printf(&apos;
 The elements in a Queue are : &apos;); if((front==-1) &amp;&amp; (rear==-1)) { printf(&apos;Queue is empty&apos;); } else { while(temp-&gt;next!=front) { printf(&apos;%d,&apos;, temp-&gt;data); temp=temp-&gt;next; } printf(&apos;%d&apos;, temp-&gt;data); } } void main() { enqueue(34); enqueue(10); enqueue(23); display(); dequeue(); peek(); } </pre> <p> <strong>Output:</strong> </p> <img src="//techcodeview.com/img/ds-tutorial/14/circular-queue-11.webp" alt="Circular Queue"> <hr></=rear)>

תְפוּקָה:

תור מעגלי