Queue/Definition: Difference between revisions

From Rosetta Code
Content added Content deleted
(Append to one side, pop from the other)
Line 13: Line 13:


Define the data structure for a FIFO element. Said element should contain a data member capable of holding a numeric value, and the link to the next element should be mutable.
Define the data structure for a FIFO element. Said element should contain a data member capable of holding a numeric value, and the link to the next element should be mutable.

==[[Ada]]==
[[Category:Ada]]
The interface specification for a FIFO is described in the package specification.
generic
type Element_Type is private;
package Fifo is
type Fifo_Type is private;
procedure Push(List : in out Fifo_Type; Item : in Element_Type);
procedure Pop(List : in out Fifo_Type; Item : out Element_Type);
function Is_Empty(List : Fifo_Type) return Boolean;
Empty_Error : exception;
private
type Fifo_Element;
type Fifo_Ptr is access Fifo_Element;
type Fifo_Type is record
Head : Fifo_Ptr := null;
Tail : Fifo_Ptr := null;
end record;
type Fifo_Element is record
Value : Element_Type;
Next : Fifo_Ptr := null;
end record;
end Fifo;
The FIFO implementation is described in the package body:
with Ada.Unchecked_Deallocation;
package body Fifo is
----------
-- Push --
----------
procedure Push (List : in out Fifo_Type; Item : in Element_Type) is
Temp : Fifo_Ptr := new Fifo_Element'(Item, null);
begin
if List.Tail = null then
List.Tail := Temp;
end if;
if List.Head /= null then
List.Head.Next := Temp;
end if;
List.Head := Temp;
end Push;
---------
-- Pop --
---------
procedure Pop (List : in out Fifo_Type; Item : out Element_Type) is
procedure Free is new Ada.Unchecked_Deallocation(Fifo_Element, Fifo_Ptr);
Temp : Fifo_Ptr := List.Tail;
begin
if List.Head = null then
raise Empty_Error;
end if;
Item := List.Tail.Value;
List.Tail := List.Tail.Next;
if List.Tail = null then
List.Head := null;
end if;
Free(Temp);
end Pop;
--------------
-- Is_Empty --
--------------
function Is_Empty (List : Fifo_Type) return Boolean is
begin
return List.Head = null;
end Is_Empty;
end Fifo;
A "main" procedure for this program is:
with Fifo;
with Ada.Text_Io; use Ada.Text_Io;
procedure Fifo_Test is
package Int_Fifo is new Fifo(Integer);
use Int_Fifo;
My_Fifo : Fifo_Type;
Val : Integer;
begin
for I in 1..10 loop
Push(My_Fifo, I);
end loop;
while not Is_Empty(My_Fifo) loop
Pop(My_Fifo, Val);
Put_Line(Integer'Image(Val));
end loop;
end Fifo_Test;


==[[Python]]==
==[[Python]]==

Revision as of 23:22, 4 November 2007

Task
Queue/Definition
You are encouraged to solve this task according to the task description, using any language you may know.

Implement a FIFO queue. Elements are added at one side and popped from the other in the order of insertion.

Operations:

  • push - add element
  • pop - pop first element
  • empty - return truth value when empty

Errors:

  • handle the error of trying to pop from an empty queue (behavior depends on the language and platform)

Define the data structure for a FIFO element. Said element should contain a data member capable of holding a numeric value, and the link to the next element should be mutable.

Ada

The interface specification for a FIFO is described in the package specification.

generic
   type Element_Type is private;
package Fifo is
   type Fifo_Type is private;
   procedure Push(List : in out Fifo_Type; Item : in Element_Type);
   procedure Pop(List : in out Fifo_Type; Item : out Element_Type);
   function Is_Empty(List : Fifo_Type) return Boolean;
   Empty_Error : exception;
private
   type Fifo_Element;
   type Fifo_Ptr is access Fifo_Element;
   type Fifo_Type is record
      Head : Fifo_Ptr := null;
      Tail : Fifo_Ptr := null;
   end record;
   type Fifo_Element is record
      Value : Element_Type;
      Next  : Fifo_Ptr := null;
   end record;
end Fifo;

The FIFO implementation is described in the package body:

with Ada.Unchecked_Deallocation;

package body Fifo is 

   ----------
   -- Push --
   ----------

   procedure Push (List : in out Fifo_Type; Item : in Element_Type) is
      Temp : Fifo_Ptr := new Fifo_Element'(Item, null);
   begin
      if List.Tail = null then
         List.Tail := Temp;
      end if;
      if List.Head /= null then
        List.Head.Next := Temp;
      end if;
      List.Head := Temp;
   end Push;

   ---------
   -- Pop --
   ---------

   procedure Pop (List : in out Fifo_Type; Item : out Element_Type) is
      procedure Free is new Ada.Unchecked_Deallocation(Fifo_Element, Fifo_Ptr);
      Temp : Fifo_Ptr := List.Tail;
   begin
      if List.Head = null then
         raise Empty_Error;
      end if;
      Item := List.Tail.Value;
      List.Tail := List.Tail.Next;
      if List.Tail = null then
         List.Head := null;
      end if;
      Free(Temp);
   end Pop;

   --------------
   -- Is_Empty --
   --------------

   function Is_Empty (List : Fifo_Type) return Boolean is
   begin
      return List.Head = null;
   end Is_Empty; 

end Fifo;

A "main" procedure for this program is:

with Fifo;
with Ada.Text_Io; use Ada.Text_Io;

procedure Fifo_Test is
   package Int_Fifo is new Fifo(Integer);
   use Int_Fifo;
   My_Fifo : Fifo_Type;
   Val : Integer;
begin
   for I in 1..10 loop
      Push(My_Fifo, I);
   end loop;
   while not Is_Empty(My_Fifo) loop
      Pop(My_Fifo, Val);
      Put_Line(Integer'Image(Val));
   end loop;
end Fifo_Test;

Python

Python 2.4 and later includes a deque class, supporting thread-safe, memory efficient appends and pops from either side of the deque with approximately the same O(1) performance in either direction. For other options see Python Cookbook.

from collections import deque
fifo = deque()
fifo. appendleft(value) # push
value = fifo.pop()
not fifo # empty
fifo.pop() -> raises IndexError when empty