Universität Duisburg-Essen PRACTICAL TRAINING TO THE LECTURE Fundamentals of Programming & Procedural Programming Session Eight: Math Functions, Linked Lists, and Binary Trees Name: First Name: Tutor: Matriculation-Number: Group-Number: Date: Prof. Dr.Ing. Axel Hunger Dipl.-Ing. Joachim Zumbrägel Universität Duisburg-Essen Faculty of Engineering, Department Electrical Engineering and Information Technology Computer Engineering Procedural Programming/Lab8 1
Math Functions There are various calculations which involve operations other than the usual four basic operations of addition, subtraction, multiplication and division. For this, C contains a library special for mathematical functions. Though to use these functions the header file <cmath> should be first included. The <cmath> header file provides a collection of functions that enable you to perform common mathematical calculations. For example, you can calculate the square root of 3600.0 with the function call sqrt(3600.0) The above expression evaluates to 60.0. Function arguments can be constants, variables or more complex expressions. If a = 12.0, b = 4.0 and c = 7.0, then the statements root = sqrt(a + b * c); printf("the sqrt of a + b * c is %f", root); calculate and print the square root of 12.0 + 4.0 * 7.0. Exercise 8.1: What is the result of the expression given in the above program? Procedural Programming/Lab8 2
The function ceil(x) Description: This function rounds x to the smallest integer which is not less than x. If we want to ceil the value 5.2 to nearest integer, we can code as: ceil(5.2); This will give us a result as 6. Exercise 8.2: What is the result after the following function is performed? ceil(-5.8); The function cos(x) Description: This function gives us the trigonometric cosine of x in radians. If we want to calculate cos of 0, we can code as: cos(0.0); This will give us a result as 1.0. Exercise 8.3: What is the result after the following function is performed? Procedural Programming/Lab8 3
The function exp(x) Description: This function gives us the exponential function e x. If we want to calculate e 1.0, we can code as: exp(1.0); This will give us a result as 2.71828. Exercise 8.4: What is the result after the following function is performed? exp(5.0); The function fabs(x) Description: This function gives us the absolute value of x. If we want to calculate the absolute value of 5.1, we can code as: fabs(5.1); This will give us a result as 5.1. Exercise 8.5: What is the result after the following function is performed? fabs(-4.67); Procedural Programming/Lab8 4
The function floor(x) Description: This function rounds x to the largest integer which is not greater than x. If we want to floor the value 9.2, we can code as: floor(9.2); This will give us a result as 9.0. Exercise 8.6: What is the result after the following function is performed? floor(-5.9); The function fmod(x,y) Description: This function gives us the remainder of x/y as a floating point number. If we want to calculate 2.6/1.2 as a float, we can code as: fmod(2.6,1.2); This will give us a result as 0.2. Exercise 8.7: What is the result after the following function is performed? fmod(9.6,3.2); Procedural Programming/Lab8 5
The function log(x) Description: This function gives us the natural logarithm of x using base e. If we want to calculate the logarithm of 2.718282, we can code as: log(2.718282); This will give us a result as 1.0. Exercise 8.8: What is the result after the following function is performed? log(8.479065); The function log10(x) Description: This function gives us the logarithm of x using base 10. If we want to calculate the logarithm of 10.0 using base 10, we can code as: log10(10.0); This will give us a result as 1.0. Exercise 8.9: What is the result after the following function is performed? log10(200.0); Procedural Programming/Lab8 6
The function pow(x,y) Description: This function gives x raised to power y (x y ). If we want to calculate 3 raised to power 5, we can code as: pow(3,5); This will give us a result as 243. Exercise 8.10: What is the result after the following function is performed? pow(5,.2); The function sin(x) Description: This function gives us the trigonometric sine of x radians. If we want to calculate the sin of 0, we can code as: sin(0.0) This will give us a result as 0. Exercise 8.11: What is the result after the following function is performed? sin(5.5); Procedural Programming/Lab8 7
The function sqrt(x) Description: This function gives us the square root of x (where x is a nonnegative value) If we want to calculate the square root of 9.0, we can code as: sqrt(9.0); This will give us a result as 3.0. Exercise 8.12: What is the result after the following function is performed? sqrt(5.0); The function tan(x) Description: This function gives us the trigonometric tangent of x in radians. If we want to calculate the tan of 0.0, we can code as: tan(0.0); This will give us a result as 0. Exercise 8.13: What is the result after the following function is performed? tan(5.5); Procedural Programming/Lab8 8
The following program demonstrates the use of pow() function using C syntax. /* example: using pow() function */ #include <stdio.h> #include <math.h> int main() float base; float exponent; float num; printf("enter a value for the base: "); scanf("%f", &base); printf("enter a value for the exponent: "); scanf("%f", &exponent); printf("%f raised to the power %f is %f", base, exponent, pow(base,exponent)); return 0; Procedural Programming/Lab8 9
Exercise 8.13: What is the value of i after each of the following functions are performed? a) i = fabs(4.5); b) i = floor(4.5); c) i = fabs(0.0); d) i = ceil(0.0); e) i = fabs(-5.2); f) i = ceil(-5.2); Procedural Programming/Lab8 10
Linked Lists A linked list is a list of elements in which the elements of the list can be placed anywhere in the memory, and these elements are linked with each other using an explicit link field. This is done by storing the address of the next element in the link field of the previous element. Successive elements are connected by pointers. The last element points to NULL. A linked list can grow or shrink in size during execution of a program and can be made just as long as required. The programmer writes a struct definition which consists of variables holding information about something, and then has a pointer to a struct of its type. Each of these individual struct in the list is commonly known as a node. data next data next data next data next Figure: A Linked List The singly linked list is the easiest of the linked list, which has one link per node. Basic operations of a linked list Create: Creating a linked list Insert: Inserting a new element at the end of the list Append: Appending or adding a node at the end of the list Delete: Deleting a node from the list. Count: Counting the number of nodes of a linked list Procedural Programming/Lab8 11
Creating a Linked list The linked list is created by using an insert() function. The insert() function takes a pointer to an existing list as the first parameter, and a data value with which the new node is to be created as the second parameter. It creates the new node by using the data value and then appends it to the end of the list. It then returns a pointer to the first node of the list. To begin with, the list is empty, so the pointer to the starting node is NULL. Therefore, when insert is called the first time, the new node created by the insert function becomes the start node. The insert() function terminates when it creates a new node with the supplied data value and appends it to the end of the list. Inserting a Node in a List This function takes the start node and data to be inserted as arguments. New node is inserted at the end so, it iterates through the list till we encounter the last node. Then, it allocates memory for the new node and puts data in it. Lastly, it stores the address in the next field of the new node as NULL. A next B next C next D next X Item to be inserted A next B next C next D next X Item to be inserted Procedural Programming/Lab8 12
Deleting a node from the list This function takes the starting node of the linked list as the pointer and the data to be deleted as the arguments. It first, goes to the node for which the node next to it has to be deleted, if that node points to NULL then the element to be deleted is not present in the list. Else, the pointer now points to a node and the node next to it has to be removed, it declares a temporary node (temp) which points to the node which has to be removed. It then stores the address of the node next to the temporary node in the next field of the node pointer. Thus, by breaking the link it removes the node which is next to the pointer (which is also the temp). Because it deleted the node, it no longer requires the memory used for it, so the free() function will deallocate that memory. Item to be deleted A next B next C next D next Deleted item A next B next C next D next Procedural Programming/Lab8 13
The following example shows us how to insert a node, delete a node, to display the elements of the list, and to determine the size of the linked list after it is created: #include<stdio.h> #include<stdlib.h> struct node int data; struct node *next; *head; /* A function to append a node at the end of the linked list */ void append(int num) struct node *temp,*right; temp = (struct node *)malloc(sizeof(struct node)); temp->data = num; right = (struct node *)head; while(right->next!= NULL) right = right->next; right->next = temp; right = temp; right->next = NULL; void add(int num) struct node *temp; temp = (struct node *)malloc(sizeof(struct node)); temp->data = num; if (head == NULL) head = temp; head->next = NULL; else temp->next = head; head = temp; void addafter(int num, int loc) int i; struct node *temp,*left,*right; right = head; for(i=1;i<loc;i++) Procedural Programming/Lab8 14
left = right; right = right->next; temp = (struct node *)malloc(sizeof(struct node)); temp->data = num; left->next = temp; left = temp; left->next = right; return; /* A function to insert a node in a singly linked list */ void insert(int num) int c = 0; struct node *temp; temp = head; if(temp == NULL) add(num); else while(temp!=null) if(temp->data < num) c++; temp = temp->next; if(c == 0) add(num); else if(c<nodecount()) addafter(num,++c); else append(num); /* A function to delete a node in a singly linked list */ int delete(int num) struct node *temp, *prev; temp = head; while(temp!=null) if(temp->data == num) Procedural Programming/Lab8 15
if(temp == head) head = temp->next; free(temp); return 1; else prev->next = temp->next; free(temp); return 1; else prev = temp; temp = temp->next; return 0; /* A function to display the values of nodes in a singly linked list */ void display(struct node *r) r = head; if(r == NULL) return; while(r!= NULL) printf("%d ", r->data); r = r->next; printf("\n"); /* A function to count the number of nodes in a linked list */ int nodecount() struct node *n; int count = 0; n = head; while(n!= NULL) n = n->next; count++; return count; Procedural Programming/Lab8 16
/* the main function */ int main() int choice,num; struct node *n; head = NULL; while(1) printf("\nlinked list Operations\n"); printf("---------------\n"); printf("1.insert\n"); printf("2.display\n"); printf("3.size\n"); printf("4.delete\n"); printf("5.exit\n"); printf("please enter your choice: "); if(scanf("%d",&choice)<=0) printf("enter only an Integer\n"); exit(0); else switch(choice) case 1: printf("enter the data values to be placed in a node: "); scanf("%d", &num); insert(num); break; case 2: if(head == NULL) printf("the list is Empty\n"); else printf("the data values in the list are: "); display(n); break; case 3: printf("the size of the list is: %d\n", nodecount()); break; case 4: if(head == NULL) printf("the list is Empty\n"); else Procedural Programming/Lab8 17
printf("enter the value to be deleted: "); scanf("%d", &num); if(delete(num)) printf("%d deleted successfully\n", num); else printf("%d not found in the list\n", num); break; case 5: return 0; return 0; default: printf("invalid option!\n"); The function malloc(); is used to allocate a certain amount of memory during the execution of a program. If the request is granted, the operating system will reserve the requested amount of memory. The space is not initialized and may contain any values initially. Again a pointer is returned to the start of the area if successful, otherwise NULL. When the amount of memory is not needed anymore, you must return it back to the operating system by using the function free(). Procedural Programming/Lab8 18
Exercise 8.14: Write a C program which deletes a node from a singly linked list with the minimum value. Procedural Programming/Lab8 19
Trees Apart from linked lists, trees are another type of dynamical data structures also used in C. They are used on a collection of data items to put into a hierarchical structure. Binary Trees A binary tree is a special case of the tree in which no node of the tree can have a degree of more than 2. The binary tree is made of nodes, where each node contains a "left" pointer, a "right" pointer, and a data element. The "root" pointer points to the topmost node in the tree. The left and right pointers point to smaller subtrees on either side of the node. A null pointer represents a binary tree with no elements, i.e. the empty tree. Root 5 Root node Left and Right subtree pointers 3 9 1 4 12 Figure: A Binary Tree Procedural Programming/Lab8 20
Creating a Binary Search Tree In C, the binary tree is built with a node type like: struct binarytree int val; struct binarytree *right; struct binarytree *left; ; The following example shows us how to create a binary search tree. It creates the binary search tree by using a function called insert, which creates a new node with the data value given to it as an argument, and inserts it into an already existing tree whose root pointer is also passed as an argument. #include<stdlib.h> #include<stdio.h> struct binarytree int val; struct binarytree *right; struct binarytree *left; ; typedef struct binarytree node; /* A function to insert a node in the binary tree */ void insert(node **btree, node *item) if(!(*btree)) *btree = item; return; if(item->val < (*btree)->val) insert(&(*btree)->left, item); else if(item->val > (*btree)->val) insert(&(*btree)->right, item); /* A function to print the value of a node in the binary tree */ Procedural Programming/Lab8 21
void print(node *btree) if(btree->left) print(btree->left); printf("%d\n",btree->val); if(btree->right) print(btree->right); int main() node *currentvalue, *root; int i; root = NULL; for(i = 1; i <= 20; i++) currentvalue = (node*)malloc(sizeof(node)); currentvalue->left = currentvalue->right = NULL; currentvalue->val = rand(); insert(&root, currentvalue); print(root); return 0; Procedural Programming/Lab8 22
Exercise 8.15: Write a C program which uses two functions, first to count the number of leaf nodes of the binary tree and then the second one to delete all the leaf nodes of that binary tree. Procedural Programming/Lab8 23