FINAL CCS4 Notes - Chester
FINAL CCS4 Notes - Chester
CCS 4
Study Guide Review
______________________________________________________________________
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;
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;
}
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
Example:
#define s 5
{
int arr [s] = { 3, 6, 2, 8, 10}, j ;
test (&arr[2]);
for (j = 0; j < s; j++)
printf(“%d” , arr[j]);
return 0;
}
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>)
STRINGS
Array of Characters:
Declare a string is the same as declaring an array
//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” ;
Example:
char name [30] = “Chester”;
char name2[30];
strcpy (name2, name);
printf(“%s” , name2) ; // output is Chester
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
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
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.
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.
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;
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\
// *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
// pass by value // 2 curly braces // replace with 60 // still 78 // pass by value , array is by
reference
C2. By Reference
D.
typedef struct
{
char name[20];
int score[3];
}STUDENT
Sep 5, 2023
typedef struct
{
char name[20];
char addr[30];
float balance;
} PERSON;
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
____________________________________________________________________________
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;
}
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
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
IN C PROGRAM:
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
Example:
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
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
begin procedure peek: tos
value <- tos.data
return value
end procedure
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <ctype.h>
#define S 100
int main(void)
{
char postExp[S];
getPostExp(postExp);
calcPostfixValue(postExp);
return 0;
}
nd createStack(void)
{
nd tos = NULL;
return 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
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
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;
}
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;
(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
#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')
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;
}
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;
}
stackBalDelimeter.c
______________________________________________________________________
Tos (top of stack) is not a pointer but a variable = integer placed inside a structure
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
typedef struct
{
int stk[s];
int tos;
}STACK;
2 VERSIONS
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;
}
In C PROGRAM :
bool isFull(int tos)
{
bool full = false;
if (tos == (S - 1))
full ==true;
return full; }
ISEMPTY Operation - ARRAY Implementation
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;
}
C PROGRAM:
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:
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdbool.h>
#include <ctype.h>
//definition of stack
typedef struct
{
char delimeters[S];
int tos;
}STACK;
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;
}
}
}
checkBalExp_Array.c
Oct 2, 2023
QUEUE ADT
// 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
____________________________________________________________________________
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
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:
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
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
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
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.
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
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.
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
_______
typedef struct
{
PROC adtQueue[Q];
int q_front;
int q_rear;
}QUEUE;
// 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
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
In C Program:
bool isEmpty(nd q_rear) // can replace rear with front
{
bool empty = false;
if ( q_rear == NULL)
empty = true;
return true;
}
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;
____________________________________________________________________________
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
Example:
//Characters
INSERT IN C PROGRAM:
typedef struct
{
char studId[5];
char studName[20];
} STUDENT;
SEARCHING IN C PROGRAM:
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 :
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
}//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
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
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;
}
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)
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
// 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
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
● 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
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <Windows.h>
typedef struct
{
char studId[5];
char studName[20];
char studDegree[10];
}STUDENT;
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);
return s;
}
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;
}
BinarySearchTree.c
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.
● 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:
//
- 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.
● 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.
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
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:
● 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
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:
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
In C PROGRAM:
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
//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
//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