Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
33 views

Binary Search Tree & Priority Queue

The document provides instructions for students to implement a binary search tree (BST) and priority queue data structures in Java. It includes definitions, explanations of common BST operations like insertion, deletion and searching, and steps for students to create a Java project and class to implement a BST with examples.

Uploaded by

Yi Yin
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
33 views

Binary Search Tree & Priority Queue

The document provides instructions for students to implement a binary search tree (BST) and priority queue data structures in Java. It includes definitions, explanations of common BST operations like insertion, deletion and searching, and steps for students to create a Java project and class to implement a BST with examples.

Uploaded by

Yi Yin
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 39

FAKULTI TEKNOLOGI

KEJURUTERAAN KELAUTAN
DAN INFORMATIK

2019/2020

DATA STRUCTURE & ALGORITHM

Lab 7: Binary
Search Tree &
Priority Queue

VERSION 1
STUDENT INFORMATION

PLEASE FILL IN YOUR DETAILS:

NAME: TEOH YI YIN

MATRIC NUMBER:S58798

GROUP:K3

LAB:CISCO

DATE:21/12/2021

i
TABLE OF CONTENTS
INSTRUCTIONS .......................................................................................................................... 1
TASK 1: Implementing Binary Search Tree (BST) ...................................................................... 2
TASK 2: Implementing Priority Queue......................................................................................22

ii
INSTRUCTIONS

Manual makmal ini adalah untuk kegunaan pelajar-pelajar Fakulti Teknologi Kejuruteraan
Kelautan dan Informatik, Universiti Malaysia Terengganu (UMT) sahaja. Tidak dibenarkan
mencetak dan mengedar manual ini tanpa kebenaran rasmi daripada penulis.

Sila ikuti langkah demi langkah sebagaimana yang dinyatakan di dalam manual.

This laboratory manual is for use by the students of the Faculty of Ocean Engineering Technology
and Informatics, Universiti Malaysia Terengganu (UMT) only. It is not permissible to print and
distribute this manual without the official authorisation of the author.

Please follow step by step, as described in the manual.

1
TASK 1: IMPLEMENTING BINARY SEARCH TREE (BST)

OBJECTIVE

In this task, students must be able to:

• Understand the concept of Binary Search Tree (BST).


• Implement BST.

ESTIMATED TIME

[60 Minutes]

DEFINITION OF BINARY SEARCH TREE


Binary Tree : A data structure in which we have nodes containing data and two references to
other nodes, one on the left and one on the right.

Binary Tree consist of Nodes

▪ Nodes are nothing but objects of a class and each node has data and a link to the left
node and right node.

▪ Usually we call the starting node of a tree as root.

▪ Left and right node of a Leaf node points to NULL so you will know that you have reached
to the end of the tree.

2
Binary Search Tree:

Often we call it as BST, is a type of Binary tree which has a special property.

Nodes smaller than root goes to the left of the root and Nodes greater than root goes to the right of
the root.

Operations:

Insert(int n) : Add a node the tree with value n. Its O(lgn)

Find(int n) : Find a node the tree with value n. Its O(lgn)

Delete (int n) : Delete a node the tree with value n. Its O(lgn)

Display(): Prints the entire tree in increasing order. O(n).

3
Detail Explanations for the Operations:

Find(int n):

▪ Its very simple operation to perform.

▪ start from the root and compare root.data with n

▪ if root.data is greater than n that means we need to go to the left of the root.

▪ if root.data is smaller than n that means we need to go to the right of the root.

▪ if any point of time root.data is equal to the n then we have found the node, return true.

▪ if we reach to the leaves (end of the tree) return false, we didn’t find the element

Insert(int n):

▪ Very much similar to find() operation.

▪ To insert a node our first task is to find the place to insert the node.
4
▪ Take current = root .

▪ start from the current and compare root.data with n

▪ if current.data is greater than n that means we need to go to the left of the root.

▪ if current.data is smaller than n that means we need to go to the right of the root.

▪ if any point of time current is null that means we have reached to the leaf node, insert
your node here with the help of parent node. (See code)

Delete(int n):

Complicated than Find() and Insert() operations. Here we have to deal with 3 cases.

▪ Node to be deleted is a leaf node ( No Children).

▪ Node to be deleted has only one child.

5
▪ Node to be deleted has two childrens.

Node to be deleted is a leaf node ( No Children).

its a very simple case, if a node to be deleted has no children then just traverse to that node,
keep track of parent node and the side in which the node exist(left or right) and set parent.left
= null or parent.right = null;

Node to be deleted has only one child.

1. its a slightly complex case. if a node to be deleted(deleteNode) has only one child then
just traverse to that node, keep track of parent node and the side in which the node
exist(left or right).

2. check which side child is null (since it has only one child).

6
3. Say node to be deleted has child on its left side . Then take the entire sub tree from the
left side and add it to the parent and the side on which deleteNode exist, see step 1 and
example.

Node to be deleted has two children.

Now this is quite exciting

You just cannot replace the deleteNode with any of its child, Why? Lets try out a example.

7
What to do now?????

Dont worry we have solution for this

Find The Successor:

Successor is the node which will replace the deleted node. Now the question is to how to find it
and where to find it.

Successor is the smaller node in the right sub tree of the node to be deleted.

8
Display() : To know about how we are displaying nodes in increasing order, Click Here

Complete Example :

9
STEPS:
1. After you understand the explanation in the above section, open NetBeans and create a
new java application project.
2. Name your project as BinarySearchTreeExperiment and click finish.
3. Change author profiles to :
a. Name :
b. Program: <put your program. E.g., SMSK(SE) or SMSK with
IM
c. Course : CSF3104
d. Lab : <enter lab number>
e. Date : <enter lab date>
4. In the same BinarySearchTreeEXperiment project’s package, create a new file
named BinarySearchTree.java.
5. Add the following codes to the file:
Note: The codes below are quite long. Take your time to understand the codes and write your
own comment where applicable. This will help you to study the codes later.

10
11
12
13
14
6. Just after the end of BinarySearchTree class, add the Node class below it:

15
7. Save, compile and run your codes. Observe the output.
8. Upload your output using the control box below:

9. Copy and paste your Java codes into the text box below:
Answer:
package BinarySearchTreeExperiment;

/**
* @author
* Name: TEOH YI YIN
* Program: SMSK(SE)
* Course: CSF3104
* Lab: 7
* Date: 21/12/2021
*/

public class BinarySearchTree {


public static Node root;

public BinarySearchTree(){
this.root = null;
}

public boolean find(int id){


Node current = root;
while(current != null){
if(current.data == id){
return true;

16
}else if (current.data > id){
current = current.left;
}else{
current = current.right;
}
}
return false;
}

public boolean delete(int id){


Node parent = root;
Node current = root;
boolean isLeftChild = false;
while(current.data != id){
parent = current;
if(current.data > id){
isLeftChild = true;
current = current.left;
}else{
isLeftChild = false;
current = current.right;
}
if (current == null){
return false;
}
}

//Case 1: if node to be deleted has no children


if(current.left == null && current.right == null){
if (current == root){
root = null;
}
if (isLeftChild == true){
parent.left = null;
}else{
parent.right = null;
}
}

17
//Case 2: if node to be deleted has only one children
else if (current.right == null){
if(current == root){
root = current.left;
}else if (isLeftChild){
parent.left = current.left;
}else{
parent.right = current.left;
}
}else if (current.left == null){
if(current == root){
root = current.right;
}else if (isLeftChild){
parent.left = current.right;
}else{
parent.right = current.right;
}
}else if (current.left != null && current.right != null){
Node successor = getSuccessor(current);
if(current == root){
root = successor;
}else if (isLeftChild){
parent.left = successor;
}else{
parent.right = successor;
}
successor.left = current.left;
}
return true;
}

public Node getSuccessor(Node deleteNode){


Node successor = null;
Node successorParent = null;
Node current = deleteNode.right;
while (current != null){
successorParent = successor;
successor = current;

18
current = current.left;
}
//check if successor has right child
//if no, add it to left of successorParent
if (successor != deleteNode.right){
successorParent.left = successor.right;
successor.right = deleteNode.right;
}
return successor;
}

public void insert(int id){


Node newNode = new Node(id);
if(root == null){
root = newNode;
return;
}
Node current = root;
Node parent = null;
while (true){
parent = current;
if (id < current.data){
current = current.left;
if (current == null){
parent.left = newNode;
return;
}
}else{
current = current.right;
if (current == null){
parent.right= newNode;
return;
}
}
}
}

public void display(Node root){

19
if (root != null){
display(root.left);
System.out.print(" " + root.data);
display(root.right);
}
}

public static void main(String arg[]){


BinarySearchTree b = new BinarySearchTree();
b.insert(3);
b.insert(8);
b.insert(1);
b.insert(4);
b.insert(6);
b.insert(2);
b.insert(10);
b.insert(9);
b.insert(20);
b.insert(25);
b.insert(15);
b.insert(16);
System.out.println("Original Tree : ");
b.display(b.root);
System.out.println("");
System.out.println("Check whether Node with value 4 exists : " + b.find(4));
System.out.println("Delete Node with no children (2) : " + b.delete(2));
b.display(root);
System.out.println("");
System.out.println("Delete Node with no children (4) : " + b.delete(4));
b.display(root);
System.out.println("");
System.out.println("Delete Node with no children (10) : " + b.delete(10));
b.display(root);
System.out.println(""); }
}

class Node{
int data;

20
Node left;
Node right;

public Node(int data){


this.data = data;
left = null;
right = null;
}
}

QUESTIONS
1. Discuss the differences between General Tree and Binary Search Tree.
Answer:
Binary search tree only has maximum 2 chidren for each internal node while general
tree can have more than 2 children for each internal node.
Binary search tree can be empty while general trss can not be empty.
Binary search tree has mainly two subtree, left-subtree and right subtree. The left-
subtree has elements less than the nodes element and the right-subtree has elements
greater than the nodes element. While in general tree, there is either zero subtree or
many subtree.

2. What are the advantages of BST?


Answer:
Insertion and deletion operations are faster compared to array and linked lists.
Searching an elements is easier due to hint is given which subtree has the desired
element.

21
TASK 2: IMPLEMENTING PRIORITY QUEUE

OBJECTIVE

During this activity, students will learn and apply the concept of priority queue data structure.

ESTIMATED TIME

[60 Minutes]

INTRODUCTION
The priority queue is a somewhat similar data structure to the queue. The difference lies in how
the elements are being processed:

• A standard queue strictly follows the FIFO (First-In-Last-Out) principle.


• A priority queue does not follow the FIFO principle.

In a priority queue, the elements are being removed from the queue based on
their priority. This translates to the requirement that:

Every element in a priority queue must have a priority associated with it.

As you might have guessed, the element with the highest priority is removed from the queue
(dequeued).

But how do should you define the priority of the elements in the queue?

Basically, you have two alternatives for defining priorities to the elements in the queue. You
can either:

• Order elements based on their natural ordering.


• Order elements with a custom Comparator.

In this article, we'll focus on how to implement a priority queue. So for simplicity's sake, we'll
order the elements based on their natural ordering.

In our example, the priority queue will be limited to int, so natural ordering is perfectly fine.
However, keep in mind that this is for demonstration purposes only.

If you were to implement a priority queue in real life, you probably want to make use of
generics — or just do like any other developer and use the built-in java.util.PriorityQueue.

22
To keep our example implementation compliant with the Java specification, the least element
is defined as the element with the highest priority.

PRIORITY QUEUE OPERATIONS


The most basic set of operations for any implementation of a queue is:

enqueue — Inserting an element into the queue.

dequeue — Removing an element from the queue.

isEmpty — Returning true if the queue is empty.

size — Returning the size/number of elements in the queue.

contains — Returning true if the queue contains the given element.

peek — Returning the front element of the queue, without removing it.

Please note that the Java implementation of the priority queue uses different names for the
methods. In a production environment, I highly suggest that you use the default
implementation of the priority queue, instead of "home-growing" it.

Implementing Enqueue and Dequeue

First, let's think about what we want to happen if we insert/enqueue an element. Note that we
ignore the doubleArray method for now. We want inserted elements to be placed in the queue,
in the correct position, according to its priority.

23
This visualization of the enqueue operation tells us that we'll have to shift all elements of lower
priority one position up in the array.

STEPS:
1. Create a new Netbeans project. Name the project as PriorityQueueExperiment.
2. Create a new class named MyPriorityQueue.
3. In MyPriorityQueue.java, insert the following codes, again, try to understand the
codes and write your own comment:

24
25
26
27
4. Write a test class by completing the codes section below for MyPriorityQueue class:

5. Save, compile and execute your codes.


6. Upload your output using the control box below:

28
7. Copy and paste your Java codes from NetBeans into text box below:
package PriorityQueueExperiment;

/**
* @author
* Name: TEOH YI YIN
* Program: SMSK(SE)
* Course: CSF3104
* Lab: 7
* Date: 21/12/2021
*/
import java.util.NoSuchElementException;

public class MyPriorityQueue {


private int[] innerArray;
private int size;

public MyPriorityQueue(){
this.innerArray = new int[10];
size = 0;
}

public int[] getInnerArray(){

29
return innerArray;
}

public void enqueue(int x){


//if empty, insert at front
if(size == 0){
size++;
innerArray[0] = x;
return;
}
//if full, double the array
if (size() == innerArray.length){
doubleArray();
}
//looping through
int temp = x;
for (int i = 0; i < size; i++){
//if priority higher, valuesshift when value lower
if (x <= innerArray[i]){
int next;
temp = innerArray[i];
innerArray[i] = x;
//shifting
while (i < size-1){
next = innerArray[i+1];
innerArray[i+1] = temp;
temp = next;
i++;
}
break;
}
}
//placing, increasing size
innerArray[size] = temp;
size++;
}

public int dequeue(){

30
if(isEmpty()){
throw new NoSuchElementException("The queue is empty");
}
//storing first int for return
int retValue = innerArray[0];
//shift all values downwards
for (int i =1; i < size; i++){
innerArray[i-1] = innerArray[i];
}
innerArray[size-1]=0;
size--;
return retValue;
}

public int peek(){


if(isEmpty()){
throw new NoSuchElementException("The queue is empty");
}
return innerArray[0];
}

public boolean contains(int x){


//check for empty
if(isEmpty()){
return false;
}
//looping through the positions which contains inserted values
//ignoring trailing default 0 values
for (int i = 0; i < size; i++){
if(innerArray[i] == x){
return true;
}
}
return false;
}

public boolean isEmpty(){


return size == 0;

31
}

public int size(){


return size;
}

private void doubleArray(){


int[] newArr = new int[innerArray.length * 2];
for (int i = 0; i < innerArray.length; i++){
newArr[i] = innerArray[i];
}
innerArray = newArr;
}

void printArray() {
for (int i=0 ; i<size ; i++) {
System.out.print(innerArray[i] + " ");
}
System.out.println();
}
}

package PriorityQueueExperiment;

/**
* @author
* Name: TEOH YI YIN
* Program: SMSK(SE)
* Course: CSF3104
* Lab: 7
* Date: 21/12/2021
*/
import java.util.NoSuchElementException;

public class MyPriorityQueue {


private int[] innerArray;
private int size;

32
public MyPriorityQueue(){
this.innerArray = new int[10];
size = 0;
}

public int[] getInnerArray(){


return innerArray;
}

public void enqueue(int x){


//if empty, insert at front
if(size == 0){
size++;
innerArray[0] = x;
return;
}
//if full, double the array
if (size() == innerArray.length){
doubleArray();
}
//looping through
int temp = x;
for (int i = 0; i < size; i++){
//if priority higher, valuesshift when value lower
if (x <= innerArray[i]){
int next;
temp = innerArray[i];
innerArray[i] = x;
//shifting
while (i < size-1){
next = innerArray[i+1];
innerArray[i+1] = temp;
temp = next;
i++;
}
break;
}
}

33
//placing, increasing size
innerArray[size] = temp;
size++;
}

public int dequeue(){


if(isEmpty()){
throw new NoSuchElementException("The queue is empty");
}
//storing first int for return
int retValue = innerArray[0];
//shift all values downwards
for (int i =1; i < size; i++){
innerArray[i-1] = innerArray[i];
}
innerArray[size-1]=0;
size--;
return retValue;
}

public int peek(){


if(isEmpty()){
throw new NoSuchElementException("The queue is empty");
}
return innerArray[0];
}

public boolean contains(int x){


//check for empty
if(isEmpty()){
return false;
}
//looping through the positions which contains inserted values
//ignoring trailing default 0 values
for (int i = 0; i < size; i++){
if(innerArray[i] == x){
return true;
}

34
}
return false;
}

public boolean isEmpty(){


return size == 0;
}

public int size(){


return size;
}

private void doubleArray(){


int[] newArr = new int[innerArray.length * 2];
for (int i = 0; i < innerArray.length; i++){
newArr[i] = innerArray[i];
}
innerArray = newArr;
}

void printArray() {
for (int i=0 ; i<size ; i++) {
System.out.print(innerArray[i] + " ");
}
System.out.println();
}
}

QUESTIONS
1. List the differences between common Queue and Priority Queue.
Answer:
Common queue will follow FIFO principle while priority queue does not follow FIFO
priniple. In priority queue, elements are being removed from queue based on their priority.

35
2. In Java, there is a built-in class for PriorityQueue, how can you use it?

Answer:

1. import from util package.


import java.util. PriorityQueue;
2. create priority queue object.
PriorityQueue<int> pq = new PriorityQueue<>();
3. Add element in the queue
pq.add(3);
4. Returns front element in queue without removing it
pq.peek();
5. Returns and remove the front element in the queue
pq.poll();

3. What are the ADTs for PriorityQueue?

Answer:

1. enqueue(element) : inserts an element


2. dequeue: removes and returns front element in the queue
3. isEmpty(): returns true if queue is empty
4. size(): return size of elements in the queue
5. contains(element): return true if the queue contains the given element
6. peek(): returns front element without removing it

Finally, read the instruction regarding submission carefully. Submit your answer using the link
provided in Oceania UMT. Please ensure your codes are submitted to the correct group.

36

You might also like