Follow along with the tutorial found here: https://www.programiz.com/c-programming/c-structures
Make sure to code the examples and manipulate the code to understand how it works.
Follow along with the tutorial found here: https://www.programiz.com/c-programming/c-structures
Make sure to code the examples and manipulate the code to understand how it works.
I found some great tutorials on C pointers. Attempt the tutorials below by coding the examples found within the tutorials.
https://www.programiz.com/c-programming/c-pointers
https://www.programiz.com/c-programming/c-pointers-arrays
https://www.programiz.com/c-programming/c-pointer-functions
(optional) https://www.programiz.com/c-programming/c-dynamic-memory-allocation
(optional) – https://www.programiz.com/c-programming/c-pointer-examples
The linked list ADT consists of nodes that are linked together by a pointer. We can think of a node programmatically as a C Structure, Node, which contains 2 variables:
Our linked list class contains one global variable of type node pointer, which points to the first item in the list.
The list can be thought of a queue of people in a line with name tags (data), however, in this queue, people can join at the front, back and cut in line.
Operations performed on a linked list are shown below:
| Operation | Explanation | Example |
| add(value) or addLast(value) | Adds the value to the end of the list. | Someone joins the end of the line |
| addFirst(value) | Adds a value to the top/front of the list | Someone joins the line from the front. |
| insert(value, i) | Adds/inserts a value at location i counting from top/front | Someone cuts in line at the become the ith position in the list. If i exceeds the size of the list, the person is added to the end of the list |
| size() | Returns the size of the list | Find out the amount of people on the line |
| isEmpty() | Returns true if the queue is empty, i.e, size==0 | Find out if the line is empty. |
| delete(i) | Deletes/removes a node at location i, and returns the value | Someone leaves the line from the ith location |
Performing the operations above is not as straightforward as our previous ADTs. In this discussion, we examine the algorithms for performing operations in the list.
First<--null
AddFirst(newValue)
{
Create the new Node newListItem
newListItem.value <-- newValue
newListItem.next <--first
first<--newListItem
}
AddLast(newValue)
{
Create the new Node newListItem
newListItem.value newValue
If the list is empty Then
first <-- newListItem
newListItem.next <-- NULL
Else
Create Nodes currentNode, previousNode
while(currentNode!=NULL)
{
previousNode=currentNode;
currentNode=currentNode->next;
}
previousNode->next=newNode;
}
The rest of the operations on the linked list were omitted:
| Number | Operation |
| 1 | size() |
| 2 | isEmpty() |
| 3 | insert(value, i) |
| 4 | delete(i) |
Using to the algorithms above as a guide, write separate algorithms which implements the operation listed in the table above.
(Solution here: Solution: Singly Linked List -In class assignment/homework 1
//Note that the operations from the in class assignment/homework are not included.
#include <stdio.h>
#include <stdlib.h>
/*keep track of the size of the list.
Initially, the size is 0,
thus the count is 0.*/
int count = 0;
/*create a structure called "Node_n"
and give it a type definition
named Node.
We do this to avoid using the
"struct" keyword everytime
we declare a Node_n structure.
It's simply a quality of life improvement
*/
typedef struct Node_n
{
int data;
struct Node_n * next;/*note that we cant
use the typedef here ,
e.g "struct Node * next;"
since the type definition
has not been created yet.
if used it will produce
a warning when you try to
assign Node Structures to
each other such as in the
add function etc:
"assignment from incompatible
pointer type
[-Wincompatible-pointer-types]|"
*/
} Node;
/*we declare Node structure to
represent the first item at the
start of the list.
It is assigned a mull pointer value,
which can be thought of a value of
0 for the pointer.
*/
Node * first;
/*functionDeclarations
that were IMPLEMWNTED
in this code*/
void addFirst(int value);
void addLast(int value);
int size();
void printList();
/*functionDeclarations
that were NOT IMPLEMENTED
in this code. It was left
for student discussion
on how this should be implemented*/
void deleteNode(int location);//for delete(i)
//algorithm from above
void insert(int value, int location);
int main()
{
//initialization
first=NULL;
//codetesting
addFirst(2);
addFirst(1);
addLast(3);
addLast(4);
printList();
return 0;
}
void addFirst(int value)
{
//create new node....
/*we use malloc
to allocate a portion of
RAM memory to store the
data contained within a node.
The amount of memory allocated is
the size of the node datatype.
the newly allocated node
Node structure's pointer is now assigned
to our pointer named "newNode"
note that "sizeof" is a unary operator
much like the address operator "&"
sizeof only requires parentheses
only when it is evaluating a data type
so :
int x;
printf("%d", sizeof x);
would complile and work fine.
*/
Node * newNode = malloc(sizeof (Node));
/*Question: how different would it be create
new node without a pointer and achieve the
same result in the line above?*/
//.....store the data in the new node
newNode->data=value;
/*It is best practice to check to see of the list
is empty and not based on the integer size being
zero. This is because most list traversal happens
through pointers and must be stopped when null
is reached. If using size to check if it's empty,
the programmer may forget to set the last link
in the list to be null resulting in infinite
traversal looping*/
//if the list is empty..
if( first==NULL)
{
first=newNode;
first->next=NULL;/*set next to null,
indicating that
this is the last item
in the list so far*/
}
else// the list contains items///
{
//create links..
newNode->next=first;
first=newNode;
//recall that the list is null terminated still.
}
count++;
}
/*Future exercise 3:
adde a node called last which always
stores the last item in the list.
modify addFirst to ensure that
add first is being tracked.
modify this code to omit the
traversal using the while loop*/
void addLast(int value)
{
/*What would happen if we used node
structures instead of pointers?
try to implement this function without
delaring pointers,
i.e declare newNode,currentNode,
previousNode as a node and not a pointer
to a Node
Answer: when current is set to null, we will
not be able to dereference the null value to
a node so that current can now bw assigned
to a NULL node. There is no such thing
as a null struct, only null pointers*/
Node * newNode = malloc(sizeof(Node));;
newNode->data = value;
newNode->next = NULL;
//if the list is empty
if(first==NULL)
first=newNode;
else
{
Node * currentNode , * previousNode;
currentNode=first;
previousNode=first;
/*while the end of the list
has not been reached*/
while(currentNode!=NULL)
{
previousNode=currentNode;
currentNode=currentNode->next;
}
/*loop terminates with previousNode
being the last one in the list
*/
previousNode->next=newNode;
}
count++;
}
void printList()
{
printf("Start list...\n");
Node * current = first;
while (current !=NULL)
{
printf("%d\n", current->data);
current=(Node *)(current->next);
}
printf("End list...\n");
}
int size()
{
return count;
}
The rest of the operations on the linked list were omitted in the code:
| Number | Operation |
| 1 | IsEmpty() |
| 2 | Insert(int value, int i) |
| 3 | deleteNode(i) |
Using to the Code above as a guide, write functions which implements the operation listed in the table above. Update your main method to test the operations so that they behave as expected.
Solution here: Solution: Singly Linked List -In class assignment/homework 2
© 2020 Vedesh Kungebeharry. All rights reserved.
2024 – 09 – 21

In a binary search, an ordered list is searched for a key starting with the item at the middle of the list. If the item is not found at the location , a determination is made on which half of the list may contain the key, either the upper or lower half. This method is applied to search the midpoint of the half of the list which may contain the key. This repeats until the key is found, or until the search space is reduced to a single location and the list can no longer be divided into halves. If the key is found, the location of the element is returned, otherwise a dummy value is returned (e.g -1)
This method of searching fall in the category of algorithms called “Divide and Conquer” since a large portion of the search space is split and discarded on each iteration.
Table of Contents
Given a list of items of a finite size and a Key we traverse the list to find the key and output the location of the key found in the list.
Consider the scenario where we have a list, with unique items (in an array) and we wish to find a key:
Algorithm:
//initialization
//Assume our data is stored in an array named list of size N.
list[0..N-1] = {Assume a sorted list}
first=1
last=N-1
result=-1 //used to store the index of a successful search. If result is -1 , the search has failed
middle = (first-last)/2
while (first<=last)
if list[middle]==key then
result= middle
break
else if key<list[middle] then
last=middle-1;
else
first=middle+1;
endif
middle=(first-last)/2 + first
endif
endwhile
return result.
/*
Demo: Searching a sorted list using
binary search
*/
#include <stdio.h>
#include <stdlib.h>
int binarySearch(int key, int list[], int listSize);
int main()
{
int list[10];
list[0]=5;
list[1]=10;
list[2]=15;
list[3]=20;
list[4]=25;
list[5]=30;
list[6]=35;
list[7]=40;
list[8]=45;
list[9]=50;
int key;
printf("\nenter a search key\n");
scanf("%d",&key);
while (key!=-1)
{
int result = binarySearch(key,list,10);
printf("\nSearch result %d\n",result);
printf("\nenter a search key\n");
scanf("%d",&key);
}
return 0;
}
int binarySearch(int key, int list[], int listSize)
{
/*we use first and last to represent a
portion of the array. Initially, first and last
points to the start of the array and the end of
the array respectively. Middle indexes the location
to the middle of the array.
*/
int result=-1;//-1 represents a failed search
int first=0;
int last=listSize-1;
int middle = (last-first)/2;
while (first<=last)//while first and last have not crossed...
{
if(key==list[middle])//if the key is found....
{
result=middle;
return result;//return the current index and exit function
}
else//the key was not found
{
if(key<list[middle])//if the key would be found
//from first to middle
last=middle-1;//we now search the lower half
else //key would be found from middle to last
first=middle+1;//we now search the upper half
middle=((last-first)/2)+first;//find the new midpoint.
}
}
return result;
}
/*
Demo: Searching a sorted list using
binary search implemented using recursion
*/
#include <stdio.h>
#include <stdlib.h>
int binarySearch(int key, int list[], int first, int last);
int main()
{
int list[10];
list[0]=5;
list[1]=10;
list[2]=15;
list[3]=20;
list[4]=25;
list[5]=30;
list[6]=35;
list[7]=40;
list[8]=45;
list[9]=50;
int key;
printf("\nenter a search key\n");
scanf("%d",&key);
while (key!=-1)
{
int result = binarySearch(key,list,0,9);
printf("\nSearch result %d\n",result);
printf("\nenter a search key\n");
scanf("%d",&key);
}
return 0;
}
int binarySearch(int key, int list[], int first, int last)
{
/*we use first and last to represent a
portion of the array. Initially, first and last
points to the start of the array and the end of
the array respectively. Middle indexes the location
to the middle of the array.
*/
int result=-1;//-1 represents a failed search
int middle = (last-first)/2+first;
if (first<=last)//if first and last have not crossed...
{
if(key==list[middle])//if the key is found....
{
result=middle;
return result;//return the current index and exit function
}
else//the key was not found
{
if(key<list[middle])//if the key would be found
{ //from first to middle
//we now search the lower half
result= binarySearch(key,list,first,middle-1);
return result;
}
else //key would be found from middle to last
{
result= binarySearch(key,list,middle+1,last);//we now search the upper half
return result;
}
}
}
return result;
}
2023/12/26
Added animated image and link to its source post.
2023/12/17
Fixed binary search algorithm , the element at middle was included every time then a partition made:
else if key<list[middle] then
last=middle;
else
first=middle;
endif
middle=(first-last)/2 + first
It was changed to:
else if key<list[middle] then
last=middle-1;
else
first=middle+1;
endif
middle=(first-last)/2 + first
Added a paragraph on Divide and Conquer
2022/2/3
Added introduction paragraph “In a binary … value is returned (e.g -1)“
Added heading “Binary Search Algorithm”
© 2020 Vedesh Kungebeharry. All rights reserved.
It seems difficult to understand but we can observe the algorithm in action in the following flowchart:

You can download the file here:
https://drive.google.com/file/d/1RvZ-dBvbHf0icL083d7vSnnce3_XDyyj/
See : https://youtu.be/KgqM6sC5Q4M
Implement the algorithm in c with the following modifications:
Create a function with the following functions declaration which will sort any double array using bubble sort:
void bubbleSort(double array[], int sizeOfArray);
© 2020 Vedesh Kungebeharry. All rights reserved.
Definition: Debugging is the process of finding and fixing errors in program code.
Definition: Factoring (Decomposition) is the breaking of a complex task to its atomized sub parts. The goal of factoring is to reach a level of detail that can be represented in an algorithm and eventually programming code.
Definition: Refactoring – Changing program code’s structure to improve readability or efficiency without changing it’s behavior; or, to change a code’s factoring
Copy and paste the following code into the main.c file of a new project:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
float a,b,c,D,root1,root2;
printf("Please enter a value for a...\n");
scanf("%f",a);
printf("Please enter a value for b...\n");
scanf("%f",&b);
printf("Please enter a value for c...\n");
scanf("%f",&c);
printf("\n");
D=(b*b)-(4*a*c);
if(D<0)
{
printf("no roots\n Exiting program...\n");
}
else if (D=0)
{
root1=(b*b)/(2*a);
printf("Equation has only one root = %.2f \n Exiting program...\n ");
}
else
{
root1=((b*b)-sqrt(D))(2*a);
root2=((b*b)+sqrt(D))/(2*a);
printf("Roots are %.2f and %.2f \n Exiting program...\n",root1,root2);
}
return 1;
}
© 2020 Vedesh Kungebeharry. All rights reserved.
Required reading: C functions (This is a link to an external website)
Similar to our previous example, create a program which contains:
Note the function declarations. This is necessary for proper execution of our code.
#include <stdio.h>
#include <stdlib.h>
//global variables
double area,volume;
double radius;
const double PI = 3.14;
//function declarations
double Area(double radius);
double Volume(double radius);
void Signature();
int main()
{
//initialization
area,radius,volume = -999;
printf("enter radius\n");
scanf("%lf", &radius);
area = Area(radius);
volume = Volume(radius);
printf("The Area is \t: \t%.2f\n",area);
printf("The Volume is \t: \t%.2f\n",volume);
Signature();
}
double Volume(double radius)
{
return((4/3)*PI*radius*radius*radius);
}
double Area(double radius)
{
return (PI*radius*radius);
}
void Signature()
{
//ASCII Art Generated using https://patorjk.com/software/taag/#p=testall&f=Big&t=kunge
printf("Thanks for using my program! \n");
printf(" _ __ \n");
printf(" | |/ / \n");
printf(" | ' /_ _ _ __ __ _ ___ \n");
printf(" | <| | | | '_ \ / _` |/ _ \ \n");
printf(" | . \.|_| | | | | (_| | __/ \n");
printf(" |_|\_\__,_|_| |_|\__, |\___| \n");
printf(" __/ | \n");
printf(" |___/ \n");
printf("Author: Vedesh Kungebeharry \n");
printf("contact: VKunge@gmail.com \n");
printf("exiting... \n");
}
© 2020 Vedesh Kungebeharry. All rights reserved.
Attempt the 2 c programming exercises below. If you are having a hard time starting, try:
1. Create a program which accepts the radius for a circle/sphere and outputs the volume and maximum cross sectional area. Your program must prompt for input, and produce relevant results.
2. Given the coefficient a b and c of a quadratic equation in the form y=ax^2+bx+c output the solution to the equation when y=0
Solution to Find the roots of a Quadratic Equation:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
float a,b,c,D,root1,root2;
printf("Please enter a value for a...\n");
scanf("%f",&a);
printf("Please enter a value for b...\n");
scanf("%f",&b);
printf("Please enter a value for c...\n");
scanf("%f",&c);
printf("\n");
D=(b*b)-(4*a*c);
if(D<0)
{
printf("no roots\n Exiting program...\n");
}
else if (D==0)
{
root1=(-b)/(2*a);
printf("Equation has only one root = %.2f \n Exiting program...\n ");
}
else
{
root1=((-b)-sqrt(D))/(2*a);
root2=((-b)+sqrt(D))/(2*a);
printf("Roots are %.2f and %.2f \n Exiting program...\n",root1,root2);
}
return 1;
}
© 2020 Vedesh Kungebeharry. All rights reserved.
This post is intended for use in class and review. In this lesson we will observe some multiple choice question examples to provoke thoughts on the fundamental principles governing stack and queue operations.
Note that the multiple choice questions are not included on this website.
If a stack is implemented using a one-dimensional array and the top of the stack is always found at location 0 in the array, how would you implement push and pop?
That is, at the end of any push or pop operation, the top of the stack is stored at location 0.
Write separate algorithms for your push and pop operations.
After considering the scenario above do you think it’s possible to implement a stack using the wrap-around technique (that was used in the implementation of a queue ) to omit the intermediate copying of elements? Consider this scenario where the first element that was pushed onto the stack goes into location 0, and every time a pop operation occurs top is incremented (unless the stack is empty) , and every time a push operation occurs top is decremented.
Justify your conclusion.
Write an algorithm which can be used to reverse the elements of a queue by using a stack. Accomplish this task by only using valid stack and queue operations.
Assuming you are required to write a c program that must use two separate stacks and five separate queues , what modifications would you need to make to the coded implementations that will already demonstrated in class.
Write the algorithm for the dequeue operation in a traditional queue with no wrap around, i.e every time an element is dequeued , all elements of are copied down one location such that location 0 in the array stores the new head of the queue.
© 2020 Vedesh Kungebeharry. All rights reserved.