Title: Data structure
1Data structure
2Contents
- Different Data Types
- Array
- String
- Record
3Definition
- A data structure is a composite of related data
items stored under the same name.
4User-defined data types
- type
- lttype identifiergt lttype declaration clausegt
- lttype identifiergt lttype declaration clausegt
-
5Type declaration in Pascal
- type
- List array1..10 of integer
- StaffRec record
- Name string30
- Salary real
- Age integer
- end
- var
- ScoreList, TestList List
- ExamList array1..10 of integer
- Programmer, Clerk StaffRec
6Ordinal data type
- An ordinal data type has a finite set of values
that can always be listed in order from the first
to the last. -
- predefined ordinal types include
- integer, boolean and char.
7Function ord()
- ord()
- This function returns the ordinal value of an
ordinal-type expression. - e.g.
- ord(A) 65
- ord(B) 66
-
8Function pred()
- pred()
- This function returns the predecessor of the
argument, i.e. the value listed before the
argument if the values of that type are arranged
in ascending order. - e.g.
- pred(B) A
9Function succ()
- succ()
- This function returns the successor of the
argument, i.e. the value listed after the
argument if the values of that type are arranged
in ascending order. - e.g.
- succ(A) B
10Enumerated types
- An enumerated type includes in its definition an
exhaustive list of possible values for variables
of that type.
11Enumerated types
- type
- DayOfWeek (Sunday, Monday, Tuesday, Wednesday,
Thursday,Friday, Saturday) - MaritalStatus (Single, Married, Divorce, Separ
ated) - var
- Today, Tomorrow, Yesterday DayOfWeek
- MS MaritalStatus
12Why use enumerated types?
enumerated types make the program considerably
easier to read and understand
13Subrange types
- A subrange type is an ordinal data type whose
values are a subset of another ordinal type (the
host type). - type
- Letter 'A'..'Z'
- var
- NextChar Letter
- NextChar can only be a capital letter
- InDay 1..31
- InDay can be any integer between 1 31 inclusiv
e
14Arrays
- An array is a collection of identically typed
data items distinguished by their indices (or
subscripts).
15Declaring arrays in Pascal
- arrayltsubscript typegt of ltelement typegt
- Example
- const
- NumEmp 8
- type
- EmpRange 1..NumEmp
- EmpArray arrayEmpRange of Boolean
- Day (Sunday, Monday, Tuesday, Wednesday, Thurs
day, Friday, Saturday) - WorkingDaySalary arrayMonday..Friday of real
-
- Spreadsheet array'A'..'Z', 1..100 of real
16How a one-dimensional array is stored in the
memory
- type
- ArrayType arraya..b of SomeType
- var
- AnArray ArrayType
- Suppose that a and b are integer constants where
a ? b, a variable of type SomeType occupies n
bytes, and the variable AnArray is stored at
address p. At what address is the element
AnArrayi stored?
p(i-a)n
17How a multi-dimensional array is stored in the
memory
- type
- TableType array1..3, 1..5 of integer
- var
- M TableType
18How a multi-dimensional array is stored in the
memory
In Turbo Pascal, elements in a multi-dimensional
array are arranged in row major order.
19Multi-dimensional Array
- type
- ArrayType array1.. M, 1.. N of SomeType
- var
- LargeArray ArrayType
- A variable of type SomeType occupies n bytes, and
the variable LargeArray is stored at address p. At
what address is the element LargeArrayR,C store
d? Consider the different cases for row-major orde
r and column-major order.
p ((R-1)N (C-1))n Row-major order p
((C-1)M (R-1))n Column-major order
20Multi-dimensional Array
- type
- ArrayType arrayL1.. U1, L2.. U2, , Lm.. Um
of SomeType - var
- LargeArray ArrayType
- Suppose that L1, L2, , Lm and U1, U2, , Um are i
nteger constants where Li ? Ui (i 1, 2, , m). A
variable of type SomeType occupies n bytes, and t
he variable LargeArray is stored at address p. At
what address is the element LargeArrayx1, x2, ,
xm stored? Consider the different cases for row-m
ajor order and column-major order.
21Strings
- A string is a sequence of characters. In Pascal,
a string is enclosed in a pair of apostrophes. A
string variable can contain up to 255 characters. - In the following example, the variable name can
store up to 25 characters - var name string25
22Storage of Strings
- If a string variable consists of n characters, it
occupies n 1 bytes. - Note Turbo Pascal uses an extra byte to store
the length of a string.
23Storage of Strings
- In some programming languages such as C, a null
character (a character with ASCII code equal to
0) is appended to the end of the string.
Question What are the advantages and
disadvantages of storing strings in the above
formats?
24Pascal string functions
- copy(s, index, count)
- It returns a string which is a substring of s.
The substring containing count characters
starting with the indexth character in s. - concat(s1, s2, ...)
- It returns a string formed by concatenation of
all the string parameters in the same order as
listed in the parameter list. - Note String concatenation can also be performed
by using . - e.g. Name David Beckham
25Pascal string functions
- length(s)
- It returns an integer which is the length of the
string s. - pos(substr, s)
- It searches for substr within the string s and
returns an integer value that is the index of the
first character of substr within s. If substr is
not found, it returns zero. - e.g.
- pos('gram', 'Programming') returns
4,pos('call', 'Pascal') returns 0.
26Pascal string procedures
- insert(source, s, index)
- It inserts the string source into the string s (a
variable parameter) at the indexth position. - e.g. if s Honest Lincoln
- insert('Abe ', s, 8)
- s will changed to Honest Abe Lincoln.
delete(s, index, count) It deletes count
characters from the string s (a variable
parameter) starting at the indexth position. e.g
if s Honest Abe Lincoln delete(s, 8, 4) s
will changed to Honest Lincoln.
27Pascal string procedures
- str(x, s)
- It converts the numeric value x to a string and
store it in the variable parameter s. - val(s, x, code)
- It converts the string s into a real or integer
value x (the value of the result is affected by
the data type of x). - If the conversion is successful, code is zero.
Otherwise, the position of the first invalid
character in the string s is stored in code.
28Records
- A record is an ordered set of fields.
- Usually the fields involved are related. We often
a record to store details of a person, an object,
etc. Actually, records are components of a
database table.
29Declaring records in Pascal
- record
- ltfield identifier 1gt ltdata type 1gt
- ltfield identifier 2gt ltdata type 2gt
-
- ltfield identifier ngt ltdata type ngt
- end
- E.g.
- type
- EmployeeInfo record
- Name string 256 bytes
- Sex char 1 byte
- Age integer 2 bytes
- Salary real 6 bytes
- end
- var
- Programmer, Manager EmployeeInfo 265 bytes
30Accessing record fields
- To access a field in a record, we write
- ltrecord namegt.ltfield namegt
- For example
- writeln(Manager.Age)
- readln(Programmer.salary)
- Manager.Name 'Mary Lee'
31 with..do statements
32Array of records
- A record can only hold information about one
item. Commonly, we have to deal with a list of
information on several items. This can be achieve
by arrays of records. -
- E.g.
- const
- size 100
- type
- Str20 string20
- Str8 string8
- Info record
- Name Str20
- Phone Str8
- end
- InfoArray array1..size of Info
- var
- Directory InfoArray
33Array of records
34Variant record
- we can use variant records (also called unions in
some programming languages) to store data
collections in which some fields are always the
same (the fixed part) and some fields may be
different (the variant part).
35Declaring variant records
- record
- ltfixed field 1gt lttype 1gt
- ltfixed field 2gt lttype 2gt
-
- ltfixed field ngt lttype ngt
- case lttag fieldgt lttag typegt of
- ltlabel 1gt (ltvariant field list 1gt)
- ltlabel 2gt (ltvariant field list 2gt)
-
- ltlabel kgt (ltvariant field list kgt)
- end
36Variant records example
- const
- StringLength 20 length of all strings ex
cept zipcode - ZipStringSize 5 length of zipcode string
-
- type
- IDRange 1111..9999
- StringType stringStringLength
- ZipString stringZipStringSize
- Month (January, February, March, April, May, J
une, July, - August, September, October, November, D
ecember) - Employee record
- ID IDRange
- Name StringType
- Gender char
- NumDepend integer
- Rate, TotWages real
- end Employee
- Address record
- Street, City, State St
ringType
- Date record
- ThisMonth Month
- Day 1..31
- Year 1900..1999
- end Date
- MaritalStatus (Married, Divorced, Single)
37Variant records example
- Executive record
- PayData Employee
- Home Address
- StartDate, BirthDate Date
- case MS MaritalStatus of
- Married (SpouseName StringType
- NumberKids integer)
- Divorced (DivorceDate date)
- Single (LivesAlone boolean)
- end Executive
- var
- boss Executive
38Sets
- A set is an unordered list of elements that are
values of the same ordinal type (called the base
type)
39Declaring Sets
- Syntax
- set of ltbase typegt
- e.g.
- type
- Day (Sun, Mon, Tue, Wed, Thu, Fri, Sat)
- CharSet set of Char
- Digits set of 0..9
- Days set of Day
- var
- GradeSet CharSet
- Codes Digits
- WorkingDaySet Days
-
40Sets assignment statment
- e.g.
- GradeSet 'A'..'F'
- Codes 0..9
- WorkingDaySet Mon..Fri
- N.B. Order and repetition of elements within the
set are irrelevant. Therefore, - 1, 2, 3 3, 1, 2 2, 1, 2, 3, 1
41Empty set and universal set
- An empty set has no elements and is denoted by
. - A universal set contains all the values in the
base type for a particular type.
42Set membership (in)
- Suppose that S is a set. In Mathematics, we write
x ? S to denote that x is a member of S. The
expression in Pascal is - x in S
- The left operand is of ordinal type, say T, and
the right operand is a set whose base type is T.
If x is a member of S, it returns true.
Otherwise, it returns false. - E.g.
- ch in '.', '?', '', '!'
43Set union
- The union of two sets is the set of elements that
are members of either or both sets.
Mathematically, we write A ? B as the union of
A and B. In Pascal, we write - A B
- E.g.
- 1, 3, 4 1, 2, 4 is 1, 2, 3, 4
- 1, 3 2, 4 is 1, 2, 3, 4
- 'A', 'C', 'F' 'B', 'C', 'D', 'F' is 'A', '
B', 'C', 'D', 'F' - 'A', 'C', 'F' 'A', 'C', 'D', 'F' is
'A', 'C', 'D', 'F'
44Set intersection
- The intersection of two sets is the set of
elements that are members of both sets.
Mathematically, we write A ? B as the union of
A and B. In Pascal, we write - A B
- E.g.
- 1, 3, 4 1, 2, 4 is 1, 4
- 1, 3 2, 4 is
- 'A', 'C', 'F' 'B', 'C', 'D', 'F' is 'C', 'F
' - 'A', 'C', 'F' 'A', 'C', 'D', 'F' is
'A', 'C', 'F'
45Set complement
- The complement of A in B is the set of elements
that are members of B but are not members of A.
Mathematically, we write B A as the
complement of A in B. In Pascal, we write - B - A
- E.g.
- 1, 3, 4 - 1, 2, 4 is 3
- 1, 3 - 2, 4 is 1, 3
- 'A', 'C', 'F' - 'B', 'C', 'D', 'F' is 'A'
- 'A', 'C', 'F' - 'A', 'C', 'D', 'F' is
- 'A', 'C', 'D', 'F' - 'A', 'C', 'F' is 'D'
46Set equality and inequality
- Two sets are equal if and only if they have the
same elements. To compare two sets, they must
have the same base type. - E.g.
- 1, 3 1, 3 is true
- 1, 3 ltgt 2, 4 is true
- 1, 3 3, 1 is true
- 1, 3 1, 3, 1 is true
47Subset and superset
- The set A is a subset of the set B if every
element of A is also an element of B. We may also
say that the set B is a superset of the set A. - Mathematically, we write A ? B as the
expression A is a subset of B. In Pascal, we
write - A lt B
- Mathematically, we write A ? B as the
expression A is a superset of B. In Pascal, we
write - A gt B
48Subset and superset
- E.g.
- 1, 3 lt 1, 2, 3, 4 is true 1, 3 gt 1, 2, 3,
4 is false - 1, 3 lt 1, 3 is true 1, 3 gt 1, 3 is true
- 1, 2, 3, 4 lt 1, 3 is false 1, 2, 3, 4 gt 1
, 3 is true - lt 1, 3 is true gt 1, 3 is false
- 1, 3 lt is false 1, 3 gt is true
49Text files
- A file is an element of data storage in a file
system (e.g. disk, tape, directory, etc.). - A text file is a file containing only printable
characters - E.g. (such as letters from the English alphabet,
numbers, punctuation marks, a few symbols, etc.),
end-of-line characters (lteolngt) and end-of-file
characters (lteofgt).
50Manipulating text files
- Declaration text variables in Turbo Pascal
- var
- infile, outfile text
- Associating a text variable with an external text
file assign(f, s) - Opening an existing text file for reading
- reset(f)
- Creating and opening a new file
- rewrite(f)
51Manipulating text files
- Reading data from a text file
- read(ltinput filegt, ltvariable listgt)
- readln(ltinput filegt, ltvariable listgt)
- Writing data to a text file
- write(ltoutput filegt, ltvariable listgt)
- writeln(ltoutput filegt, ltvariable listgt)
- Closing a file
- close(f)
52Binary files
- A binary file is a file containing arbitrary
bytes or words, as opposed to a text file
containing only printable characters. - A component of a binary file is stored on disk
using the same binary form as it has in main
memory.
53Declaring file variables
- The type declaration clause for a binary file is
as follows - file of ltcomponent typegt
- E.g.
- type
- NumberFile file of integer
- Book record
- StockNum integer
- Author, Title string20
- Price real
- Quantity integer
- end
- BookFile file of Book
- var
- Numbers NumberFile
- Books BookFile
54Manipulating binary files Sequential access
- Similar to text files
- assign(f, s)
- reset(f)
- rewrite(f)
- read(ltinput filegt, ltcomponent type variablegt)
- write(ltoutput filegt, ltcomponent type variablegt)
- close(f)
- eof(f)
55Abstract Data Types
- An abstract data type is a combination of a data
type and procedures and functions for
manipulating the data type. - The details of how to implement the data type and
the procedures and functions are unknown to users
of the abstract data type. Instead, users are
only required to know how to use them.
56Advantages of ADT
- It allows us to implement the client program and
the ADT relatively independent of each other. - If we decide to change the implementation of an
operator(procedure) in the ADT, we can do so
without affecting the client program. - Finally, because the internal representation of a
data type is hidden form its client program, we
even change the internal representation at a
later time without modifying the client program.
57Pointers
- A pointer variable (pointer) is one whose
contents are a memory cell address. This means
that we store the address of a particular data
object in a pointer variable.
58Declaring pointer type
- The type declaration clause for a pointer type is
- ltdata typegt
- For example
- type
- RealPointer real
- NodePtr node
- node record
- data integer
- next NodePtr
- end
- var
- px RealPointer
- pn integer
- head NodePtr
59Pointer operations - New()
- The procedure new(ltpointergt) allocates a memory
storage from the heap (a storage pool of
available memory cells maintained by the
computer) for a new data area, - and the address of this data is stored in pioneer
variable ltpointergt - Since allocation of memory is done during program
execution when new is called, this is called
dynamic allocation
60Pointer operations - Dispose()
- The procedure dispose(ltpointergt) returns the
memory cells in the data area whose address is
stored ltpointergt to the heap. These cells can be
reallocated when procedure new is called. - After the procedure dispose(ltpointergt) is done,
ltpointergt points to nothing. We say that the
content of ltpointergt is nil (a reserved word).
61the dereferencing operator
- The (caret) is called the dereferencing
operator. Use ltpointergt to reference the data
area. the memory cell pointed to by px is
expressed as - px
- It can be processed just like any other real
variable. - Note that the value of a pointer (i.e. an
address) cannot be directly displayed.
62PointerExamples
63PointerExamples
begin new(ip) ip 7
writeln(ip) Display 7
iq ip
64PointerExamples
iq 8 writeln(ip, ' ', iq) Display
8 8 i 9 ip i writel
n(ip) Display 9
65PointerExamples
new(iq) iq 4 i iq writel
n(i) Display 4 dispose(ip)
66PointerExamples
new(iq) new(ip) end.
Note that there should always be at least one
pointer variable points to a dynamically
allocated storage. Remember to use dispose() to
return a dynamically allocated storage which will
not further be used to the heap. Otherwise, heap
overflow may occur.
67Lists
- A list is a data structure holding a number of
values which are usually accessed sequentially,
working from the head to the tail.
68Operations
- Let L be a list of objects of type ElementType,
- x be an object of ElementType and
- p be an integer indicating a position in the
list L. - The following are some examples of operations of
lists - ListSize(L)
- A function returning the number of elements in
L. - InsertAfter(x, p, L)
- A function that inserts an object x after the
pth position of L. It returns true if the
insertion is successful and false otherwise. - InsertBefore(x, p, L)
- A function that inserts an object x before the
pth position of L. It returns true if the
insertion is successful and false otherwise. - DeleteItem(x, p, L)
- A function that deletes the object at the pth
position of L. It returns if the deletion is
successful and false otherwise.
69Operations
- LocateItem(x, L)
- A function that returns the position of the
first occurrence of x in L (and returns an
appropriate value if x is not in L). - RetrieveItem(p, L)
- A function that returns the pth element in L. It
will return an undefined value if there is no
position p in L. - NextPos(p, L)
- A function that returns the position following
the pth element in L. - PrevPos(p, L)
- A function that returns the position preceding
the pth element in L. - LastPos(L)
- A function that returns the position of the last
element in L. - FirstPos(L)
- A function that returns the position of the
first element in L. - MakeNull(L)
- A procedure causing L to become an empty list.
- PrintList(L)
- A procedure displaying the all the elements of L
sequentially.
70Array implementation
- Declaration an example
- const max 5
- type
- list record
- item array1..max of ElementType
- size integer
- end
- var L list
71Implementation of some operations
- function ListSize(L list) integer
- begin
- ListSize L.size
- end
-
- function InsertAfter(x ElementType p integer v
ar L list) boolean - var i integer
- begin
- If (L.size gt max) or (p gt L.size) or (p lt 0) th
en - InsertAfter false
- else begin
- for i L.size downto p 1 do
- L.itemi1 L.itemi
- L.itemp 1 x
- L.size L.size1
- InsertAfter true
- end
- end
72Implementation of some operations
- function RetrieveItem(p integer L list) Elemen
tType - begin
- if (p lt 1) or (p gt L.size) then
- writeln('RetrieveItem Item not found!')
- else
- RetrieveItem L.itemp
- end
-
- function NextPos(p integer L list) integer
- begin
- NextPos p 1
- end
-
- function PrevPos(p integer L list) integer
- begin
- PrevPos p - 1
- end
73Implementation of some operations
- function LastPos(L list) integer
- begin
- LastPos L.size
- end
-
- function FirstPos(L list) integer
- begin
- FirstPos 1
- end
74Linked lists
- A linked list consists of a number of nodes. Each
node contains a pointer to the next node, thus
forming a linear list.
75The contents of the memory
- The field data is used to store the data we want
the linked list to store, and - the field link is a pointer pointing to the next
node. Actually, the address of the next node is
stored in the field link.
76Linked lists Declaration
- Syntax of Linked lists
- type
- ltNode Pointer Typegt ltNode Typegt
- ltNode Typegt record
- ltData Field 1gt ltData Type 1gt
- ltData Field 2gt ltData Type 2gt
-
- ltData Field ngt ltData Type ngt
- ltPointer Fieldgt ltNode Pointer
Typegt - end
77Linked lists Declaration
- For example, the linked list shown on the
previous page can be declared as follows - type
- NodePtr NodeType
- NodeType record
- data ElementType
- link NodePtr
- end
- var
- L NodePtr
- We can use a pointer (in this case, L) to the
first node of a linked list to reference a linked
list.
78Implementation - ListSize
- function ListSize(L NodePtr) integer
- var
- n integer
- q NodePtr
- begin
- q L
- n 0
- while q ltgt nil do begin
- q q.link
- n n 1
- end
- ListSize n
- end
79Implementation - InsertAfter
- function InsertAfter(x ElementType p NodePtr v
ar L NodePtr) boolean - var
- q NodePtr
- begin
- if (p nil) and (L ltgt nil) then
- InsertAfter false
- else begin
- new(q) Request for a
new node from heap - q.data x
- if L nil then begin L is a null li
nked list - L q
- L.link nil
- end
- else begin
- q.link p.link
- p.link q
- end
- InsertAfter true
- end
p
X
80Implementation - DeleteItem
- function DeleteItem(p NodePtr var L NodePtr) b
oolean - var
- temp NodePtr
- begin
- if p nil then DeleteItem false
- else if p L then begin
- L L.link dispose(p) DeleteItem tru
e - end
- else begin
- temp L
- while (temp.link ltgt p) and (temp.link ltgt nil
) do - temp temp.link
- if temp.link p then begin
- temp.link p.link
- dispose(p)
- DeleteItem true
- end
- else DeleteItem false
- end
p
X
81Implementation - LocateItem
- function LocateItem(x ElementType L NodePtr) N
odePtr - var
- temp NodePtr
- begin
- temp L
- while (temp ltgt nil) and (temp.data ltgt x) do
- temp temp.link
- LocateItem temp
- end
82Implementation - PrintList
- procedure PrintList(L NodePtr)
- var
- temp NodePtr
- begin
- temp L
- while temp ltgt nil do begin
- writeln(temp.data)
- temp temp.link
- end
- end
83Implementation Notes
- Remember to assign nil to the link field of the
last node. - Take care to the pointers when inserting or
deleting a node, especially at the beginning and
the end of a linked list. - Do not use new unless you really want to add a
new node to the linked list, and remember to use
dispose whenever you want to remove a node from
the linked list.
84Using a header node I
- An empty list is no longer a nil pointer
(instead, a dummy node always exists at the
front)
85Using a header node II
- The header node may point to the end of the list
(for convenient access to the front and the rear
of a queue).
86Using a header node III
- The header node may be used to keep the number of
nodes within a list (however, the header must be
updated during insertion and deletion).
87Using a header node IV
- The header node may store the title for the rest
of the information stored in the list.
88Using a header node V
- The header node may indicate the current node
during list traversal (to facilitate searching,
insertion, deletion or resume processing).
89Circular linked lists
- A circular linked list is formed when the pointer
of the last node points to the first node. It
overcomes the need to traverse the list from the
first node to the last node every time when we
need to process every node within the list.
90Doubly linked lists
- To facilitate list traversal at the expense of
extra storage for links, an extra pointer can be
added to each node to point to the previous node
of the list.
91Circular Doubly Linked Lists
92Circular Doubly Linked Lists with header node
Actually, we can have any form of linked lists,
depending on the needs of the problem we are
going to solve.
93Stacks
- A stack is a data structure for storing items
which are to be accessed in last-in-first-out
(LIFO) order.
- We can think of a stack as a pile of trays at a
fast food restaurant. After each tray is cleaned,
it is put on the top of the existing pile one by
one. Normally, the tray on the top is taken to be
used first. Thus the last one in is the first one
out.
94Stack Applications
- Perhaps the most common use of stacks is to store
subroutine arguments and return addresses. This
is usually supported at the machine code level
either directly by jump to subroutine and
return from subroutine instructions or by
auto-increment and auto-decrement addressing
modes, or both. - A stack can also be used to evaluate an infix
expression
95Most common operations
- CreateStack(S) to create a new (empty) stack S,
- Push(x, S) to push a new item x onto the top of
the stack S, and - Pop(S) to pop the top item off the stack S (and
returns the popped item). - StackTop(S) returns the top item of the stack S
(without popping), - IsEmptyStack(S) returns whether the stack S is
empty, - IsFullStack(S) returns whether the stack S is
full.
96Array implementation - CreateStack
- We may use an array to implement a stack, the
first entry being the bottom. We need one
variable (sometimes called the stack pointer) to
keep track of the top position. - type
- Stack record
- item array1..max of ItemType
- top 0..max
- end
-
- procedure CreateStack(var S Stack)
- Initialises the stack S
- begin
- S.top 0
- end
97Array implementation IsEmptyStack and
IsFullStack
- function IsEmptyStack(S Stack) boolean
- Checks whether the stack S is empty
- begin
- IsEmptyStack (S.top 0)
- end
- function IsFullStack(S Stack) boolean
- Checks whether the stack S is full
- begin
- IsFullStack (S.top max)
- end
98Array implementation - Push
- procedure Push(x ItemType var S Stack)
- Adds one item x at the top of the stack S
- begin
- if IsFullStack(S) then
- writeln('Cannot push Stack is full!')
- else
- with S do begin
- top top 1
- itemtop x
- end
- end
99Array implementation - Pop
- function Pop(var S Stack) ItemType
- Returns the top item of the stack S and removes
it - begin
- if IsEmptyStack(S) then
- writeln('Cannot pop Stack is empty!')
- else
- with S do begin
- Pop itemtop
- top top - 1
- end
- end
100Array implementation - StackTop
- function StackTop(S Stack) ItemType
- Returns the top item of the stack S without popp
ing the stack - if IsEmptyStack(S) then
- writeln('Stack is empty!')
- else
- StackTop S.itemS.top
- end
101Linked list implementation
- One of the advantages of using a linked list to
implement a stack is that storage is allocated
only when necessary. The stack can grow or
shrink. The maximum capacity of the stack is only
limited by the amount of memory. - type
- NodePtr node
- node record
- item ItemType
- next NodePtr
- end
- Stack NodePtr
102Linked list implementation CreateStack and
IsEmptyStack
- procedure CreateStack(var S Stack)
- Initialises the stack S
- begin
- S nil
- end
- function IsEmptyStack(S Stack) boolean
- Checks whether the stack S is empty
- begin
- IsEmptyStack (S nil)
- end
103Linked list implementation Push
- procedure Push(x ItemType var S Stack)
- Adds one item x at the top of the stack S
- var
- temp NodePtr
- begin
- new(temp)
- temp.item x
- temp.next S
- S temp
- end
104Linked list implementation Pop
- function Pop(var S Stack) ItemType
- Returns the top item of the stack S and removes
it - var
- temp NodePtr
- begin
- if IsEmptyStack(S) then
- writeln('Cannot pop Stack is empty!')
- else begin
- Pop S.item
- temp S
- S S.next
- dispose(temp)
- end
- end
105Linked list implementation StackTop
- function StackTop(S Stack) ItemType
- Returns the top item of the stack S without popp
ing the stack - begin
- if IsEmptyStack(S) then
- writeln('Stack is empty!')
- else
- StackTop S.item
- end
106Application of stacks Infix, prefix and postfix
notations
- An arithmetic expression may be written in
different forms. - Most programming languages (including Pascal) use
infix notation. With infix notation, the
operators are placed between their operands
(e.g., 1 2, a b). - The operators have their own precedence. If
low-precedence operations are to be evaluated
first, parentheses () are required.
107Application of stacks Infix, prefix and postfix
notations
- Some programming languages (such as LISP) use
prefix notation. With prefix notation, the
operators precedes their operands (e.g., 1 2,
a b).
108Application of stacks Infix, prefix and postfix
notations
- Some other programming languages (such as FORTH)
use postfix notation (also called Reverse Polish
Notation). With postfix notation, the operators
are preceded by their operands (e.g., 1 2 ,
a b ). - With prefix and postfix notations, there is no
precedence associated with operators. The order
of evaluation solely depends on the order of the
operators placed. - Postfix notation is well suited for stack-based
computer architectures.
109Evaluating an expression in postfix notation
using a stack
- var
- x, x1, x2 token
- S Stack
- begin
- CreateStack(S)
- x NextToken(e)
- while x ltgt EndOfExpression do begin
- if x in OpSet then begin
- x2 Pop(S)
- x1 Pop(S)
- Push(x1 op(x) x2, S)
- end
- else
- Push(x, S)
- end
- EvaulatePostfix Pop(s)
- end
- e be an expression in postfix notation,
- OpSet be the set of all operators (e.g., , -, ,
/), - NextToken(e) be a function which returns the next
operand or operator to be processed, and - op(x) be the operation related to the operator x.
110Postfix notation example
Take the following postfix expression as an
example 2 3 5 9 7 -
Hence, the result of the expression is 18.
111Converting an infix expression to a postfix
expression (1)
- function Postfix(e InfixExpression) PostfixExpre
ssion - var
- x, y token S Stack P PostfixExpression
- begin
- CreateStack(S)
- InitializePostfixExpression(P)
- Push(DummyOperator, S)
- x NextToken(e)
-
-
112Converting an infix expression to a postfix
expression (2)
- while x ltgt EndOfExpression do begin
- if IsOperand(x) then ConcatenatePostfixExpre
ssion(P, x) - else if x ')' then
- repeat
- y Pop(S)
- ConcatenatePostfixExpression(P, y)
- until y '('
- else begin
- while InStackPriority(StackTop(S)) gt InComi
ngPriority(x) do - begin
- y Pop(S)
- ConcatenatePostfixExpression(P, y)
- end
- Push(x, S)
- end
- x NextToken(e)
- end
-
113Converting an infix expression to a postfix
expression (3)
- while not IsEmptyStack(S) do
- ConcatenatePostfixExpression(P, Pop(S))
- Postfix P
- end
- Assumption
- In-stack priority (InStackPriority) and in-coming
priority (InComingPriority) are shown below
114Queues
- A queue is a data structure for storing items
which are to be accessed in first-in- first-out
(FIFO) order.
Dequeue remove an item from the front.
Enqueue insert an item at the rear.
115Queue Application
- The operating system of a computer maintains a
queue for each resource to be accessed by
multiple demands. - E.g. print queue, a queue of processes to use
the CPU, interrupt handler, etc.
116Most common operations
- CreateQueue(S) to create a new (empty) queue Q,
- Enqueue(x, Q) to insert a new item x at the
rear of the queue Q, and - Dequeue(Q) to remove the first item at the
front of the queue Q (and returns the removed
item). - QueueFront(Q) returns the first item of the
queue Q, - QueueRear(Q) returns the last item of the queue
Q, - IsEmptyQueue(Q) returns whether the queue Q is
empty, - IsFullQueue(Q) returns whether the queue Q is
full.
117Array implementation - not a very good one
- We may use an array to implement a queue, the
first entry being the front and the last entry
being the rear. We need a variable to keep track
of the rear position. - type
- Queue record
- item array1..max of ItemType
- rear 0..max
- end
-
- procedure CreateQueue(var Q Queue)
- Initialises the queue Q
- begin
- Q.rear 0
- end
118Array implementation IsEmptyQueue and
IsFullQueue
- function IsEmptyQueue(Q Queue) boolean
- Checks whether the queue Q is empty
- begin
- IsEmptyQueue (Q.rear 0)
- end
-
- function IsFullQueue(Q Queue) boolean
- Checks whether the queue Q is full
- begin
- IsFullQueue (Q.rear max)
- end
119Array implementation Enqueue
- procedure Enqueue(x ItemType var Q Queue)
- Adds one item x at the rear of the queue Q
- begin
- if IsFullQueue(Q) then
- writeln('Cannot enqueue Queue is full!')
- else
- with Q do begin
- rear rear 1
- itemrear x
- end
- end
120Array implementation Dequeue
- function Dequeue(var Q Queue) ItemType
- Returns the item at the front of the queue Q and
removes it - var
- i 0..max
- begin
- if IsEmptyQueue (Q) then
- writeln('Cannot dequeue Queue is empty!'
) - else
- with Q do begin
- Dequeue item1
- for i 2 to rear do
- itemi - 1 itemi
- rear rear - 1
- end
- end
121Array implementation QueueFront and QueueRear
- function QueueFront(Q Queue) ItemType
- Returns the item at the front the queue Q
- begin
- if IsEmptyQueue(Q) then
- writeln('Queue is empty!')
- else
- QueueFront Q.item1
- end
-
- function QueueRear(Q Queue) ItemType
- Returns the item at the rear the queue Q
- begin
- if IsEmptyQueue(Q) then
- writeln('Queue is empty!')
- else
- QueueFront Q.itemQ.rear
- end
122Modified array implementation
- In order to be time efficient, shifting should be
avoided. We can use one more variable to keep
track of the front position. - Type
- Queue record
- item array1..max of ItemType
- front, rear 0..max
- end
123Modified array implementation -CreateQueue
- procedure CreateQueue(var Q Queue)
- Initialises the queue Q
- begin
- Q.front 1
- Q.rear 0
- end
124Modified array implementation IsEmptyQueue and
IsFullQueue
- function IsEmptyQueue(Q Queue) boolean
- Checks whether the queue Q is empty
- begin
- IsEmptyQueue (Q.rear0) and (Q.front1)
- end
- function IsFullQueue(Q Queue) boolean
- Checks whether the queue Q is full
- begin
- IsFullQueue ((Q.rear 1 Q.front) and
(Q.rear ltgt 0)) or ((Q.front 1) and (Q.rear
max)) - end
125Modified array implementation Enqueue
- procedure Enqueue(x ItemType var Q Queue)
- Adds one item x at the rear of the queue Q
- begin
- if IsFullQueue(Q) then
- writeln('Cannot enqueue Queue is full!')
- else
- with Q do begin
- if rear max then
- rear 1
- else
- rear rear 1
- itemrear x
- end
- end
126Modified array implementation Dequeue
- function Dequeue(var Q Queue) ItemType
- Returns the item at the front of the queue Q and
removes it - var
- i 0..max
- begin
- if IsEmptyQueue (Q) then
- writeln('Cannot dequeue Queue is empty!'
) - else
- with Q do begin
- Dequeue itemfront
- if front rear then begin
- front 1 rear 0
- end
- else if front max then
- front 1
- else front front 1
- end
- end
127Linked list implementation
- type
- NodePtr node
- node record
- item ItemType
- next NodePtr
- end
-
- Queue record
- front, rear NodePtr
- end
128Linked list implementation - CreateQueue
- procedure CreateQueue(var Q Queue)
- Initialises the queue Q
- begin
- Q.front nil
- Q.rear nil
- end
129Linked list implementation - IsEmptyQueue
- function IsEmptyQueue(Q Queue) boolean
- Checks whether the queue Q is empty
- begin
- IsEmptyQueue (Q.front nil) and (Q.rear n
il) - end
130Linked list implementation - Enqueue
- procedure Enqueue(x ItemType var Q Queue)
- Adds one item x at the rear of the queue Q
- var
- temp NodePtr
- begin
- new(temp)
- temp.item x
- temp.next nil
- if IsEmptyQueue(Q) then
- Q.front temp
- else
- Q.rear.next temp
- Q.rear temp
- end
131Linked list implementation - Dequeue
- function Dequeue(var Q Queue) ItemType
- Returns the item at the front of the queue Q and
removes it - var temp NodePtr
- begin
- if IsEmptyQueue(Q) then
- writeln('Queue is empty!')
- else begin
- Dequeue Q.front.item
- temp Q.front
- Q.front temp.next
- if Q.front Q.rear then
- Q.rear nil
- dispose(temp)
- end
- end.
132Linked list implementation - QueueFront
- function QueueFront(Q Queue) ItemType
- Returns the item at the front the queue Q
- begin
- if IsEmptyQueue(Q) then
- writeln('Queue is empty!')
- else
- QueueFront Q.front.item
- end
133Linked list implementation - QueueRear
- function QueueRear(Q Queue) ItemType
- Returns the item at the rear the queue Q
- begin
- if IsEmptyQueue(Q) then
- writeln('Queue is empty!')
- else
- QueueRear Q.rear.item
- end
134Trees
- A tree is a data structure accessed beginning at
the root node. Each node is either a leaf or an
interior node. An interior node has one or more
child nodes and is called the parent of its child
nodes.
135Trees
- A tree with no nodes is called a null tree.
- A tree which is not null has one and only one
root. The root has no parent. Each of the other
nodes has one parent only. - Each node in a tree can have any number of
children. Those nodes which have no children are
called leaves. - The nodes which have the same parent are called
siblings. - Each child of any node can be considered as the
root of the corresponding subtree.
136Trees
- The degree of a node is the number of children
(or subtrees) it has got. - If Ni, Ni 1, , Nj is a sequence of nodes in
a tree such that Nk is the parent of Nk 1 for
i ? k lt j, the sequence is called the path from
Ni to Nj. - Let p be the number of nodes in the path Ni to
Nj. The length between Ni and Nj is (p 1). - The depth of a leaf is the length between the
root and that leaf. - The height of a tree is the maximum depth among
the leaves. - The ancestors of a node are those nodes (except
itself) which appear in the path from the root to
itself. - Suppose that a node has m ancestors. The level of
that node is (m 1).
137Tree Exercise
N-1 3 A B, F, G, D, I, J, K E, H, K Not exist A,
E, H 3 B, C, D, E E B, D, E
- A tree with n nodes has edges.
- Its height is .
- The root is .
- The leaves are .
- The path between E and K is .
- The path between C and K is .
- The ancestors of K are .
- The level of H is .
- The children of A are .
- The parent of H is .
- The siblings of C are .
138Application of trees
- implementing directory structures in file
systems, - search trees in artificial intelligence,
- syntax trees in programming languages, etc.
139Implementation of trees
- It is obvious to use pointers to implement a
tree. - we can define two pointer fields in a tree node
one for the first child (the leftmost one) and
the other for the right sibling
140Implementation of trees
- Thus, the tree shown on the left can be
implemented as follows
141Binary trees
- A binary tree is a tree in which each node has at
most two children (or subtrees). We often
identify the children of a node as left child and
right child. - A full binary tree has no nodes with only one
child, i.e. each node has either no children or
two children. - A perfect binary tree is a full binary tree in
which all leaves have the same depth. A perfect
binary tree of height h has 2h 1 1 nodes, of
which 2h are leaves.
142Pointer implementation of binary trees
- type
- TreeNode Node
- Node record
- item ItemType
- LChild, RChild NodePtr
- end
- var
- T TreeNode
Here LChild and RChild are pointers to the left
child (or left subtree) and right child (or right
subtree) respectively. T can be considered as a
pointer to a binary tree. There is no definite
way to construct a binary tree.
143Binary tree traversals
- Inorder traversal
- Traverse the left subtree of the root by inorder
traversal - Visit the root
- Traverse the right subtree of the root by inorder
traversal - Preorder traversal
- Visit the root
- Traverse the left subtree of the root by inorder
traversal - Traverse the right subtree of the root by inorder
traversal - Postorder traversal
- Traverse the left subtree of the root by inorder
traversal - Traverse the right subtree of the root by inorder
traversal - Visit the root
144Binary tree traversals Exercise
B, F, A, D, C, G, E
- Inorder traversal
- Preorder traversal
- Postorder traversal
A, B, F, C, D, E, G
F, B, D, G, E, C, A
145Inorder traversal
- procedure Inorder(T TreeNode)
- begin
- if T ltgt nil then begin
- Inorder(T.LChild)
- write(T.item)
- Inorder(T.RChild)
- end
- end
146Preorder traversal
- procedure Preorder(T TreeNode)
- begin
- if T ltgt nil then begin
- write(T.item)
- Inorder(T.LChild)
- Inorder(T.RChild)
- end
- end
147Postorder traversal
- procedure Postorder(T TreeNode)
- begin
- if T ltgt nil then begin
- Inorder(T.LChild)
- Inorder(T.RChild)
- write(T.item)
- end
- end
148Array implementation of binary trees
- We can also use an array to implement a binary
tree. Since there at most (2h 1 1) nodes in a
binary tree with height h (as in a perfect binary
tree), the minimum number of entries in the array
used for implementing the binary tree should be
2h 1 1. - declaration
- type
- BinTree array1..max of ItemType
- var
- T BinTree
149Rules for storing the contents of the tree nodes
- The root is stored at T1.
- If a node is stored at Ti, then its left child
is stored at T2 i and its right child is
stored at T2 i 1. - The unused entries must be cleared (or assigned
appropriate values to indicate that those entries
are not used).
150Questions
- Given a node Tj which is not the root. Where is
its parent stored? - Show how an array can be used to implement the
binary tree
Tj div 2
151Array implementation of Binary Trees Declaration
- const
- max 15
- NULL ' '
- type
- ItemType char
- BinTree array1..max of ItemTy