Survey							
                            
		                
		                * Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Lesson 12 — Stacks and Lists
Microsoft Visual Basic
.NET, Introduction to
Programming
1
Objectives
2
Use the Stack collection defined in
System.Collections.
Write a stack-based program to evaluate an
expression in postfix notation.
Parse an input string.
Define and use a Stack class.
Use the Queue collection defined in
System.Collections.
Define and use a Linked List class.
Traverse a linked list recursively.
Add nodes to a linked list in order.
Vocabulary
3
Body
Constructor
Infix notation
Linked list
Parse
Peek
Pop
Postfix notation
Push
Queue
Stack
Traversal
Stacks
4
A stack is a first-in, last-out way of organizing data so that only
the top element is accessible. If a, b, and c are pushed onto a
stack, only the last element, c, is accessible. For element b to
reach the top of the stack, element c must be removed.
Putting an element onto the top of the stack is called a push.
Removing an element from the top of a stack is called a pop.
Imagine a stack as a spring-loaded stack of cafeteria trays. The
last tray, washed and put on the top of the stack, is the first tray
removed from the stack. The first tray pushed onto the stack is
buried at the bottom and is the last tray to be removed.
To read the top element of a stack without removing it, a peek
is used.
Creating a New Stack Collection
The Stack collection is built into the
System.Collections library of Visual Basic. The
procedure or method used to create a new instance
of a class is called a constructor. The constructor in
Visual Basic is the New method. There are three
ways to use the New method to create a new
instance of the Stack class. The line that follows
creates a new instance of a stack with a default
capacity of 10 objects. The parentheses are
automatically supplied and can be omitted when
entering the line.
Dim StackOne As New Stack()
5
The
StackDemonstration
Project Showing the
Final Placement of
Controls
6
Step-by-Step 12.1
At the top of the Code window, just below the
line Inherits System.Windows.Forms.Form,
add the following line to create an instance of
the Stack class — StackOne has an initial
default capacity of 10 objects:
Dim StackOne as New Stack()
7
Step-by-Step 12.1
StackOne.Push(txtEnter.Text)
StackOne.Push(txtEnter.Text)
txtEnter.ResetText()
txtEnter.Focus()
MessageBox.Show(StackOne.Peek, "Top of
Stack")
8
Step-by-Step 12.1
Dim x As Integer
For x = 1 To StackOne.Count
lstDisplay.Items.Add(StackOne.Pop)
Next
9
Appearance of the Application after
You Click the Display Button
10
Note
There are two ways to code so the run-time
error does not occur. One way is to prevent
the error by never peeking a value if the
stack is empty. If StackOne.Count is 0, the
stack is empty and the Peek method should
not be executed. Another way is to handle
the error with a Try-Catch-End Try statement.
11
Step-by-Step 12.1
If StackOne.Count <> 0 Then
MessageBox.Show(StackOne.Peek, "Top
of Stack")
Else
MessageBox.Show("The stack is empty.")
End If
12
Postfix and Infix Notation
13
Postfix notation is a way to write an arithmetic
expression where the binary operators (like +, -, *, /)
are behind the operands instead of between them.
For instance, the infix expression a + b, expressed in
postfix notation, becomes a b +. Although, at first,
postfix notation seems useless and at least a little
strange, it is quite useful. Translating a normal
expression into postfix notation is easy once you
have had a little practice.
Normal expressions use infix notation. An
expression written with infix notation places the
operators between the operands, for example, a + b.
Note
When an infix expression is correctly
translated to a postfix expression, the
operands will be in exactly the same order,
although it is possible to have an equivalent
expression where the operands are not in the
original order.
14
Parsing
To parse an input string means to interpret
the string entered by the user into data and
instructions.
15
Parsing an Input String
16
The rules for parsing the input string are easy.
First, if a character from the input string is part of a
numeric constant (a number), read the remaining
digits, convert to a number, and push the result on a
stack.
If the character represents an operator, pop the top
of the stack. This first value popped from the stack is
the second operand. Pop the stack again to read the
first operand. Apply the operator to the two values
and push the result back on the stack.
The Split Method
The String class, used to instantiate strings in a
program, has a very helpful method called Split. The
Split method divides a string into pieces and puts
each piece into an array. The separator character,
the character that separates one piece of the
command from another in the input string, can be
specified as a parameter in the Split method. If the
separator character is not specified, the space
character is assumed to be the separator.
17
Final Placement of Controls for the
ExpressionEvaluator Application
18
Step-by-Step 12.2
Dim OperandStack As New Stack()
Dim Operand, FirstOperand, SecondOperand,
Result As Double
Dim InputString As String = txtInputExpr.Text
Dim SubStringArray() As String = InputString.Split
Dim SubString As String
Dim i As Integer
19
Step-by-Step 12.2
For i = 0 To SubStringArray.Length - 1
' MessageBox.Show(SubStringArray(i).ToString)
Try
SubString = SubStringArray(i)
Operand = CDbl(SubString)
' MessageBox.Show("Value:" & Operand)
OperandStack.Push(Operand)
20
Step-by-Step 12.2
Catch
' MessageBox.Show("operator:" & SubString)
Select Case SubString
Case "+"
SecondOperand = OperandStack.Pop
FirstOperand = OperandStack.Pop
Result = FirstOperand + SecondOperand
OperandStack.Push(Result)
21
Step-by-Step 12.2
Case "."
MessageBox.Show(OperandStack.Pop)
End Select
End Try
Next
22
Note
23
Scattered throughout the code are three
MessageBox.Show statements. These are
commented out so they will not execute when the
button is clicked. They are positioned and built to
either debug or illustrate the operation of the code. If
the code did not work, you could remove the single
quote characters that turn the message boxes into
comments and, when the button was clicked,
messages would appear to let you know what was
going on as the code executes. You may also want
to remove the single quotes if you just want to see
what is happening as the code executes. You can
always put the single quote characters back in or
delete the lines with the extra message boxes.
Run-Time Error
24
Note
25
Now that you know what kind of errors can occur,
you should think about how you would modify the
code to trap them before incorrect values are
displayed. An obvious modification is to add Case
statements to handle other operators and a branch
to stop processing if an unrecognized character is
encountered. While thinking about adding additional
operators, you should think about the things that you
have to do no matter what the operator is. For each
operator, you must pop two values from the stack.
Once the operator is applied and the result is
obtained, the result must be pushed onto the stack.
These common operators can be factored out as
shown in the code.
Step-by-Step 12.2
Select Case SubString
Case "+", "-", "*", "/"
Try
SecondOperand = OperandStack.Pop
FirstOperand = OperandStack.Pop
Catch
MessageBox.Show("Error in expression.")
Exit Sub
End Try
26
Step-by-Step 12.2
Select Case SubString
Case "+"
Result = FirstOperand + SecondOperand
Case "-"
Result = FirstOperand - SecondOperand
Case "*"
Result = FirstOperand * SecondOperand
Case "/"
Result = FirstOperand / SecondOperand
End Select
OperandStack.Push(Result)
27
Step-by-Step 12.2
Case "."
MessageBox.Show(OperandStack.Pop)
Case Else
MessageBox.Show("Unrecognized
character:" & SubString)
Exit Sub
End Select
28
Implementing a Stack Class
If you really want to understand a data structure and learn how
it works, you should build one yourself. The built-in Stack class
works well, as you have seen in the previous two sections, but
you may have no idea how it works. Actually, not knowing how
something works internally is a good thing: that is the point of
writing and using classes to build objects. It is not necessary to
know how the Stack class works to use it.
29
One way to implement a Stack class is to use an array to store
the data and a pointer to the top of the array to indicate the top
of the stack. Normally, access to any element of an array is
possible. But in the Stack class, the array is declared as a
private variable, accessible only from within the class. Access
to the stack is limited to use of Public procedures for push and
pop.
Note
It is always possible to write code to increase the
capacity of a stack by using ReDim Preserve to
change the size of the array that holds the values in
the stack, but every time ReDim is executed, a new
array is created and the elements of the old array
are transferred to the new one. This process takes
time. It is always better (but sometimes difficult) to
declare an array that is just big enough to hold the
data, but not so big as to waste memory.
30
Add New Item Dialog Box Showing the
Creation of the ArrayStack Class
31
Step-by-Step 12.3
Dim StackBody()
Dim TopOfStack As Integer
Public ReadOnly SizeOfStack As Integer
Public Sub New(ByVal Dimension As Integer)
ReDim StackBody(Dimension)
TopOfStack = 1
SizeOfStack = Dimension
End Sub
32
Step-by-Step 12.3
Public Sub New()
ReDim StackBody(10)
TopOfStack = 1
SizeOfStack = 10
End Sub
33
Step-by-Step 12.3
Public Sub Push(ByVal Item)
If TopOfStack <= SizeOfStack Then
StackBody(TopOfStack) = Item
TopOfStack += 1
Else
MessageBox.Show("Stack is full")
End If
End Sub
34
Note
The compiler recognizes the two New
procedures as different because the
parameters are different for each. A third or
fourth New procedure could be defined by
adding more parameters or changing the
data type of an existing parameter.
35
The Form of the Creating a Stack Class
Application
36
Step-by-Step 12.3
Dim StackOne As New ArrayStack(20)
Dim StackTwo As New ArrayStack()
Dim Item = txtItem.Text
StackOne.Push(Item)
StackTwo.Push(Item)
txtItem.ResetText()
txtItem.Focus()
37
Step-by-Step 12.3
Public Function Pop()
If TopOfStack > 1 Then
TopOfStack -= 1
Return StackBody(TopOfStack)
Else
MessageBox.Show("Stack is empty")
End If
End Function
38
Step-by-Step 12.3
Public Function Peek()
If TopOfStack > 1 Then
Return StackBody(TopOfStack - 1)
Else
MessageBox.Show("Stack is empty")
End If
End Function
39
The Form of the
Creating a Stack
Class Application
Showing Buttons
for Peek and Pop
40
Step-by-Step 12.3
MessageBox.Show("Stack One:" & StackOne.Pop)
MessageBox.Show("Stack Two:" & StackTwo.Pop)
MessageBox.Show("Stack One:" & StackOne.peek)
MessageBox.Show("Stack Two:" & StackTwo.Peek)
41
Programming Skills
Writing programs for a class can be much different from writing
programs professionally. Programs written for a class are
typically run a few times, printed, and discarded. A program
written for a real application, whether or not you are paid for the
application, has quite a different lifetime. For one, you cannot
assume that you will be the only one to ever read the program
code. If your program serves an ongoing need, it may be in use
long after you have left the scene. To help that unknown
programmer of the future, document your code. Do not use
tricks or shortcuts in your code. Believe it or not, you may forget
your own tricks after a month or two. Make sure there are
backup copies and print out the documentation along with
directory information.
42
Step-by-Step 12.4
Public Function CopyToArray() As Object()
Return StackBody
End Function
43
Step-by-Step 12.4
Public ReadOnly Property stCount()
Get
Return TopOfStack - 1
End Get
End Property
44
Historically Speaking
In March 1988, Microsoft bought a set of
visual tools designed by Alan Cooper to
customize the Windows interface. The tools
were called Tripod. By 1991, the QuickBasic
language was integrated with the tools and
Visual Basic was introduced at the Windows
World trade show.
45
CreateAStackClass Application
Showing Final Placement of Controls
46
Step-by-Step 12.4
Dim Local() = StackOne.CopyToArray
Dim i As Integer
lstDisplay.Items.Clear()
For i = 1 To StackOne.stCount
lstDisplay.Items.Add(Local(i))
Next
47
The Using a Custom Stack Class
Application
48
Queues
A queue is a data structure that stores a list of
values with access granted to both the front and
back of the list. But access at the front of the list is
limited to removal of an item, and access at the back
of the list is limited to the addition of an item. You
can liken this kind of data structure to the line you
might stand in while you wait for a teller at a bank or
to the line an airplane must sit in when it is waiting to
take off.
49
The Queue Simulation Project Showing
the Final Placement of Controls
50
Step-by-Step 12.5
Add the following declarations below the
Inherits line:
Dim CustomersPerHour As Integer
Dim ServedPerHour As Integer
51
Step-by-Step 12.5
Private Function Arrival() As Boolean
'chance of arrival per minute: CustomersPerHour/60
If Rnd() <= CustomersPerHour / 60 Then
Return True
Else
Return False
End If
End Function
52
Step-by-Step 12.5
Private Function Served() As Boolean
Return Rnd() <= ServedPerHour / 60
End Function
Private Function QueueEmpty(ByVal Q As
Queue) As Boolean
Return Q.Count = 0
End Function
53
Step-by-Step 12.5
Dim LineUp As New Queue(70)
Dim Minutes, WaitTime As Integer
Dim TotalMinWaited As Integer = 0
Dim Customers As Integer = 0
Dim WorkerBusy As Boolean = False
CustomersPerHour = CInt(txtCustPerHour.Text)
ServedPerHour = CInt(txtServedPerHour.Text)
54
Step-by-Step 12.5
For Minutes = 1 To 8 * 60
If Arrival() Then
Customers += 1
If WorkerBusy Then
LineUp.Enqueue(Minutes)
Else
WorkerBusy = True
End If
End If
55
Step-by-Step 12.5
If WorkerBusy AndAlso Served() Then
If Not QueueEmpty(LineUp) Then
WaitTime = Minutes - LineUp.Dequeue
TotalMinWaited += WaitTime
WorkerBusy = True
Else
WorkerBusy = False
End If
End If
Next
56
Step-by-Step 12.5
lstDisplay.Items.Add("Average wait time: " & _
Format(TotalMinWaited / Customers, "Fixed"))
lstDisplay.Items.Add("Still waiting to be served: " & _
LineUp.Count)
lstDisplay.Items.Add("Total customers: " & _
Customers)
57
Linked List
A linked list is another kind of data structure used to
organize and store data in a list. Unlike an array that
reserves a block of memory and stores data together
in the same memory block, a linked list is composed
of nodes that exist anywhere at all in memory.
Each element of a linked list is called a node. Each
node has a data area and a link that points to the
next element in the list. New nodes are created only
when they are needed. They take only as much
memory as necessary to contain the data that is
already stored.
58
Step-by-Step 12.6
Public Data As Object
Public Link As ListNode
Public Sub New()
Data = "empty"
Link = Nothing
End Sub
59
Step-by-Step 12.6
60
Public Sub AddItemTop(ByRef LN As ListNode, ByVal Obj As
Object)
If LN.Data = "empty" Then
LN.Data = Obj
Exit Sub
End If
Dim TempNode As New ListNode()
With TempNode
.Data = Obj
.Link = LN
End With
LN = TempNode
End Sub
Step-by-Step 12.6
Public Sub Transversal(ByVal LN As ListNode)
If Not LN Is Nothing AndAlso LN.Data <>
"empty" Then
MessageBox.Show(LN.Data)
Transversal(LN.Link)
End If
End Sub
61
Step-by-Step 12.6
Dim LListStack As New ListNode()
Dim LListInOrder As New ListNode()
Dim Obj
Obj = InputBox("Enter an object:")
LListStack.AddItemTop(LListStack, Obj)
LListStack.Transversal(LListStack)
62
Step-by-Step 12.6
Public Sub AddInOrder(ByRef LN As ListNode, ByVal Obj As Object)
If LN.Data = "empty" Then ' the list is empty
LN.Data = Obj
Exit Sub
End If
' list is not empty
Dim TempNode As New ListNode()
TempNode.Data = Obj
If Obj < LN.Data Then ' new first node
TempNode.Link = LN
LN = TempNode
Exit Sub
End If
63
Step-by-Step 12.6
Dim Pointer, TrailPointer As ListNode
Pointer = LN.Link
TrailPointer = LN
Do While Not Pointer Is Nothing
' more to check
If Obj < Pointer.Data Then
' we found the spot
TempNode.Link = Pointer
TrailPointer.Link = TempNode
Exit Sub
64
Step-by-Step 12.6
Else
TrailPointer = Pointer
Pointer = Pointer.Link
End If
Loop
' if we get here, insert at end of list
TempNode.Link = Nothing
TrailPointer.Link = TempNode
End Sub
65
Step-by-Step 12.6
Dim Obj
Obj = InputBox("Enter an object:")
LListInOrder.AddInOrder(LListInOrder, Obj)
LListInOrder.Transversal(LListInOrder)
66
Step-by-Step 12.6
Public Sub Remove(ByRef LN As ListNode)
If LN.Data = "empty" Then
Exit Sub
End If
If Not LN.Link Is Nothing Then
Dim Temp As ListNode
Temp = LN
LN = LN.Link
Temp = Nothing
Else ' there is only one node left
LN.Data = "empty"
End If
End Sub
67
Step-by-Step 12.6
LListInOrder.Remove(LListInOrder)
68
Historically Speaking
The earliest versions of the BASIC programming language were quite
different than the Visual Basic of today. Many of the statements we
take for granted did not exist in the original versions. There was no IfThen-Else statement. There was no indefinite (Do-While) loop. There
was no ReDim statement and no New statement. In the original
versions of BASIC, you had to completely anticipate the amount of
memory needed to store information. You could Dim an array to a
specific size at the beginning of the program, but you could never
change the size of the array once it was established. You could not
create a new instance of a data structure with the keyword New. In
fact, there were no data structures beyond what you could create with
an array or with variables.
The ability to claim free memory as needed to create new data
structures or ReDim an array is called Dynamic Memory Allocation.
Early versions of BASIC had only Static Memory Allocation: all claims
for free memory had to be made when the program first started.
69
Summary
70
A stack is a first-in, last-out data structure. You can only access
a stack by pushing or popping the item at the top of the stack. It
is extensively used below the surface of programming
languages to translate infix to postfix expressions, evaluate
postfix expressions, and support jumping from one code
segment to another and back.
The Stack class definition, part of the System.Collections
library, is used to create stack data structures in application
programs. It supports push, pop, and peek access to the top
element of the stack.
A Stack class can be implemented using an array to hold the
items in the stack and a variable that points at the next place in
the stack to be filled with information. All access to the stack
comes through manipulating this pointer.
Summary
71
New instances of a class definition are created with the New
method. This method is called a constructor.
Postfix notation builds expressions by placing binary operators
after the operands instead of between them. An example is a b
+. The notation that places the operator between the operands,
a + b, is called infix notation.
Parsing an input string is taking it apart and recognizing the
commands and data contained in the string. The Split method
of the String type makes parsing easy by taking a string and
returning each part separated by spaces as elements of an
array. Once in the array, the separate parts can be examined
and processed.
Summary
72
A queue is a first-in, first-out data structure. A
class definition for a queue class is found in
System.Collections. It supports Enqueue
(add to the queue) and Dequeue (remove
from the queue) operations. Queues are
useful for simulations.
To simulate an event of probability p, where
0 < p < 1, use the statement: If Rnd() <= p
Then.
Summary
73
A linked list is composed of nodes, each with two
fields: one field contains the node’s data; the other
field contains a pointer that points to the next node in
the list. An advantage of the linked list over an array
is that a linked list uses only the amount of memory
needed to store the information, while an array has
to reserve a block of memory whether it is entirely
used or not. A disadvantage of the linked list is that
the pointers only point in one direction: you can start
at the head of the list and traverse the list from front
to back, but you cannot back up.