450 likes | 626 Views
Structured Programming Instructor: Prof. K. T. Tsang. Lecture 9: Linked lists. Static arrays. A “List” is a useful structure to hold a collection of data. So far, we use arrays for lists Examples: List of ten students names int student_names[10];
E N D
Structured ProgrammingInstructor: Prof. K. T. Tsang Lecture 9: Linked lists
Static arrays • A “List” is a useful structure to hold a collection of data. • So far, we use arrays for lists • Examples: List of ten students names int student_names[10]; List of temperatures for the last two weeks double temperature[14]; We have to know exactly how big is the array (dimension) before we declare it. These are called static arrays.
Dynamic array in C++ • For static array, we have to decide in advance the size of the array, e.g. int myArray[10]; • list using dynamic array int n, *myArray; cin >> n; myArray = new int[n]; In C++ we can allocate an array of any specified size while the program is running using the function new. Use delete to release the memory allocated. delete [] myArray;
Dynamic array in C In C, a block of memory can be allocated using the function malloc, e.g. int *p1, n; cin >> n; //get n while running p1 = (int*) malloc( n * sizeof(int) ); Determine the size of a memory block by the sizeof operator. To release the run-time allocated memory, use the free function; free(p1);
Link Data 20 45 75 85 Linked Lists: Basic Idea • A linked list is an orderedcollection of data • Each element of the linked list has • Some data • A link to the next element • The link is used to chain the data • Example: A linked list of integers:
20 45 add(75), add(85) 20 45 75 85 delete(85), delete(45), delete(20) Linked lists: dynamically controlable The list can grow and shrink dynamically. 75
Linked list: declaration #include <iostream> using namespace std; struct Node{ int data; //data stored Node *next; //point to next node }; typedef Node* NodePtr;
“typedef” C allows programmer to define new variable types with “typedef” statement. typedef int boolean; //define new type boolean boolean flag; //declare variable of new type typedef int group[10]; group gr1; for (int i=0; i<10; i++) gr1[i] = 0; typedef Node* NodePtr; NodePtr Head; // same as: Node* Head;
Simple way to create a linked list int main() { struct Node { int data; //contains useful information Node* next; //points to next element or NULL }; struct Node n1, n2, n3; n1.data = 12; n2.data = 43; n3.data = -59; n1.next = &n2; n2.next = &n3; n3.next = NULL; //last in the list print_list(&n1); int n = count_nodes(&n1); printf(“total number of nodes is &d\n”, n); return 0; }
Print & count the list recursively void print_list(Node *a_node) { if (a_node == 0) { printf(“ empty list\n”); return; } printf(“%d >> ”, a_node->data); if (a_node->next == 0) printf(“\n”); else print_list(a_node->next); } int count_nodes(Node *a_node) { if (a_node == 0) return 0; else return 1+count_nodes(a_node->next); }
Dynamically created linked lists • Node : Data + Link • Definition struct Node { int data; //contains useful information Node* next; //points to next element or NULL }; • Create a Node Node* p; p = new Node; //allocated memory in C++ p = (Node *) malloc(sizeof(Node));//in C • Delete a Node delete p; //free memory in C++ free(p); //in C
Accessing linked List members • Access fields in a node (*p).data; //access the data field (*p).next; //access the pointer field Or it can be accessed this way p->data //access the data field p->next //access the pointer field
Creating a linked list with pointer • Define the struct struct Node { int data; //contains useful information Node* next; //points to next element or NULL }; • Define a pointerthat points to the first node of the linked list. Node *head; • When the linked list is empty then head is NULL. head = 0; • Otherwise, allocate the necessary memory. head = (Node *) malloc(sizeof(Node)); • Then initialize. head->data = 34; head->next = 0; //end of the linked list
Function to create head of linked list Node* create_head(int idata) { Node *head; head = (Node *) malloc(sizeof(Node)); head->data = idata; head->next = 0; return head; }
Adding more element to the linked list Node* add_node_after(Node *lead, int idata) { Node *newnode; newnode = (Node *) malloc(sizeof(Node)); newnode->data = idata; newnode->next = lead->next; lead->next = newnode; return newnode; }
Assignment Write a function to switch 2 neighboring nodes (i.e. swap the data content between the 2 nodes). //swap the data content between p and p->next. If p-> is 0, return 0, otherwise return the same p. Node * switch_node(Node * p) Use it to write a sort_node function using the bubble sort algorithm. sort_node(Node * p)
Structured ProgrammingInstructor: Prof. K. T. Tsang Lecture 10: File processing in C
Using Input/Output Files A computer file • is associated with a filename: e.g. input.data • is permanently stored on a secondary storage device (e.g., disk) • can be used to provide input data or receive output data, or both • must be opened before reading it
FILE pointer in C • FILE is a data type defined in stdio.h • All files should be declared as FILE before they are used in C • Then use standard library function fopen to open and return a FILE pointer FILE *fp; fp = fopen (“filename”, “mode”);
Using fopen “Mode” specifies the purpose of opening the file, which can be one of the following: r open for reading only w open for writing only a open for appending (adding) data to it FILE *f1, *f2 f1 = fopen (“data”, “r”); f2 = fopen (“result”, “w”);
Standard streams: provided by stdio.h, need not declare, open or close
Using fclose A file must be closed after all operations on it is completed. Use fclose declared in stdio.h to close file. fclose ( file_pointer ); fclose returns 0 if the file was closed successfully. FILE *f1, *f2; f1 = fopen (“data”, “r”); f2 = fopen (“result”, “w”); .. .. .. fclose (f1); fclose (f2);
Example – open & close file #include <stdio.h> void main() { FILE *f1; char filename[50]; printf(“Please input a file name: ”); gets(filename); f1 = fopen (filename, “r”); if (f1 == NULL) { printf (“The file: %s cannot be opened”, filename); exit(1); } printf (“The file: %s has been opened successfully for reading”, filename); /*.. Reading from file .. */ fclose (f1); }
Open file & check the returning file pointer Alternatively, use if ((f1 = fopen (filename, “r”)) == NULL) { printf (“The file: %s cannot be opened”, filename); exit(1); /*a system function to end execution gracefully*/ } replacing: f1 = fopen (filename, “r”); if (f1 == NULL) { printf (“The file: %s cannot be opened”, filename); exit(1); }
I/O operations on FILEs Character I/O: char c; fputc (c, f2); //f2 opened for writing c = fgetc (f1); //f1 opened for reading Number I/O: int i1; putw( i1, f2); i1 = getw(f1); String I/O: char str[99]; fgets (str, sizeof(str), f2); str = fputs( str, f2);
/*Example program for using getw and putw functions*/ #include< stdio.h > main() { FILE *f1,*f2,*f3; int number I; printf(“Input Contents of the data file\n”); f1=fopen(“DATA”,”W”); for(I=1;I< 30;I++) { scanf(“%d”,&number); if(number==-1) break; putw(number,f1); } fclose(f1); f1=fopen(“DATA”,”r”); f2=fopen(“ODD”,”w”); f3=fopen(“EVEN”,”w”);
while((number=getw(f1))!=EOF)/* Read from data file*/ { if(number%2==0) putw(number,f3);/*Write to even file*/ else putw(number,f2);/*write to odd file*/ } fclose(f1); fclose(f2); fclose(f3); f2=fopen(“ODD”,”r”); f3=fopen(“EVEN”,”r”); printf(“Contents of the odd file\n”); while(number=getw(f2))!=EOF) printf(“%d%d”,number); printf(“Contents of the even file\n”); while(number=getw(f3))!=EOF) printf(“%d”,number); fclose(f2); fclose(f3); }
Copy content from one file to another #include <stdio.h> main() { FILE *f1, *f2; char c; int n=0; f1 = fopen (“data”, “r”); f2 = fopen (“result”, “w”); while ((c=getc(f1)) != EOF) { putc(c, f2); printf( “%c”, c); n++; } fclose (f1); fclose (f2); printf (“Total characters read: %d\n”, n); }
Output functions //to stdout Input functions //from stdin fgetc and getc are equivalent, except that the latter one may be implemented as a macro.
/* fgetc example: money counter */ #include <stdio.h> int main () { FILE * pFile; int c; int n = 0; pFile=fopen ("myfile.txt","r"); if (pFile==NULL) fprintf(stderr, “Error opening file\n"); else { do { c = fgetc (pFile); if (c == '$') n++; } while (c != EOF); fclose (pFile); printf ("The file contains %d dollar sign characters($).\n", n); } return 0; }
fgets char * fgets ( char * str, int num, FILE * stream ); Reads characters from stream and stores them as a C string into str until (num-1) characters have been read or either a newline or a the End-of-File is reached, whichever comes first.A newline character makes fgets stop reading, but it is considered a valid character and therefore it is included in the string copied to str.A null character is automatically appended in str after the characters read to signal the end of the C string.
/* fgets example */ #include <stdio.h> int main() { FILE * pFile; char mystring [100]; pFile = fopen ("myfile.txt" , "r"); if (pFile == NULL) fprintf(stderr, “Error opening file\n"); else { if ( fgets (mystring , 100 , pFile) != NULL ) printf (“%s”, mystring); fclose (pFile); } return 0; }
Assignment: In cryptography, the Cæsar Cipher can be broken by statistical frequency analysis. By knowing the expected distribution of the letters in the original language of the plaintext, a human can easily spot the value of the shift by looking at the displacement of particular features of the graph. This is known as frequency analysis. For example in the English language the plaintext frequencies of the letters E, T, (usually most frequent), and Q, Z (typically least frequent) are particularly distinctive. The following histogram shows the expected relative frequency distribution of the English alphabets. Write a program to find the relative frequency distribution of the English alphabetsby reading a long input text file that contains an English article and count the number of occurrence of each alphabet (disregard whether it is lower or upper cases), then divide it by the total number of the alphabets. Print your result out to a file and the standard output. Check your answer by comparing it with the histogram shown below.
Using Input/Output Files stream - a sequence of characters • Interactive/console (iostream) cin - input stream associated with keyboard cout - output stream associated with display • file (fstream) ifstream - defines new input stream (normally associated with a file) ofstream - defines new output stream (normally associated with a file)
C++ File-Related Functions #include <fstream> • xxx.open(fname) • connects streamxxxto the external filefname • xxx.get(ch) • Gets the next character from the input stream xxx and places it in the character variable ch • xxx.put(ch) • Puts the character ch into the output stream xxx • xxx.eof() • tests for end-of-file condition • xxx.close() • disconnects the stream and closes the file
<< and >>: Example 1 You can read and write integers, doubles, chars, etc. from files just like cin >> and cout << : #include <iostream> #include <fstream> using namespace std; void main(){ ifstream fin; int A[4], r; fin.open("file1.dat"); // read data file of four integers for(r=0; r<4; r++) // into array fin >> A[r]; fin.close(); ofstream fout; fout.open("file2.dat"); // write data file for(r=3; r>=0; r--) // with numbers reversed fout << A[r] << ' '; fout.close(); }
File I/O: Example 1 file1.dat: 1 2 3 4(eof) file2.dat: 4 3 2 1 (eof)
File I/O: Example 2 // Copies indata.dat to outdata.dat // and counts the number of lines. // Prints file to screen too. #include <iostream> #include <fstream> using namespace std; void main(){ ifstream ins; ofstream outs; int count=0; char next; ins.open("indata.dat"); // open the input file outs.open("outdata.dat"); // open the output file
File I/O: Example 2 while(true){ // loop for each line while(true){ // loop to read each char on line ins.get(next); if(ins.eof() || next== '\n') break; cout << next; outs << next; } count++; cout << endl; if(ins.eof()) break; outs << endl; } ins.close(); outs.close(); cout << "Number of lines copied: " << count << endl; }
File I/O: Example 2 indata.dat: a b c top10 methods to count spaces 1 3(eof) outdata.dat: a b c top10 methods to count spaces 1 3(eof) Output to screen: a b c top10 methods to count spaces 1 3 Number of lines copied: 4