0% found this document useful (0 votes)
12 views92 pages

FINAL CCS4 Notes - Chester

Uploaded by

rockstargilbey
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
12 views92 pages

FINAL CCS4 Notes - Chester

Uploaded by

rockstargilbey
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 92

CHESTER JORDAN

CCS 4
Study Guide Review
______________________________________________________________________

Header files and why do we need them?

#include <stdio.h> // input output // example scanf and printf


#include <conio.h> // conio. h stands for console input - output. It has many inbuilt
functions which are used to perform many input and output operations. Some of the builtin
functions are - clrscr(), getch(), getche(),gotoxy(),wherex(),wherey() and many more. Some
other functions used in conio.
#include <string.h> // h is a standard header file in the C language that contains
functions for manipulating strings (arrays of characters). <string. h> header file contains some
useful string functions that can be directly used in a program by invoking the #include
preprocessor directive.
#include <stdlib.h> // h is the header of the general purpose standard library of C
programming language which includes functions involving memory allocation, process control,
conversions and others. It is compatible with C++ and is known as cstdlib in C++.
#include <stdbool.h> // h allows you to use bool as a Boolean data type. true evaluates
to 1 and false evaluates to 0
#include <ctype.h> // The ctype.h header file of the C Standard Library declares several
functions that are useful for testing and mapping characters.
All the functions accept int as a parameter, whose value must be EOF or representable as an
unsigned char. All the functions return non-zero (true) if the argument c satisfies the condition
described, and zero(false) if not. Example:int isdigit

Aug 29, 2023


ARRAY
What's an array?
Collection of objects (the same data type)
You can't put data into an array if it has a diff data type

SYNTAX:
< data type > <array name> [<size>];
<size> = no. of data / number of pieces

<> []
Required / optional
Size of an array should be inside a square bracket
Example:
Int array[10] , [10] is literal values
Integer can hold 10 integers;
//Not a problem if your problem is very short , but you have to locate all of them

Float arr[10];
Float can hold 10 float;

#define s 10 // defining a constant


Int array1[s];
Int arr[s];
// All you have to do is change the constant, automatically changes the value
//If you have an Array always put inside the loop , you only need one statement rather
than making individual statements.

scanf , printf should always be in a loop.

Copying elements from one array to another

Copy one element at a time.


int x[s]; = { 5, 8, 10 , 3, 9};
int y[s];

Copy elements from array x to array y


for ( i = 0; i < s; i++)
y[i] = x[i];
// y = x will not work
Parameter passing
1. SYNTAX : Single element by value:
Calling function: <function name> (<indexed array name>);
Recipient function: <function name> (<data type> <ordinary variable>)
<data type> must be compatible with the array data type
Example:
void test(int num)
{
Num = num + 1;
printf(“%d”, num);
getch();
return;
}
#define s 5
void test (int); // data type is an integer

int main(void)
{
int arr [s] = { 3, 6, 2, 8, 10}, j ;
test (arr [2]); // index array is 2, the element to be passed is 2
for (j = 0; j < s; j++)
printf(“%d” , arr[j]);
return 0;
}

Pass array as a parameter, the whole array or the single value

Single value:
//You can pass it by value or pass it by reference
//Indexed = one value only
//Need only an ordinary variable , not an array

By value: The output is still 2, we passed it by value, when it goes back the
copy will be lost; // the output is 3 6 2 8 10

Single Value By reference:

Calling function: <function name> (&index array>); // need to be ampersand


Recipient function: <function name> (<data type> *ordinary variable) // need an
asterisk

Example:

#define s 5

void test (int *);


Int main (void)

{
int arr [s] = { 3, 6, 2, 8, 10}, j ;
test (&arr[2]);
for (j = 0; j < s; j++)
printf(“%d” , arr[j]);
return 0;
}

void test(int *num)


{
*num= *num + 3; // 2 + 3 = 5
printf(“%d”, *num);
getch();
return;
}

Asterisk = pointer , pointing to the 2 ( index )


2+3=5

//Go back to for loop


//And the output is 3 6 5 8 10 // take note of the difference , the value of the original is
still the same but with reference it will change.
//Without ampersand and asterisk the value will always stay the same

Pass the whole array

v25;
printf (“%d”, num[2]); // 25
getch();
}

#define s 5
void test (int []);
Int main (void)

{
int arr [s] = { 3, 6, 7, 5, 10}, j ;
test (arr) //
for (j = 0; j < s; j++)
printf(“%d” , arr[j]);
return 0;
}

Output: 3, 6, 25, 5, 10
Calling function: <function name> (<array name>); // the whole array
Recipient function: <function name> (<data type><array name>)

The size will adjust to the size of the array

Array = num , there is no problem, important is both should be in array

STRINGS
Array of Characters:
Declare a string is the same as declaring an array

SYNTAX: <data type> <string name> [<size>];


char

//char name [ 20 ];
//Can hold 19 characters
//0 - 18 will hold characters, the 20th or 19 will hold the backslash 0 = \0
//All strings in C end with backslash 0.

Initializing a string:
Syntax: char <string name> [size] = “string data” ;

Assigning data to a string : strcpy()


Syntax: strcpy(<destination> , <source>); // separated by comma, the data in the
source will be copied to the destination.
<source> can be another string variable or a literal string.

Example:
char name [30] = “Chester”;
char name2[30];
strcpy (name2, name);
printf(“%s” , name2) ; // output is Chester

//Equal sign is only valid during assigning


//We are not allowed to use equal sign but use the function strcpy
Literal string: …..
Example:
char name3[30];
strcpy(name3 , “Pedro”);
Difference between
‘a’ = one byte
“a” = two byte // a | \0

Inputting of data to a string:


1. scanf()
Syntax: scanf(“%s” , f<string>);
*terminates the input when space is encoded
2. gets()
Syntax: gets(<string>);
*terminates the input when the hard carriage return or enter key is pressed

scanf() vs gets() JUAN DELA CRUZ

scanf()
scanf( “%s” , name3);
printf(“%s” , name3);
Output: Juan
//Once we put the spacebar, it will terminate = the output is Juan, ok to use if there is
surely no space

gets()
gets(name3)
Output: Juan Dela Cruz
//It will terminate after enter = output is Juan dela Cruz , if space is involved use gets()

Sep 1, 2023

Comparing strings

//Both will return an integer


strcmp() , A is not equal with a
SYNTAX: int strcmp(<string1>) , <string2>); // 2 strings you are going to compare
If : string1 = string 2 it returns 0
string1 < string2 it returns -1 // less than the second parameter
string1 > string2 it returns 1 // greater than the second parameter
strcmp() is case sensitive

strcmpi() is not case sensitive , Small a is equal to capital A


Syntax: the same as strcmp() except that strcmpi is not case sensitive

a.
char str1[10] = “abc”
char str2[10] = “bac”
int x;

x = strcmp(str1, str2);
printf(“%d” , x); output is -1; // meaning string 1 is less than string 2

// “abc” < “bac”


//97 98 99 < 98 97 99 // 97 is less than 98 , automatically compares the first letter
(value) , not compare the remaining characters

b.
x = strcmp(str2, str1);
printf(“%d” , x) // output is 1

c.
char str1[10] = “ABC”
char str2[10] = “abc”
int y;
y = strcmp(str1, str2);
printf(“%d” ,y); // output is -1

d.
y = strcmpi(str1,str2);
printf(“%d” , y);// output is 0

e.
str1[10] = “abcd”
str2[10] = “abmx”
strcmp(“abcd” , abmx”)
//ABC vs abc
//65 < 97 , output is negative 1
//strcmpi will disregard and the return value will be 0 , given that both values are the
same
// strcmp() abcd vs abmx , it will continue to compare the third , c is less than m ,
comparing characters.
// use string comparison , shorter and better than for loop.
// use this if you are searching for a string , if it is zero then you found it.

// string length
// encryption, process character by character
// char pass[30] ; loop when typing a password, replace with char pass[s]; // if i>s it will
loop 30 times even though you have 8 characters
// the best way = determine the length
// use the variable m , always use the same variable with your assigned variable in
string length function and in the loop.
// don't forget to use #include<string.h> in your header file or your program won’t work.

SIDE NOTES
You can’t do “abc” = “abc”

If the case of the letter is important, how the letters are written is important, use the first
one.

ASCII code - to compare the letters


A = 65 , B = 66 , …..
a = 97 , b = 98 ….
______________________________________________________________________

STRUCTURES

Defining structures:

SYNTAX:
typedef struct // all small letters , type definition structure
{
<datatype1> <field1>; // define your fields // each has its own data type
<datatype2> <field2>;
<datatypeN><fieldN>; // meaning as many fields as you wish // N is the last
} NEWTYPE;
// closing brace , put the name of the structure // a structure is a data type //Why
capitalize? Two types of data types, native data types (program itself) and we have
user defined types (programmer). All native are in small letters, big letters are more
distinguishable. // to know which is native and which is not.

Declaring a variable of type structure:


SYNTAX:
<NEW TYPE> <var name>;

a.
typedef struct
{
char id[5];
char name[20];
int age;
} PERSON;

b.
PERSON p1 = {“101” , “PEDRO” , 25};
PERSON p2;
strcpy (p2.id , “102”) ;
strcpy (p2.name , “Juan”);
P2.age = 28;

Determining the length string : strlen()


SYNTAX: int strlen(<string>);
define S 10
char str[S] = “abcde”;
int = m;

m = strlen(str);
printf(“%d”, m); // output is 5
for ( i =0 ; i < m ; i++)
char strl[s] = “abe”
m = strlen(strl); // for ( i = 0; i < m ; i++)

// you can have multiple variables, PERSON can declare a variable , and can now
declare an initial value for PERSON. //PERSON p1 =
// period is member operator // collection of objects
// combine different data types and place it in one structure compared to arrays
// 3 ways to declare structures
______________________________________________________________________

Sep 4, 2023

A.
#include<string.h>
#include<stdio.h>

typedef struct
{
char id[3];
char name[15];
float balance;
}PERSON;

PERSON inputData(void);
int main(void)
{
PERSON person;
person = InputData();
printf("\nID: %s",person.id);
printf("\Name: %s" , person.name);
printf("\nBalance: %0.2f" , person.balance);
getch();
return 0;

} // end of main\
PERSON inputData(void)
{
PERSON p;
printf("\nID: );
gets(p.id);
printf("\nName: ");
gets(p.name);
printf("Balance: ");
scanf("%f", &p.balance);
return p;
} // end of input Data

B.
#include<string.h>
#include<stdio.h>

typedef struct
{
char id[3];
char name[15];
float balance;
}PERSON;

void inputData(PERSON*);

int main(void)
{
PERSON person;
inputData(&person);
printf("ID: %s",person.id);
printf("Name: %s", person.name);
printf("\nBalance: %f" , person.balance);
getch();
return 0;

} // end of main\

void inputData(PERSON *person)


{
printf("\n ID: ");
gets((*person).id);
printf("\nName: ");
gets((*person).name);
printf("Balance: ");
scanf("%f",&(*person).balance);
return;
} // end of input Data

// *person. Id // 2 operators // the only pointer is the person while Id is the field
// rule of precedence , asterisk will be applied first
//*(person.id) // is the same // error asterisk applied to id , id is not a pointer
// SOLUTION , enclose person with a parenthesis – (*person).id // person -> id

C.
typedef struct
{
char name[20];
int score[3];
} STUDENT;

STUDENT stud;

// stud is a variable

C1. By Value

Assign the name Johnny to name:


strcpy(stud.name, “Johnny”);

Assign the score 85 to score[1]:


stud.score[1] = 85;

int main (void);


{
STUDENT stud = { “Johnny” , { 80,78, 92} } ;

test (stud) ; // By value


printf(“Score: %d, stud.score[1]); // 78 output
}
void test (STUDENT stud)
{
stud.score [1] = 60;
return;
}

// pass by value // 2 curly braces // replace with 60 // still 78 // pass by value , array is by
reference

C2. By Reference

int main (void);


{
STUDENT stud = { “Johnny” , { 80,78, 92} } ;

test (&stud) ; // By reference


printf(“Score: %d”, stud.score[1]); // 60 output
.
.
.
}
void test (STUDENT *stud)
{
stud.score [1] = 60; //is the same as (*stud).score[1] = 60;
return;
} // ampersand received by an asterisk

D.

typedef struct
{
char name[20];
int score[3];
}STUDENT

// Display the score 92:


printf(“%d”, arr[1].score[1]);
ARRAY OF STRUCTURES
SYNTAX:
<structure type> <array name> [<size>];
Example:
STUDENT arr[3];

// this array can hold 3 type of STUDENT


structures
// start the name of the array of structure ,
period must be outside the bracket

Sep 5, 2023

#define FLUSH while (getchar()!=’\n’)

typedef struct
{
char name[20];
char addr[30];
float balance;
} PERSON;

int main (void)


{
PERSON person;
inputData (&person);
}

void inputData (PERSON *person)


{
FLUSH;
printf(“\n Name: “);
gets(person -> name) ;
printf(“\n Address: “);
gets(person -> addr);
printf(“Balance : “);
scanf(“%f” , &person -> balance);
}
// some will be skip is because , “Juan” 15 empty spaces , clear the buffer , to do that , declare a
constant : #define FLUSH while(getchar() !=’/n’ , put it down, it will flush after \n
//now it won’t skip
____________________________________________________________________________

APPLICATION OF STACK
STACK ADT

Postfix expression
● Read the expression from left to right
● When a number is seen, it is pushed onto the stack;
● When an operator is seen
○ Pop two numbers from the stack
○ the operator is applied to the two numbers
○ the result is pushed onto the stack.
● The time to evaluate a postfix expression is O(n).
//infix expression - the way to do it //postfix notation - how computer do it
//numbers are put into the stack
//operators are pop
// number on top is the final answer
// a marker will guide you - TOS

What is a STACK?
● A stack is a list with the restriction that inserts and deletes can be performed in only one
position, namely the end of the list called the top.
● The fundamental operations on a stack are push, which is equivalent to an insert, and
pop, which deletes the most recently inserted element.
● A pop or top on an empty stack is generally considered an error in the stack ADT.
● On the other hand, running out of space when performing a push is an implementation
error but not an ADT error.
● Stacks are sometimes known as LIFO (last in, first out) lists
//Collection of objects (set /array)
// draw it vertically “top”
// input will place on top, and it will remove from the top , can only access the top of the stack
//push - input | pop - remove something

____________________________________________________________________________

LINKED-LIST Implementation of STACK

● We perform a push by inserting at the front of the list.


● We perform a pop by deleting the element at the front of the list.
● A top (peek) operation merely examines the element at the front of the list, returning its
value.
● Support operations:
○ Create stack - initializes the pointer top to NULL
○ isEmpty - checks if the stack is empty and returns a Boolean value. This is done
prior to executing the pop operation.
● All the operations take constant time
● The drawback of this implementation is that the calls to malloc and free are expensive
//free()

PUSH OPERATION (add element) - LINKED-LIST STACK

Begin procedure push: tos, value // let *tos point to where temp is pointing
Create node temp void push (ndPtr *tos, int value)
temp.data <- Value {
temp.next <- tos /* Line 1 */ ndPtr temp =
tos <- temp malloc(sizeof(NODE));
End procedure /* Line 2 */ temp -> num = value;
/* Line 3 */ temp -> next = *tos;
// let pointer next point to the object pointed /* Line 4 */ *tos = temp;
to by *tos. return;
}

// two parameters , tos and value


// it’s using an arrow because it is a basic operation for assignment ->
In C PROGRAM:
void push(ndPTR *tos, int value) // should have value type of int
// Begin procedure push: tos, value
{
ndPTR temp = malloc(sizeof(NODE)); Create node temp
temp -> num = value; // temp.data <- Value
temp -> next = *tos; // temp.next <- tos
*tos = temp; // tos <- temp
} // end of Function

Defining A LINKED-LIST

SYNTAX:
typedef struct <node name> <self pointer>; //pointer should have an asterisk
Struct <node name> // node name should be the same

{
<data type1> <field1>;
<data type2> <field2>;
.
.
.
<date typeN> <fieldN>;
<self pointer> <pointer name>;
} NODE; // name of the node// must be in capital letter

Declaring a node pointer


SYNTAX:
<self pointer> <nodepointer name>;

Creating a Node
SYNTAX:
<node pointername> = malloc(sizeof(NODE));
Example:
typedef struct pnode *ndPtr;
struct pnode
{
int num;
ndPtr next; //next can be any name
} NODE; //Defining A LINKED-LIST

ndPtr temp; // Declaring a node pointer


temp = malloc(sizeof(NODE)); //Creating a Node
Sep 7, 2023

PUSH Operation (Add element) - LINKED- LIST STACK


Example:

Typredef struct pnode *ndPtr;


struct pnode
{
int num;
ndPtr next;
} NODE;

IN C PROGRAM:

void push (ndPtr *tos, int value)


{
/* Line 1 */ ndPtr temp = malloc(sizeof(NODE));
/* Line 2 */ temp -> num = value;
/* Line 3 */ temp -> next = *tos; // let pointer next point to the object pointed to by *tos.
/* Line 4 */ *tos = temp; // let *tos point to where temp is pointing
return;
}

Scenario 1 :
(PUSH)
The STACK is
empty

Scenario 2 :
(PUSH) The
STACK has at
least one
element
// 2 . //Value 15
is pointed by
temp
//15 Front data,
be removed
regardless of
value. 10 is the
Rear data.
POP Operation - (Remove element) - LINKED- LIST STACK

begin procedure pop: tos


create node pointer noptr int pop(ndPtr *tos)
value <- tos.data {
ndptr <- tos int value;
tos <- tos.next ndPtr ndptr;
deallocate ndptr /* Line 1 */ Value = (*tos) -> num;
return value /* Line 2 */ ndPtr = *tos;
end procedure /* Line 3 */ *tos = (*tos) -> next;
/* Line 4 */ free(ndptr);
/* Line 5 */ return value;
}
// you don’t include the data to be remove
//there should ba return data type
//the return type of POP is also int
//there is an asterisk because we have to remove a node

Example:

Typredef struct pnode *ndPtr;


struct pnode
{
int num;
ndPtr next;
} NODE;

IN C PROGRAM:
int pop(ndPtr *tos)
{
int value;
ndPtr ndptr;
/* line 1 */ value = (*tos) -> num;
/* line 2 */ ndptr = *tos;
/* line 3 */ *tos = (*tos) -> next;
/* line 4 */ free(ndptr);
/* line 5 */ return value;
}
// rule of thumb: declare less complex data type first
//this function will not work if your stack is empty
First Scenario: STACK with one node (POP)

//free (ndptr) or free() destroys the memory allocation occupied by the node
//return value si baklang 10

Second Scenario: STACK has more than one node (POP)

//transfer tos to pointer next or the node will be destroyed


// number 3 line // next; *tos = ndptr ->next;
ISEMPTY Operation - LINKED-LIST STACK

if tos = NULL
return true
else
return false
//end procedure

In C PROGRAM :
bool isEmpty (ndPtr tos)
{
bool empty = false; //assume that it is false
if (tos == NULL)
empty = true;
return empty;
} // Sir’s version
// is always executed with POP , don’t run pop if you do not run this
//value = (*tos) -> num
//extract the value from field num, this will become an error if tos is pointing to NULL
// is your stack empty or not? // true , stack is empty

PEEK Operation - LINKED-LIST STACK

PEEK Operation
begin procedure peek: tos
value <- tos.data
return value
end procedure

Sep 11, 2023

Example 1 Program: PUSH and POP - LINK-LIST Implementation

#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <ctype.h>

#define S 100

typedef struct snode *nd;


struct snode
{
int num;
nd next;
}STACK;
void getPostExp(char []);
void push(nd *, int);
int pop(nd *);
bool isEmpty(nd);
void dispResult(char [], int);
nd createStack(void);
void calcPostfixValue(char []);

int main(void)
{
char postExp[S];
getPostExp(postExp);
calcPostfixValue(postExp);
return 0;
}

void getPostExp(char postFix[])


{
printf("\n\n\tInput a postfix expression: ");
gets(postFix);
return;
}

void push(nd *tos, int value)


{
nd temp = malloc(sizeof(STACK));
temp->num = value;
temp->next = *tos;
*tos = temp;
return;
}

int pop(nd *tos)


{
int retValue = (*tos)->num;
nd ndptr = *tos;
*tos = (*tos)->next;
free(ndptr);
return retValue;
}

bool isEmpty(nd tos)


{
bool empty = false;
if(tos == NULL)
empty = true;
return empty;
}
void dispResult(char postFixExp[], int result)
{
printf("\n\n\t%s = %d",postFixExp, result);
getch();
return;
}

nd createStack(void)
{
nd tos = NULL;
return tos;
}

void calcPostfixValue(char postFixExp[])


{
char term;
int termNum, num1, num2, res, length, j;
bool empty;
nd tos;

tos = createStack();
length = strlen(postFixExp);
for(j = 0; j < length; j++)
{
term = postFixExp[j];
if(isdigit(term))
{
termNum = term - '0'; // converts the character value term
into an integer using the ASCII value
push(&tos, termNum);
}
else
{
empty = isEmpty(tos);
if(!empty)
num1 = pop(&tos);
else
{
printf("\n\tError: invalid expression...");
getch();
return;
}
empty = isEmpty(tos);
if(!empty)
num2 = pop(&tos);
else
{
printf("\n\tError: invalid expression...");
getch();
return;
}
switch(term)
{
case '+': res = num1 + num2;
break;
case '*': res = num1 * num2;
break;
case '-': res = num2 - num1;
break;
case '/': res = num2 / num1;
break;
default: printf("\n\n\tInvalid operator...");
getch();
return;
}
push(&tos, res);
}// end of else
}// end of for ... loop
empty = isEmpty(tos);
if(!empty)
num1 = pop(&tos);
else
{
printf("\n\tError: invalid expression...");
getch();
return;
}
empty = isEmpty(tos);
if(!empty)
{
printf("\n\tError: invalid expression...");
getch();
}
else
dispResult(postFixExp,num1);
return;
}// End of Program
Example1.c

SIDE NOTES :
// //4 statements main
// nd Createstack
- Local variable

//caclPostfixValue
// for loop for the program is short, you have to know exactly where to stop
// for loop calculate the length of the string
//convert a character into an integer
//if(isdigit(term)) // 6 can be converted into a number
93 // termNum = term - '0'; // converts the character value term into an integer using the ASCII
value // convert a single character into an integer; // termNum is declared as an integer //
// termNum = ‘6’ - 0 = 6 // haski code 54 - 48 = 6

94 // push(&tos, termNum); // 6 will be pushed

96//
else
{
empty = isEmpty(tos);
if(!empty)
num1 = pop(&tos);
else
{
printf("\n\tError: invalid expression...");
getch();
return;
}

// if it is an asterisk
// bool is false
// it will pop two elemens , 2 and 6
// check stack if it is empty or not
// if it is true, it will pop and element and store it in num 1

107 // empty = isEmpty(tos);


if(!empty)
num2 = pop(&tos);
else
{
printf("\n\tError: invalid expression...");
getch();
return;
}
// check value again
// use switch statement

116
// switch(term)
{
case '+': res = num1 + num2;
break;
case '*': res = num1 * num2;
break;
case '-': res = num2 - num1;
break;
case '/': res = num2 / num1;
break;
default: printf("\n\n\tInvalid operator...");
getch();
return;
}

// asterisk multiply * // call push in

130 // push(&tos, res);


//increment and it will repeat the same process

133// What is the purpose of this? //

empty = isEmpty(tos);
if(!empty)
num1 = pop(&tos);
else
{
printf("\n\tError: invalid expression...");
getch();
return;
}
empty = isEmpty(tos);
if(!empty)
{
printf("\n\tError: invalid expression...");
getch();
}
else
dispResult(postFixExp,num1);
return;

// at the end of the loop only one value left

//What if the expression is


// 6 2 * 2 \0
// backslash zero, the one on the top is the answer
// before you say 2 is the answer, check your stack and it is not empty // error
What is a balance equation ?
6 +2*3
( 6 + 2 ) * 3 Balanced

(6+2) * (2*3)
// if stack is empty it is not balance
// only after the parentheses
// disregard the value and operations
//char term
term = ‘ ( ‘
if (term = ‘( ‘ )
push
if (term = ‘) ‘ )
Pop

Assignment 1 Program: Check Balance for Parenthesize Equation


LINKED-LIST Implementation

#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdbool.h>
#include <stdlib.h>
#include <ctype.h>

#define S 100
#define FLUSH while(getchar() != '\n')

typedef struct snode *nd;


struct snode
{
char delimeter;
nd next;
}STACK;

nd create_Stack(void);
void get_Delimeted_Exp(char []);
void push(nd *,char);
char pop(nd*);
bool isEmpty(nd);
void display_Result(char [], bool);
bool isBalance(char []);
int main(void)
{
bool balance;
char ans, deli_Exp[S];
do
{
system("cls");
get_Delimeted_Exp(deli_Exp);
balance = isBalance(deli_Exp);
display_Result(deli_Exp,balance);
printf("\n\n\tDo you want to try another expression (Y/N)?");
scanf(" %c",&ans);
}while(toupper(ans)== 'Y');
return 0;
}

nd create_Stack(void)
{
return NULL;
}

void get_Delimeted_Exp(char del_Exp[])


{
FLUSH;
printf("\n\n\tInput a parenthesized expression: ");
gets(del_Exp);
return;
}

void push(nd *tos,char paren)


{
nd temp = malloc(sizeof(STACK));
temp->delimeter = paren;
temp->next = *tos;
*tos = temp;
temp = NULL;
return;
}

char pop(nd *tos)


{
char ret_Paren = (*tos)->delimeter;
nd ptr = *tos;
*tos = ptr->next;
free(ptr);
return ret_Paren;
}
bool isEmpty(nd tos)
{
bool empty = false;
if(tos == NULL)
empty = true;
return empty;
}

void display_Result(char del_Exp[],bool balance)


{
if(balance)
printf("\n\n\tThe expression %s is balance",del_Exp);
else
printf("\n\n\tThe expression %s is not balance",del_Exp);
getch();
}

bool isBalance(char del_Exp[])


{
int j = 0;
char del, ret_del;
bool empty, balance;
nd tos;

tos = create_Stack();
while(del_Exp[j] != '\0')
{
del = del_Exp[j];
if((del == '(') ||(del == '['))
push(&tos,del);
else if((del == ')')||(del == ']'))
{
empty = isEmpty(tos);
if(empty)
{
balance = false;
return balance;
}
else
{
ret_del = pop(&tos);
if ((del == ']') && (ret_del == '('))
return false;
else if ((del == ')') && (ret_del == '['))
return false;
}

}// end of else


j++;
}// end of while loop
empty = isEmpty(tos);
if(!empty)
balance = false;
else
balance = true;
return balance;
}// end of program

stackBalDelimeter.c
______________________________________________________________________

Sep 18, 2023


Array Implementation of STACK

Tos (top of stack) is not a pointer but a variable = integer placed inside a structure

Defining the Stack

typedef struct
{
int stk[size]; // the actual stack of array
int tos; // variable that holds the value of the latest stack index being filled with data
//the top of the stack

}STACK;

NOTE:
For this discussion, we will use integers , However the stack data type must be changed
in order for it to be compatible with the data being handled.
//Index of an array regardless of data type is integer
//Tos and array will be pass as a parameter = put in in the container for easier pass
//Major operations of Push and Pop

CREATE STACK Operation: - ARRAY Implementation


begin procedure createStack;
create local stack ;
While not end of stack
clear each cell in the stack
tos <- (first index - 1)
return stack
end
In C PROGRAM: Refer to this structure :

typedef struct
{
int stk[s];
int tos;
}STACK;

2 VERSIONS

1. Return statement , declare local variable initialize and return

STACK createStack(void)
{
int j;
STACK stak;
for (j = 0; j < s; j++)
stak.stk[j] = 0; // actual array is inside
stak.tos = -1 ;
return stak;
}

2. Implement using a pointer , parameter

void createStack (STACK *stak)


{
int j;
for (j = 0 ; j<S; j++)
stak -> stk[j] = 0; // can be written as (*stak).stk[j] = 0;
stak -> tos = -1; // can be written as (*stak).tos = -1;
return ;
}

ISFULL Operation - ARRAY Implementation


//Called before you call the push operation
//ARRAYis predefined , while the size is reached you can not add anymore
//Link list the size is dynamic - there is no checking if the stack is full or not,

In C PROGRAM :
bool isFull(int tos)
{
bool full = false;
if (tos == (S - 1))
full ==true;
return full; }
ISEMPTY Operation - ARRAY Implementation

begin procedure isempty: tos


If tos less than first index
return true
else
return false
endif
end procedure

In C PROGRAM:
bool isEmpty(int tos)
{
bool empty = false;
if (tos < 0 )
empty = true;
return empty;
}
OR
bool isEmpty(int tos)
{
bool empty = false;
if (tos== -1) // top of stack won’t reach -2
empty = true;
return empty;
}

PUSH Operation - ARRAY Implementation

begin procedure push: stack, data


tos <- tos + 1
stack[top] <- data
end procedure
//Increment the value of tos because we can not store a value of negative 1

C PROGRAM:

void push (STACK *stak, int data)


{
stak -> tos += 1;
stak->stk[stak -> tos] = data;
return;
} // first parameter is stack and the data to be added
POP Operation - ARRAY Implementation

begin procedure pop:stack


data <- stack[tos]
tos <- tos -1
return data
end procedure

Note: no data erased during the pop operation. The data are overwritten during the next push
operation.
//In LINKED-LIST you can delete the value but in ARRAY you can not
// instead of replacing the value, move tos

In C PROGRAM:

int pop(STACK *stak) {


int refValue = stak -> stk [stak -> tos ]; // declare local variable
stak -> tos = stak -> tos -1; z
return refValue; \
}

int peek(STACK stak) {


int refVal = stak.stk[stak.tos];
return retval;
}
Example Program: This program will check if the parenthesize equation is
balanced or not. - ARRAY Implementation

#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdbool.h>
#include <ctype.h>

#define FLUSH while(getchar() != '\n') // used to clear the input buffer


#define E 100 // size of the postfix string expression
#define S 50 // size of the stack

//definition of stack
typedef struct
{
char delimeters[S];
int tos;
}STACK;

STACK create_Stack(void);// the one that create the stak


void get_Delimeted_Exp(char []);
bool isFull(int);
bool isEmpty(int);
void push(STACK *,char);
char pop(STACK *);
bool check_Expression(char []);
void display_Result(char [],bool);

int main(void)
{
char ans, del_Exp[E]; // the string that will hold the expression
bool balance;
do{
system("cls");
get_Delimeted_Exp(del_Exp);
balance = check_Expression(del_Exp);
display_Result(del_Exp,balance);
printf("\n\n\tDo you want to try another expression(Y/N)?");
scanf(" %c",&ans);
}while(toupper(ans) == 'Y'); // this function is going to convert
ans into an uppercase , if ans is a character
return 0;
}

void get_Delimeted_Exp(char del_Exp[])


{
FLUSH;
printf("\n\n\tInput a parenthesized expression: "); // should not be put
in main
gets(del_Exp);
return;
}
//this is where the user inputs

bool isFull(int tos)


{
bool full = false;
if(tos == (S - 1))
full = true;
return full;
}
//executed prior to push

bool isEmpty(int tos)


{
bool empty = false;
if(tos == -1)
empty = true;
return empty;
}
// should be placed in a separate function
//executed prior to pop

void push(STACK *stak,char delimeter)


{
stak->tos += 1;
stak->delimeters[stak->tos] = delimeter;
return;
}
//it is assume that it is not full

char pop(STACK *stak)


{
char retDelimeter = stak->delimeters[stak->tos];
stak->tos = stak->tos - 1;
return retDelimeter;
}
//the stack is not empty

bool check_Expression(char delimeted_Exp[])


{
char delimeter, retDelimeter;
int j, str_Length;
bool empty, full,balance;
STACK stak;
stak = create_Stack();
str_Length = strlen(delimeted_Exp); //count the expression
for(j = 0; j < str_Length; j++) // for the limit of the loop
{
delimeter = delimeted_Exp[j];
if((delimeter == '(') ||(delimeter == '[' )) // it has the be
pushed
{
full = isFull(stak.tos);//by value
if(full)
{
printf("\n\n\tError: stack is full...");
getch();
break;
}
else
push(&stak,delimeter);
}
else if((delimeter == ')') ||(delimeter == ']' ))
{
empty = isEmpty(stak.tos);
if(empty)
{
return false;
break; // not empty
}
else
{
retDelimeter = pop(&stak); // by parameter
if ((retDelimeter == '[') && (delimeter == ')')) // not
balanced
{
return false;
break;
}
else if ((retDelimeter == '(') && (delimeter == ']'))
{
return false;
break;
}

}
}

}// end of for loop


empty = isEmpty(stak.tos);
if(!empty)
balance = false;
else
balance = true;
return balance;
}

void display_Result(char delimeted_Exp[],bool balance)


{
if (balance)
printf("\n\n\tThe expression %s has a balance parenthesis or
brackets.",delimeted_Exp);
else
printf("\n\n\tThe expression %s has an unbalance parenthesis or
brackets.",delimeted_Exp);
getch();
}

STACK create_Stack(void)// parameter is structure STACK


{
int j;
STACK stak;

for(j = 0; j < S;j++)


stak.delimeters[j] = ' '; //every element will be an empty space
stak.tos = -1;
return stak;
}// end of program

checkBalExp_Array.c

LAB 2 : (Convert to Binary)


______________________________________________________________________________

Oct 2, 2023

QUEUE ADT

● Like stacks, queues are lists.


● With a queue, however, insertion is done at one end, whereas deletion is performed at
the other end
● The basic operations on a queue are enqueue, which inserts an element at the end of
the list (called the rear), and dequeue, which deletes (and returns) the element at the
start of the list (known as the front).
● Like stacks, both the linked list and array implementations give fast O(1) running times
for every operation.
// can be used an array or a link-list
// Normally drawn as an array
// Difference = stack is only one pointer (tos) , queue has 2 pointers
// one pointer points at the front, one at the rear

// 2 Pointers
//first pointer = front pointer or head pointer, use to remove elements
//second pointer = the rear pointer, tail pointer, use to add elements
//not use simultaneously, only used one at a time

// use an array = isempty, isfull,


// link list = isempty only

// 2 types - Linear and Circular

____________________________________________________________________________

Linear QUEUE
Array Implementation

● For each queue data structure, we keep an array, adtque[],and the positions q_front
and q_rear that represent the ends of the queue.
● These adtque[], q_front and q_rear are contained in a structure QUEUE.
QUEUE structure: Array Implementation

typedef struct
{
int adtQueue[s];
int q_front;
int q_rear;
}QUEUE;

// Note: This definition assumes that the data being handled is an integer.
// doesn't always mean it always has to be an integer // depends on what data is being handled
//front and rear has to be always an integer

1. Create Queue Operation [linear q] - ARRAY Implementation


__________________________________
begin procedure createqueue: QUEUE
for j ←1 to MAXSIZE
QUEUE.adtque[j] ← NULL
QUEUE.q_front ← 0
QUEUE.q_rear ← -1
return QUEUE
end procedure
__________________________________
// if this is circular queue it has to be different
//if the programming language does not accept NULL , replace with 0 , or a pair of single quotes
if it is a character

In C Program:

QUEUE createQueue(void)

{
int j;
QUEUE q;
for ( j = 0; j < S ; j ++ )
q.adtQueue[j] = 0;
q.q_front = 0;
q.q_rear = -1 ;
return q;
}
2. Enqueue operation [linear q] - ARRAY Implementation
__________________________________________
begin procedure enqueue: QUEUE, value
QUEUE.q_rear ← QUEUE.q_rear + 1
QUEUE. adtque[QUEUE.q_rear] ← value
return QUEUE
end procedure
__________________________________________
//will take 2 parameters , structure and the data being added

// increment rear
// move rear -1 index forward to make it a valid
index
//store the value
//return queue , after the enqueue should have 1
more element inside, not technically returned
//return type void

In C Program:

void enQueue(QUEUE *q, int value)


{
q -> rear += 1;
q -> adtQueue[ q ->rear] = value;
return;
}
// if we add 5
// pass the whole QUEUE
//rear moves, the front stays at index 0 , which means regardless of how many times the rear
moves , front will always stay at its place
//q front does not move.
//add to elements to make it full

3. Dequeue Operation[linear queue] - ARRAY Implementation


__________________________________________
begin procedure dequeue: QUEUE
declare variable r
r ← QUEUE.que[QUEUE.q_front]
QUEUE.q_front ← QUEUE.q_front + 1
return r
end procedure
__________________________________________
// in a queue when we remove an element add 1 , always move to the right
// in a stack we subtract (pop) up and down
// one parameter structure QUEUE

In C Program:
int deQueue(QUEUE *q)
{
int r = q -> adtQueue[ q -> q_front]; // copy the value of 5 or index 0
q -> q_front + = 1; // move the front to index 1
return r;
}
//base from the last example
// notice that there is no value , or a parameter which value is removed , because the front is
always removed
// deQueue: r = 5

//can we add an element ? NO


// check if the stack is full /empty
before adding an element
4. isFull Operation[linear queue] - ARRAY Implementation

In C Program:
bool isFull_Queue(int rear)
{
bool full = false;
if (rear == ( M - 1 ) ) // Max Size
full = true;
return full;
}
4 == ( 5 - 1) // Max size of 4 Arrays
4 == 4
full = true
____________________________________________________________________________

Circular QUEUE
Array Implementation

● An array implementation of queue where it is treated as a circle rather than as a straight


line.
● Assumes that the first element of the array follows immediately its last element.
● Resolves the inherent inefficiency of linear queue.

1. Create Queue Operation [circular q] - ARRAY Implementation


____________________________________
begin procedure createqueue: CQUEUE
for j ←1 to MAXSIZE
CQUEUE.adtque[ j ] ← NULL
CQUEUE.q_front ← 0
CQUEUE.q_rear ← 0
return CQUEUE
end procedure
_____________________________________

In C Program:

QUEUE createQueue(void){
int j;
QUEUE q;
for ( j = 0; j < s ; j ++ )
q.adQueue[j] = 0;
q.q_front = 0;
q.q_rear = 0;
return q; } //Difference is rear and front pointing to 0 , already a valid index
2. Enqueue Operation [circular q] - ARRAY Implementation
_______________________________________________
begin procedure enqueue: CQUEUE, value
CQUEUE.adtque[CQUEUE.q_rear] ← value
CQUEUE.q_rear ← (CQUEUE.q_rear + 1) modulo
MAXSIZE;
return CQUEUE
end procedure
_______________________________________________
//difference is the arrangement of 2 statements
//circular store data first in index 0, then we increment it by 1
//linear is += but in circular it is modulo

A.

B. if not pointing
to 5
In C Program :
void enQueue(QUEUE *q, int value)
{
q -> adtQueue[q -> rear] = value;
q -> rear = ( q -> rear + 1 ) %SIZE;
return;
} // using Modulo
Or
void enQueue(QUEUE *q, int value)
{
q -> adtQueue [ q - q_rear] = value;
if ( q -> q_rear == (SIZE - 1))
q -> q_rear = 0;
else
q -> q_rear += 1;
return;
} // up to preference

Oct 3, 2023

3. Dequeue Operation [circular q] - ARRAY Implementation


___________________________________________
begin procedure dequeue: CQUEUE
declare variable r
r ← CQUEUE.adtque[CQUEUE.q_front]
CQUEUE.q_front ← (CQUEUE.q_front + 1) modulo
MAXSIZE;
return r
___________________________________________

In C Program:
int deQueue (QUEUE *q)
{
int r = q -> adtQueue[ q -> q_front];
q -> q_front = ( q -> q_front + 1 ) % SIZE;

return r;
}
1.

2.

3.

return type , int


// declare a local variable r ,
// 5 will be store in variable r , index 0
// when we do a dequeue we will not move
our rear, it will always stay
// it is empty if both pointer is pointed to the
same index = empty queue
4. isEmpty Operation [circular q] - ARRAY Implementation
________________________________________
begin procedure isCEmpty: q_front, q_rear
if q_front = q_rear then
return true
else
return false
end procedure
________________________________________

In C Program :
bool isEmpty (int front, int rear) {
bool empty = false;
if (front == rear)
empty = true;
return empty;
} //need the two pointers, front and rear

5. isFull Operation [circular q] - ARRAY Implementation


____________________________________________
begin procedure isCFull: q_front, q_rear)
if q_front = ((rear + 1) modulo MAXSIZE) then
return true
else
return false
end procedure
____________________________________________
In C Program :
bool isFull (int front, int rear)
{
bool full = false;
if (front == rear)
full = true;
return full;
}
// before you can enqueue you have to check if it is Full
// this program can pose a problem

INSTEAD (proposed solution) :

// rear is right behind front , rear


has a free memory , 4 over 5
elements are occupied will be
considered full

bool isFull ( int rear , int front) {


bool full = false;
if (front == (rear +1) %SIZE )
full = true;
return full;
}
0 == 4 % 5
0 == 4 FALSE
Oct 5, 2023

Problem: Simulation of time-sharing in the operating system using a circular queue.

NOTE: The process must have a name and duration. The unit of measure of duration is in
seconds. In addition, since C does not allow concurrent functions to run (we cannot
have an input during runtime), allow the user to input at least 5 processes before the
simulation starts.

The time-sharing algorithm is presented below:


1. The process in the head of the queue is dispatched to use the CPU for a maximum of 10
seconds.
2. If a process has a remaining time to execute of x <= 10, then this process is terminated when
the clock ticks x times after it is dispatched. Otherwise, the process is executed to 10 seconds
and is timed out and is written back to the queue.
3. As the process is executed, display the process name as well as the remaining time after it
timed out.
4. While there are still processes left in the queue, repeat step 1. Otherwise the program
terminates. The program shall display a message upon completion of all the jobs in the queue.

SOLUTION:

1st illustration
// two element , name and duration
// first dispatch P1
// each of them will be allowed for 10 seconds
//P1 has 15 seconds , the remaining will be
put back to the CPU
//this queue is full

2nd illustration
//p1 queue front
//dequeue P1
(run for 10 seconds)
// this is not full anymore
3rd illustration
//after 10 seconds , enqueue P1
//where rear is pointing = p1 = 5 seconds
///rear will move forward to index 0

4th illustration
// dequeue p2
// run for 10 seconds
//q front will move forward to index 2 / p3 , q rear will
remain in index 0
// it will run for 10 seconds

5th illustration
//enqueue p2
// p2 will be index 0

6th illustration
//after 8 seconds it will terminate , it will not be given
back
7th illustration
//dequeue q_front
//after 5 seconds p1 will terminate

8th illustration
//p2 will dequeue
//queue is already empty = stop
_______

// queue 2 dimensional array


//name is a character and duration is numeric,
can't combine , instead use inside a structure
//definition of queue
ILLUSTRATIONS ONLY
typedef struct
{
char pName[N];
int duration;
}PROC;

typedef struct
{
PROC adtQueue[Q];
int q_front;
int q_rear;
}QUEUE;

The process will look like this:


Illustration

// main program
// call to simulate
// call input
//enqueue
//dequeue
// evaluate the time, if there is more time,
enqueue
// the cycle repeats

//windows.h
//use this function Sleep(): suspend process
running in milliseconds
// Sleep(<time in milliseconds>); // place it
after the dequeue x

Practice Sample Program : TimeQueue.c


Oct 12, 2023
CIRCULAR QUEUE
Implementation of LINKED-List
Transfer Null to the temp
Enqueue to the right (rear)
Dequeue from the left (front)

typdedef struct node *nd


struct node
{
int num;
nd next;
} NODE;

1. Create Queue Operation - LINKED-LIST Implementation

In C Program:
void create_Queue (nd *q_front, nd *q_rear)
{
*q_front = NULL ;
*q_rear = NUL;
return;
}
// the queue is empty, both of it is pointing to null, empty queue // no isfull

2. Is Empty Operation - LINKED-LIST Implementation

In C Program:
bool isEmpty(nd q_rear) // can replace rear with front
{
bool empty = false;
if ( q_rear == NULL)
empty = true;
return true;
}

3. EnQueue Operation - LINKED-LIST Implementation

In C Program:
A.
void enQueue(nd *q_front, nd *q_rear, int data)
{
nd temp = malloc(sizeof(NODE));
temp -> num = data;
temp -> next = NULL;
if ( *q_rear != NULL)

{
(*q_rear ) -> next = temp;
q_rear = temp;
}
else
{
*q_rear = temp;
*q_front = temp;
}
}// three parameters

B.
void enQueue(nd *q_front, nd *q_rear, int data) {
nd temp = malloc(sizeof(NODE));
temp -> num = data;
temp -> next = null;
if (*q_rear != NULL)
(*q_rear) -> next = temp;
else
*q_front = temp;

*q_rear = temp;
}
4. Dequeue Operation - LINKED-LIST Implementation

In C Program:
int deQueue(nd *q_front , nd *q_rear)
{
int retData = (*q_front) -> num; // local data // copy the data
nd ptr;

ptr = *q_front;
*q_front = ptr -> next;
if (*q_front == NULL)
*q_rear == NULL;
free (ptr);

return retData;

}// end of dequeue //need front and rear

// link list as a circular queue , no need to


discuss , no problem it will never be empty
//q_rear -> next = temp
//q _rear -> next = q_front

____________________________________________________________________________
Oct 23, 2023
Binary Search Trees

Trees
● It consists of a finite set of elements called NODES or VERTICES, and a finite set of
DIRECTED ARCS that connects pairs of nodes.
● As shown (on the next slide), trees are usually drawn upside down.
○ The ROOT is at the top
○ LEAVES are at the bottom

//line only - indirected arc


//line with arrow - directed arc /directed line
//nodes without nodes below are called a leaf
Binary Tree
● It is a structure that is either:
○ empty, or
○ one that contains a single node called the root, or
○ A root with at most two descendants
● Each descendant is a root of another binary tree.
//utmost 2 children below, if more than 2 , it is no longer a binary

● 50 is a special node called the root.


● Each node has at most two children
● 17 and 72 are the left child and the
right child respectively of 50
● 17 is the parent of 12 and 23.
● Nodes without children are called the leaves.
● Nodes with at least one child are called internal nodes
● The level of a node is equal to 1 plus the level of its parent. NOTE: the root has level 0.
● Level i of a binary tree is full if there are exactly 2i nodes at this level.

Binary Search Tree

● It is a data structure wherein every node is


greater than or equal to the values in its left subtree
and is less than or equal to the values of the nodes in
its right subtree.

Inserting a Node into a Binary Search Tree


● Create a new node
● Check if the root is NULL
● If root is NULL then
○ Root = new node
● If not, traverse tree until node-pointer left or node-pointer right is equal to NULL.
○ If new node < node, move left
○ If new node > node, move right
● If node-pointer left or node-pointer right is NULL then node-pointer left or node pointer
right is equal to new node.*
// use a doubly linked list
// use a loop - while loop
//the node you are going to add < the available nodes move left the node you are going to add > the
available nodes move right
// NOTE : The first value becomes the root

Example:

- 20 is the node while 30 is the


new node
- New node is now 10 and
compare it with 20 and so on…

//Characters

//lexo-graphic comparison - strcmp()


//the one who runs out of character is the smaller one
//alphabetical a < c
// Capital letter B is compared with small letter c, in HASKII code, capital letters are smaller than
lowercase letters.example: A = 65 a = 97.
typedef struct
{
char studId[5];
char studName[20];
} STUDENT;

typedef struct StudNode *ndPtr;


struct StudNode
{
STUDENT stud;
ndPtr left;
ndPtr right;
} STUDNODE;

//Arrange the data based on Student ID:

INSERT IN C PROGRAM:

void addNode(ndPtr *root, STUDENT s)


{
int j ;
ndPtr temp = malloc(sizeof(STUDNODE)), ptr,ptr1;
temp -> stud = s;
temp -> left = NULL;
temp -> right = NULL;
if (*root == NULL)
*root = temp;
else{
ptr = *root;
while ( ptr! = NULL){
j = strcmp (temp -> strud. studId, ptr->stud.studId)
ptr =ptr1;
if (j < 0)
ptr = ptr -> left;
else
ptr = ptr -> right;
}//end of while

j = strcmp ( temp -> stud.studId, ptr -> s


} //root and data to be added
// do not move your root, // if they have the same data type inside the structure
//temp is our new node //ptr1 is to follow where ptr will go, ptr1 will be used in
//ptr is also a new node (else) adding the node
//return type is void , parameter is root and the data //root should be initialized to NULL
// no need to use string copy , equal operation is used
Oct 24, 2023

Searching a Binary Search Tree


● Start at the root
● Compare search value with node value
○ If search value = node value then it is found, exit
○ If search value < node value then move to the left subtree
○ If search value > node value then move to the right subtree
● If ptr is equal to NULL, it’s not found, exit Else repeat second step
//there is a loop inside
//return value of search will depend on why you are searching. Example: boolean if it exists, if display
returns the data inside that depends on the data type.
//Searching: display the result
//return value : data inside the NODE , in the example it is STUDENT

typedef struct
{
char studId[5];
char studName[20];
} STUDENT;

typedef struct StudNode *ndPtr;


struct StudNode
{
STUDENT stud;
ndPtr left;
ndPtr right;
} STUDNODE;

SEARCHING IN C PROGRAM:

STUDENT search_StudentId (ndPtr root, char keyId[ ] )


{
int j;
STUDENT s;
ndPtr ptr = root;

while ( ptr != NULL)


{
j = strcmp ( keyId , ptr -> stud.studId);
if ( j == 0 )
{
s = ptr-> stud; //assignment statement
break ;
}
else if ( j < 0)
ptr = ptr -> left;
else
ptr = ptr -> right;
} //end of while

if (ptr == NULL)
printf(“ %s not found “ , keyId);
else
displayResult(s);
} // can pose a problem because if you are finding a character that doesn’t exist

OR Proposed Solution :

boolean search_StudentId (ndPtr root, char keyId[ ], STUDENT *s )


{
int j;
ndPtr ptr = root;

while ( ptr != NULL)


{
j = strcmp ( keyId , ptr -> stud.studId);
if ( j == 0 )
{
*s = ptr-> stud; //assignment statement
break ;
}
else if ( j < 0)
ptr = ptr -> left;
else
ptr = ptr -> right;
} //end of while

if (ptr == NULL)
return false;
else
return true;
}

To call this:

bool found;
found = search_studentID(root, keyId, *s) ;
if (found)
displayResult(s);
else
printf(“ %s not found” , keyId) ;

//parameters are the root and the search key which is a character string , char keyID[]
//strings are compared by strcmp() while character are compared by ==
// both should be compatible
//strcmp() return value is an integer -1 , 0 , 1
//pass the root by value

Oct 26, 2023


typedef struct
{
char studId[5];
char studName[20];
} STUDENT;

typedef struct StudNode *ndPtr;


struct StudNode
{
STUDENT stud;
ndPtr left;
ndPtr right;
} STUDNODE;

SEARCH: for deletion IN C PROGRAM:

bool search_Delete(ndPtr *ptr1 , ndPtr *ptr2, char sKey[])


{
bool found = false;
int j; // j is used for string comparison
while ( *ptr1! = NULL){
j = strcmp(sKey, (*ptr1) -> stud.studId);
if ( j == 0 ){
found = true;
break;
}
else{
*ptr2 = *ptr1;
if ( j < 0 )
*ptr1 = (*ptr1) -> left;
else
*ptr1 = (*ptr1) -> right;

}//end of else
}//end of while

return found;
}//assumption: ptr1 is set to root before calling this function
//searching should be separate from deletion
// when we delete a node it needs 2 pointers
// asterisk - pointers don't go away when we delete ,it still points to the node.
// return type bool = in order the user to know whether to proceed delete or not
Searching for Max and Min in a Binary Search Tree

● The minimum value is found in the lower leftmost node or the leftmost node without a
child.
● The maximum value is found in the lower rightmost node or the rightmost node without
a child.
//to know the smallest and largest value in the tree
//smallest - go straight to the left (last node)
// largest - go straight to the right (last node)
// ptr is pointing to NULL
//return the data
//you can not return an array when searching for key , make it as a parameter instead

SEARCH minimum IN C PROGRAM: SEARCH maximum IN C PROGRAM:


String String

void search_Min(ndPtr root , char min[]) void search_Max(ndPtr root , char max[])
{ {
ndPtr ptr = root; ndPtr ptr = root;
while (ptr -> left != NULL) while (ptr -> right != NULL)
ptr = ptr -> left; ptr = ptr -> right;
strcpy (min, ptr -> stud.studId); strcpy (max, ptr -> stud.studId);
return ; return ;
} //Minimum string } //Maximum string

SEARCH minimum IN C PROGRAM: SEARCH maximum IN C PROGRAM:


Integer Integer

int search_Min(ndPtr root) int search_Max(ndPtr root)


{ {
ndPtr ptr = root; ndPtr ptr = root;
while(ptr -> left != NULL) while(ptr -> right!= NULL)
ptr = ptr -> left; ptr = ptr -> right;
return ptr -> num; return ptr -> num;
} //Minimum } //Maximum

Deleting a node from a Binary Search Tree

● There are three possibilities that can happen:


○ The node to be deleted has no child
○ The node to be deleted has only one child
○ The node to be deleted has two children
Case 1: Leaf (The node to be deleted has no child)
● Since the node to be deleted has no child it can be deleted without worry
● Set the parent’s pointer to NULL.*

Example 1:
*ptr2 -> right = NULL
free(*ptr1);

Example2:
*ptr2 -> left= NULL
free(*ptr1);

Example3:
//root is being deleted
*root = NULL ;
free(*ptr1);
typedef struct
{
char studId[5];
char studName[20];
} STUDENT;

typedef struct StudNode *ndPtr;


struct StudNode
{
STUDENT stud;
ndPtr left;
ndPtr right;
} STUDNODE;

Deleting a Node IN C PROGRAM: The node to be deleted has no child

bool delete_leaf (ndPtr *root, ndPtr *ptr1, ndPtr *ptr2)


{
if (*root == *ptr1)
*root = NULL;
else{
a = strcmp((*ptr1) -> stud.studId , (*ptr2) -> stud.studId );
if (a < 0 )
(*ptr2) -> left = NULL;
else
(*ptr2) -> right= NULL;

}
free(*ptr1);
return true;
}

Case 2: One child (The node to be deleted has only one child)
● Move ptr to the node to be deleted
● Set the parent’s pointer of the node to be deleted to the child of the node to be deleted
● Free ptr
Case 2: One child (The node to be deleted has only one child)

Example C: ptr2 -> right

//Move pointer that is marked x


//we need ptr2 to access the pointer to be moved
//ptr2 -> right = ptr1 -> left
//floating node
//free (ptr1);

// ptr2 -> right = ptr1 -> right;


//free(ptr1);

Example B: ptr2 -> left

// ptr2 -> left = ptr1 -> right;


//free(ptr1);

// ptr2 -> left


= ptr1 -> left;
//free(ptr1);
Example A: deleting the root

//if (ptr1 == root)


// we will not move ptr1, will not
use ptr 2
//what we will use is root
//root = ptr1 -> left; or root = root
-> left; // can use either of the two
//free(ptr1)

// root = ptr1 -> right; or root = root ->


right;
//free(ptr1)
Deleting a Node IN C PROGRAM: The node to be deleted has only one child

bool delete_One_Child (ndPtr *root, ndPtr *ptr1, ndPtr *ptr2 )


{
int j ;

if (*root == *ptr1 )
{
if ((*ptr1) -> left == NULL) // example A
*root = (*root) -> right;
else
*root = (*root) -> left;
}
else{
j = strcmp((*ptr1) -> stud.studId, (*ptr2) -> stud.studId) ; //example B
if ( j < 0){
if ((*ptr1) -> left == NULL)
(*ptr2) -> left = (*ptr1) -> right;
else
(*ptr2) -> left = (*ptr1) -> left;
}//end if j<0

else{
if ((*ptr1) -> left == NULL)
(*ptr2) -> right = (*ptr1) -> right;
else
(*ptr2) -> right= (*ptr1) -> left;
}//end of else j >0
}//end else

free (*ptr1);
return true;
}// end
// we will check the other side
//if pointer right is NULL, the child is on the left
//if ptr -> left is not equal to NULL

Nov 7, 2023

Case 3: Two Children

Example 1: Delete 100

// When there are two children you can’t actually delete the node
//Instead look at the next higher value of this node (70)
//searching should be done first before doing this
● Inorder Successor

○ Starting at the node to be deleted move one node to the right then traverse
leftward all the way to the leftmost node

//100 to 70
//don't move ptr, use another pointer, ptr1
//ptr1 = ptr -> right, after moving one node to the
right move all the way to the left

while (ptr1 -> left != NULL) // loop to check whether


ptr1 -> is already null and will continue to traverse to
the last node until ptr1 -> left is NULL and the loop
terminates.

○ Replace the value of the node to


be deleted with the value of the leftmost node

//Replace 100 with 70


//ptr - > num = ptr1 -> num;
○ Free the leftmost node.
//ptr-> right = NULL ;
//free (ptr1) ;

Example 2: Delete 300

1. Move one node to the right 300 -> 400


// ptr1 = ptr -> right
2. Traverse all the way to the left node
// while (ptr1 -> left != NULL)
{
ptr2 = ptr1; // to follow ptr1
ptr1 = ptr1 -> left; // move until NULL
}
3. Replace the value of the node to be deleted
with the leftmost node
// ptr -> num = ptr1 -> num;
//300 will be replaced by 320
4. ptr2 -> left = NULL ;
// 350 -> NULL
5. free (ptr1)
Example 3: Delete 300 ( In this example 320 has a child (330))

1. Move one node to the right 300 -> 400


// ptr1 = ptr -> right
2. Traverse all the way to the left node
// while (ptr1 -> left != NULL)
{
ptr2 = ptr1; // to follow ptr1
ptr1 = ptr1 -> left; // move until NULL
}
3. Replace the value of the node to be
deleted with the leftmost node
// ptr -> num = ptr1 -> num;
//300 will be replaced by 320
4. ptr2 -> left = ptr1 -> right;
//connect ptr2 to the nearest node
// 350 -> 330
5. free (ptr1)
Example 4: Delete 300 ( In this example 400 -> left is NULL but 400 has a child (500))

1. Move one node to the right 300 - 400


// ptr1 = ptr -> right
2. Traverse to the left node
// while (ptr1 -> left != NULL)
{
ptr1 = ptr1 -> left;
}// in this case 400 -> left is already NULL
and the loop terminates.
3. Replace the value of the node to be
deleted with the leftmost node
// ptr -> num = ptr1 -> num;
//300 will be replaced with 400
4. ptr -> right = ptr1 -> right;
// 400 -> 500
Deleting a Node IN C PROGRAM: The node to be deleted has 2 children

bool delete_Two_Children( ndPtr *ptr, ndPtr *ptr1)


{
int r;
ndPtr ptr2;
*ptr1 = (*ptr) -> right; // move one node to the right

while ((*ptr1) -> left != NULL)


{
ptr2 = *ptr1;
*ptr1 = (*ptr1) -> left ;
} //end of while

(*ptr) -> num = (*ptr1) -> num;

if ((*ptr1) -> left == NULL)


{
if (*ptr1 -> right == NULL) // A1 Example 1
(*ptr1) -> right = NULL ;
else
(*ptr1) -> right = (*ptr1) -> right; //A2 Example 4
} //end of if

else
{
if ((*ptr1) -> right == NULL )
ptr2 -> left = NULL; // B1 Example 2
else
ptr2 -> left = *ptr1 -> right; // B2 Example 3
}//end of else

free (*ptr1);
return true;
} //end of program

Group A:
A1: (*ptr1) -> right = NULL ; // Example 1
A2: (*ptr1) -> right = (*ptr1) -> right; // Example 4

Group B: else is group B


B1: ptr2 -> left = NULL; // Example 2
B2: ptr2 -> left = *ptr1 -> right; // Example 3

● Inorder Predecessor
○ Starting at the node to be deleted, move one node to the left then traverse
rightward all the way to the rightmost node
○ Replace the value of the node to be deleted with the value of the rightmost node
//Opposite of Inorder Predecessor
//Replace with the largest value but is less than 300 (if 300 is supposed be deleted)
//Example 2: Replace 300 with 250
//In the program, all left will be changed to right and vice versa

Nov 13, 2023

EXAMPLE PROGRAM OF BINARY SEARCH TREE

#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <Windows.h>

#define F while (getchar() != '\n')

typedef struct
{
char studId[5];
char studName[20];
char studDegree[10];
}STUDENT;

typedef struct nodePtr *ndPtr;


struct nodePtr
{
STUDENT stud;
ndPtr left;
ndPtr right;
}STUDNODE;

STUDENT input_StudInfo(void);
void add_Node(ndPtr *, STUDENT);
bool view_StudentRecord(ndPtr, char[], STUDENT *);
void view_AllStudentRecord(ndPtr);
bool search_Delete(ndPtr *, ndPtr *, char[]);
bool delete_LeafNode(ndPtr *, ndPtr *, ndPtr *);
bool delete_OneChild(ndPtr *, ndPtr *, ndPtr *);
bool delete_TwoChildren(ndPtr *, ndPtr *);
bool edit_StudentDegree(ndPtr *);
void input_SearchKey(char sKey[]);
void display_StudentRecord(STUDENT);

int main(void)
{
int choice;
bool found, deleted, edited;
char sKey[5];
STUDENT s;
ndPtr root = NULL, ptr, ptr1;
do{
system("cls");
printf("\n\n\t1] Add a New Student Record");
printf("\n\t2] View Specific Student Record");
printf("\n\t3] View All Student Records");
printf("\n\t4] Edit a Student Record");
printf("\n\t5] Delete a Student Record");
printf("\n\t6 Exit");
printf("\n\n\tChoice: ");
scanf("%d", &choice);
switch(choice)
{
case 1: s = input_StudInfo();
add_Node(&root, s);
break;
case 2: input_SearchKey(sKey);
found = view_StudentRecord (root, sKey, &s);
if (found)
display_StudentRecord(s);
else
printf("\n\n\tStudent record not
found...");
getch();
break;
case 3: if(root != NULL)
view_AllStudentRecord(root);
else
printf("\n\n\tNo data is available...");
getch();
break;
case 4: input_SearchKey(sKey);
ptr = root;
found = search_Delete(&ptr, &ptr1, sKey);
if (found)
edited = edit_StudentDegree(&ptr);
else
printf("\n\n\tRecord not found...");
getch();
break;
case 5: input_SearchKey(sKey);
ptr = root;
found = search_Delete(&ptr, &ptr1, sKey);
if (found)
{
if((ptr->left == NULL ) && (ptr->right ==
NULL))// leaf
deleted = delete_LeafNode(&root,
&ptr, &ptr1);
else if ((ptr->left !=NULL ) &&
(ptr->right != NULL))// has two children
deleted = delete_TwoChildren(&ptr,
&ptr1);
else
deleted = delete_OneChild(&root,
&ptr, &ptr1);
}//end of if case 5
else
printf("\n\n\tRecord not found...");
getch();
break;
case 6: printf("\n\n\tProgram is closing...");
Sleep(3000);
break;
default: printf("\n\tInvalid choice...");
getch();
}//end of switch
}while (choice != 6);
return 0;
}//end of int main function

STUDENT input_StudInfo(void) {
STUDENT s;
F;
printf("\n\n\tEnter Student ID (4 characters): ");
gets(s.studId);

printf("\n\tEnter Student Name (up to 19 characters): ");


gets(s.studName);

printf("\n\tEnter Student Degree (up to 9 characters): ");


gets(s.studDegree);

return s;
}

void add_Node(ndPtr *root, STUDENT s)


{
int r;
ndPtr ptr, ptr1, temp = malloc(sizeof(STUDNODE));
temp->stud = s;
temp->left = NULL;
temp->right = NULL;
if(*root != NULL)
{
ptr = *root;
while (ptr != NULL)
{
ptr1 = ptr;
r = strcmp(temp->stud.studId, ptr->stud.studId);
if (r <= 0 )
ptr = ptr->left;
else
ptr = ptr->right;
}//end of while ptr != NULL
r = strcmp(temp->stud.studId, ptr1->stud.studId);
if ( r<= 0)
ptr1->left = temp;
else
ptr1->right = temp;
}// end of if *root != NULL
else
*root = temp;
temp = NULL;
return;
}

void view_AllStudentRecord(ndPtr root)


{
if(root->left != NULL)
view_AllStudentRecord(root->left);
printf("\n\n\tStudent ID: %s", root->stud.studId);
printf("\n\tStudent Name: %s", root->stud.studName);
printf("\n\tStudent Degree: %s", root->stud.studDegree);
if(root->right != NULL)
view_AllStudentRecord(root->right);
}

void input_SearchKey(char sKey[])


{
F;
printf("\n\tStudent ID: ");
gets(sKey);
return;
}

bool view_StudentRecord(ndPtr root, char sKey[], STUDENT *s)


{
int r;
bool found = false;
ndPtr ptr = root;
while (ptr!=NULL)
{
r = strcmp(sKey, ptr->stud.studId);
if (r == 0)
{
found = true;
*s = ptr->stud;
break;
}
else if (r < 0)
ptr = ptr -> left;
else
ptr = ptr -> right;
}//end of while ptr!=NULL
return found;
}

void display_StudentRecord(STUDENT s)
{
system("cls");
printf("\n\n\tID: %s", s.studId);
printf("\n\n\tName: %s",s.studName);
printf("\n\n\tDegree: %s",s.studDegree);
getch();
return;
}

bool search_Delete(ndPtr *ptr, ndPtr *ptr1, char sKey[])


{
int r;
bool found = false;
while(*ptr != NULL)
{
r = strcmp(sKey,(*ptr)->stud.studId);
if (r==0)
{
found = true;
break;
}
else
{
*ptr1 = *ptr;
if (r<0)
*ptr = (*ptr)->left;
else
*ptr = (*ptr)->right;
}
}//end of while
return found;
}

bool delete_LeafNode(ndPtr *root, ndPtr *ptr, ndPtr *ptr1)


{
int r;
if (*root == *ptr)// root is leaf
*root = NULL;
else
{
r = strcmp((*ptr)->stud.studId,(*ptr1)->stud.studId);
if(r<0)
(*ptr1)->left=NULL;
else
(*ptr1)->right=NULL;
}
free(*ptr);
return true;
}

bool delete_OneChild(ndPtr *root, ndPtr *ptr, ndPtr *ptr1)


{
int r;
if(*root == *ptr)
{
if ((*ptr)->left == NULL)
*root = (*root)-> right;
else
*root = (*root)-> left;
}
else
{
r = strcmp((*ptr)->stud.studId,(*ptr1)->stud.studId);
if(r<0)//ptr is to the left of ptr1
{
if((*ptr)->left == NULL)
(*ptr1)->left = (*ptr)->right;
else
(*ptr1)->left = (*ptr)->left;
}//end if inside else
else
{
if((*ptr)->left == NULL)
(*ptr1)-> right = (*ptr)->right;
else
(*ptr1)-> right = (*ptr)-> left;
}//end else inside else
}//end else
free(*ptr);
return true;
}

bool delete_TwoChildren(ndPtr *ptr, ndPtr *ptr1)


{
// this uses inorder successor
int r;
ndPtr ptr2;

*ptr1 = (*ptr)-> right; // move one node to the right


//traverse all the way to the leftmost node
while((*ptr1)->left!=NULL)
{
ptr2 = *ptr1;
*ptr1 = (*ptr1)->left;
}
(*ptr)->stud = (*ptr1)->stud;
if((*ptr)->right == *ptr1) // the leftmost node is the one to the right
of ptr
{
if((*ptr1)->right == NULL)
(*ptr)->right = NULL;
else
(*ptr)->right = (*ptr1)-> right;
}
else
{
if ((*ptr)->right == NULL)
ptr2 = NULL;
else
ptr2 = (*ptr1)->right;
}
free (*ptr1);
return true;
}

bool edit_StudentDegree(ndPtr *ptr)


{
// assumption - only the degree is editable
char v_Degree[10];
F;
printf("\n\n\tDegree: ");
gets(v_Degree);
strcpy((*ptr)->stud.studDegree,v_Degree);
return true;
}

BinarySearchTree.c

Nov 21, 2023

HASHING

● Hashing is the process of mapping large amounts of data items to a smaller table with
the help of a hashing function.
● The essence of hashing is to facilitate the next level searching method when
compared with the linear or binary search.
● A hash function is one which maps an element’s key into a valid hash table index ,
h(key) => hash table index

//
- Difference of Array and Hashing: Array Index 0 , Fill it up from left to right VS In
Hashing, Calculate of the index , result of the calculated is where data is placed.

Applications of Hash Tables

● Database systems
● Symbol tables
● Data dictionaries
● Network processing algorithms - route lookup, packet classification, and network
monitoring
● Browser Caches

//
- Data dictionaries - what table you have , who what when
- Network processing of algo - routing algorithm
- Browser Caches - change the color of the link after clicking the link
Hash Tables are not Suitable for:

● Problems for which data ordering is required


● Problems having multidimensional data
● Prefix searching especially if the keys are long and of variable-lengths

//
- Hashing will not work if it is sequential why? - this is not arranged in order , it depends
on the calculation.
- It will return one value only
- Prefix will not work with hashing when searching for a specific subject.

Hash Functions Properties

● A hash function maps key to integer - Integer should be between [0, TableSize-1]
● A hash function can result in a many-to-one mapping (causing collision)
● Collisions cannot be avoided but its chances can be reduced using a “good” hash
function

//
- Always an integer , from zero to Tablesize - 1
- Many are assigned to one address , all the data collides but you should not place Data
2 and Data 3 to index 2 or two different values in both indexes.

“Good” Hash Function Properties

1. Reduced chance of collision


● Different keys should ideally map to different indices
● Distribute keys uniformly over table

2. Should be fast to compute


What to do with strings as keys? OPTION 1
Option 1:
● Add up character ASCII values (0 - 255) to produce integer keys
● If the string is “abcd”: a = 97, b = 98, c =99, and d = 100
● Key(“abcd”) = 97 + 98 + 99 + 100 = 394
● Possible issue:
○ Anagrams will map to the same index
○ h(“abcd”) == h(“dcba”)
// Modulo
// convert a string to numeric

IN C PROGRAM :

int string_Int_Opt1(char str[])


{
int sum_key = 0 , j , length;
length = strlen(str);

for (j = 0 ; j < length; j++)


sum_key = sum_key + str[j];
return sum_key;
}
//problem is anagram , the characters inside are valued the same even if they are arranged
differently

What to do with strings as keys? OPTION 2


Option 2:
● Consider only the first 3 or last 3 characters of the string as base-27 integer (26 letters
plus space)
● Key = S[0] + (27 * S[1]) + (272 * S[2])
● Let string s = “abcd” and taking the first three
● Key(s) = ‘a’ + (27 * ‘b’) + (272 * ‘c’)
● Key(s) = 97 + (27 * 98) + (272 * 99) = 97 + 2,646 + 72,171 = 74,914
○ Possible issue:
■ If the first three or last three are the same : abcd abce abcm abcz
IN C PROGRAM:

//define B 27
int string_Int_Opt2(char str[])
{
int sum_key = 0 , j , length;
for (j = 0; j < 3; j++)
{
sum_key = sum_key + (str[j] * power(B, j ));
}
return sum_key;
}
//power or pow //will loop three time //s represents the array //declare 27 as a constant

What to do with strings as keys? OPTION 3

// Use all N characters


// banana 3 unique characters // use a prime number
// k = 5 but that is if the string is like banana
//string is abcdef = 6 unique characters
// choose a prime number greater than 6 , like 7 or 101
// i will be loop control variable
// L is calculate the length

Dec 5, 2023
Selecting Hash Functions

Modular Arithmetic
● Compute the index by dividing the key with some value and use the remainder as the
index.
index := key MOD table_size
● The key has to be an integer.
● For the values of table_size, powers of 2 should be avoided.
● Good values for table_size are prime numbers.
In C PROGRAM:

int modular_Hashing (int key)


{
int index;
index = key % size;
return index;
}
//the table size must be prime
Truncation

● Ignoring part of the key and using the rest as the array index.
● For Example: If student id’s are the key 928324312 then select just the last three digits
as the index i.e. 312 as the index.
○ The table size has to be at least 999.
● The problem with this approach is that there may not always be an even distribution
throughout the table.

//It will get part of the key and then that part will become the index of the data
//For Example: last 3 digit,
//It does not mean it will always be 3 digits, can be 5 if the company is large
//How do we get the last digit, last 3, last 2 , last 1
//atleast 999 , but it is not prime why? Because in modular the table size is the divisor , in
truncating the table size is not the divisor so it is ok if it is not a prime number

//three zeroes will extract three digits

EXAMPLE: Data 1
//the problem is when you have 12576, 99567 , both will collide because they have the same
last 3 digits, but happens lesser than modular

IN C PROGRAM:

int truncation (int key)


{
int index;
index = key % 1000; // last three digits
return index;
}
// this function will get the last three digits of the key

Folding

• It involves splitting keys into two or more parts and then combining the parts to form the
hash addresses.
• Very useful if we have keys that are very large.
• Fast and simple especially with bit patterns.
• Suppose key = 25936715. divide it into two groups [2593 & 6715], then add them to obtain
the hash value. So, adding 2593 & 6715, we will have a hash value of 9308.
• The size must be 10,001 [with indexes 0 – 10,000].

//it depends on the company how many split or parts they will do with the data

Example:
SPLIT: first group: first two digits
temp = key - last three
12576 - 567 = 12000

First two = temp div 1000


= 12000 div 1000
= 12

Second group: last three digits and then well add


Last three = key % 1000;
Last three = 12576 % 1000 = 576
Index = firsttwo + last three;

In C PROGRAM:

int truncate (int key)


{
int index, firstTwo, lastThree, temp;
lastThree = key % 1000;
temp = key - lastThree;
firstTwo = temp / 1000;
index = firstTwo + lastThree;
return index;
} OR
int truncate (int key)
{
int index, firstTwo, lastThree, temp;
lastThree = key % 1000;
firstTwo = key/ 1000;
index = firstTwo + lastThree;
return index;
} // the 1000 depends, it depends on how many digits will have the same amount of zero

Dec 7, 2023

MID SQUARE

• The key is squared and the middle part of the result taken as the hash value
• Works well if the keys do not contain a lot of leading or trailing zeros.
• Non-integer keys have to be preprocessed to obtain corresponding integer values

// key = 456 //square this //extract the middle part


//assuming 2 digits to be extracted
//1. Modulo //2. Fodling
Collision Resolution
The algorithm for inserting a value M into a table:

1. compute the position at which M ought to be stored, P = H(key(M)).


2. If position P is not OCCUPIED, store M there.
3. If position P is OCCUPIED, compute another position in the table; set P to this value and
repeat (2)-(3).

//modular arithmetic //calculate the index // Variable P //id will be the key
//linear probe is recalculation of collision

Linear Probing
• The simplest method
• P = (1 + P) mod TABLE_SIZE
• Issue with linear probing is clustering.
Double Hashing

● A very simple way to sharply reduce clustering


● increment P by an amount that depends on the Key
● P = (P + INCREMENT(Key)) mod TABLE_SIZE
● INCREMENT(Key) = 1 + (Key mod INCR)
○ Where INCR is a prime number less than the table size

//prime number lesser than the table size, for example table size is 7 then prime numbers are
5/3/2
//Should declare INCR as a PRIME NUMBER
//Formula for double hashing

Formula for Double Hashing:

Replace else on first example (linear probe to double hash):

You might also like