Vous êtes sur la page 1sur 21

ASSISSGNMENT Q.1. What do you mean by data structure? What are data types? Explain with giving examples?

DATA STRUCTURE
In computer science, a data structure is a particular way of storing and organizing data in a computer so that it can be used efficiently. Different kinds of data structures are suited to different kinds of applications, and some are highly specialized to specific tasks. For example, B-trees are particularly well-suited for implementation of databases, while compiler implementations usually use hash tables to look up identifiers. Data structures are used in almost every program or software system. Data structures provide a means to manage huge amounts of data efficiently, such as large databases and internet indexing services. Usually, efficient data structures are a key to designing efficient algorithms. Some formal design methods and programming languages emphasize data structures, rather than algorithms, as the key organizing factor in software design. A data structure is defined as a way of organizing all the data items that consider not only elements stored but also stores the relationship between those elements. This is of two types 1.Primitive 2.Non Primitive

Data types vs. Data Structures


A data type is a well-defined collection of data with a well-defined set of operations on it. A data structure is an actual implementation of a particular abstract data type. Example: The abstract data type Set has the operations Emptiest(S), Insert(axis), Delete(axis), Intersection(S1,S2), Union(S1,S2), Member(axis), Equal(S1,S2), Subset(S1,S2).

DATA TYPES

Data types are used within type systems, which offer various ways of defining, implementing and using them. Different type systems ensure varying degrees of type safety. Formally, a type can be defined as "any property of a programmed we can determine without executing the program". Almost all programming languages explicitly include the notion of data type, though different languages may use different terminology. Common data types may include:

integers, Booleans, characters, floating-point numbers, Alphanumeric strings.

EXAMPLES:#include < stdio.h > #include < conio.h > #include < alloc.h > #define new node (struct node*) malloc (sizeof (struct node)) struct node { int data; struct node *next; }; struct node *create_list(); void main () { struct node *f; int len; f = NULL; clrscr(); f = create_list(); len = find_len(f); printf("\n length = %d",len); } // main struct node *create_list() { struct node *f,*c,*p; int tdata; f = NULL; printf("\n Enter data ( use 0 to exit ) : "); scanf("%d",&tdata);

while( tdata != 0 ) { c = newnode; if( c == NULL) { printf("\n Insuf. mem. "); exit(0); } c->data = tdata; c->next = NULL; if( f== NULL) f = c; else p->next = c; p = c; printf("\n Enter data ( use 0 to exit ) : "); scanf("%d",&tdata); } //while return(f); } // create list int find_len(struct node *f) { int len=0; struct node *t; if( f == NULL) return(0); t = f; while( t != NULL ) { len++; t = t->next; } return(len); }

Q.2. What do you mean by algorithm,flowchart and pseudocode.Explain it by giving suitable example.Write a program to find largest no. from natural number 1 to 50.

ALGORITHM:A simple definition: A set of instructions for solving a problem. The algorithm is either implemented by a program or simulated by a program. Algorithms often have steps that iterate (repeat ) or require decisions such as logic or comparison.

An very simple example of an algorithm is multiplying two numbers: on first computers with limited processors, this was accomplished by a routine that in a number of loop based on the first number adds the second number. The algorithm translates a method into computer commands. Algorithms are essential to the way computers process information, because a computer program is essentially an algorithm that tells the computer what specific steps to perform (in what specific order) in order to carry out a specified task, such as calculating employees' paychecks or printing students' report cards. Thus, an algorithm can be considered to be any sequence of operations which can be performed by a Turing-complete system.

Examples:int multiply(int x, int y) int sum = 0 while y > 0 sum + x let y - 1 return sum int a = 5 int b = 7 print a,"x", b, "=", multiply(a, b)

FLOWCHART:Flowcharts are used in designing and documenting complex processes. Like other types of diagram, they help visualize what is going on and thereby help the viewer to understand a process, and perhaps also find flaws, bottlenecks, and other less-obvious features within it. There are many different types of flowcharts, and each type has its own repertoire of boxes and notational conventions. The two most common types of boxes in a flowchart are:

a processing step, usually called activity, and denoted as a rectangular box a decision, usually denoted as a diamond.

A flowchart is described as "cross-functional" when the page is divided into different swimlanes describing the control of different organizational units. A symbol appearing in a particular "lane" is within the control of that organizational unit. This technique allows the author to locate the responsibility for performing an action or making

a decision correctly, showing the responsibility of each organizational unit for different parts of a single process. Symbols A typical flowchart from older basic computer science textbooks may have the following kinds of symbols: Start and end symbols Represented as circles, ovals or rounded rectangles, usually containing the word "Start" or "End", or another phrase signaling the start or end of a process, such as "submit inquiry" or "receive product". Arrows Showing "flow of control". An arrow coming from one symbol and ending at another symbol represents that control passes to the symbol the arrow points to. The line for the arrow can be solid or dashed. The meaning of the arrow with dashed line may differ from one flowchart to another and can be defined in the legend. Generic processing steps Represented as rectangles. Examples: "Add 1 to X"; "replace identified part"; "save changes" or similar. Subroutines Represented as rectangles with double-struck vertical edges; these are used to show complex processing steps which may be detailed in a separate flowchart. Example: PROCESS-FILES. One subroutine may have multiple distinct entry points or exit flows (see coroutine); if so, these are shown as labeled 'wells' in the rectangle, and control arrows connect to these 'wells'. Input/Output Represented as a parallelogram. Examples: Get X from the user; display X. Prepare conditional Represented as a hexagon. Shows operations which have no effect other than preparing a value for a subsequent conditional or decision step (see below). Conditional or decision Represented as a diamond (rhombus) showing where a decision is necessary, commonly a Yes/No question or True/False test. The conditional symbol is peculiar in that it has two arrows coming out of it, usually from the bottom point and right point, one corresponding to Yes or True, and one corresponding to No or False. (The arrows should always be labeled.) More than two arrows can be used, but this is normally a clear indicator that a complex decision is being taken, in which case it may need to be broken-down further or replaced with the "pre-defined process" symbol. Junction symbol Generally represented with a black blob, showing where multiple control flows converge in a single exit flow. A junction symbol will have more than one arrow coming into it, but only one going out. In simple cases, one may simply have an arrow point to another arrow instead. These are useful to represent an iterative process (what in Computer Science is

called a loop). A loop may, for example, consist of a connector where control first enters, processing steps, a conditional with one arrow exiting the loop, and one going back to the connector. For additional clarity, wherever two lines accidentally cross in the drawing, one of them may be drawn with a small semicircle over the other, showing that no junction is intended. Labeled connectors Represented by an identifying label inside a circle. Labeled connectors are used in complex or multi-sheet diagrams to substitute for arrows. For each label, the "outflow" connector must always be unique, but there may be any number of "inflow" connectors. In this case, a junction in control flow is implied. Concurrency symbol Represented by a double transverse line with any number of entry and exit arrows. These symbols are used whenever two or more control flows must operate simultaneously. The exit flows are activated concurrently when all of the entry flows have reached the concurrency symbol. A concurrency symbol with a single entry flow is a fork; one with a single exit flow is a join. It is important to remember to keep these connections logical in order. All processes should flow from top to bottom and left to right.

Examples:-

Pseudocode:In computer science and numerical computation, pseudocode is an informal highlevel description of the operating principle of a computer program or other algorithm. It uses the structural conventions of a programming language, but is intended for human reading rather than machine reading. Pseudocode typically omits details that are not essential for human understanding of the algorithm, such asvariable declarations, systemspecific code and some subroutines. The programming language is augmented with natural language description details, where convenient, or with compact mathematical notation. The purpose of using pseudocode is that it is easier for people to understand than conventional programming language code, and that it is an efficient and environmentindependent description of the key principles of an algorithm. It is commonly used in textbooks and scientific publications that are documenting various algorithms, and also in planning of computer program development, for sketching out the structure of the program before the actual coding takes place. No standard for pseudocode syntax exists, as a program in pseudocode is not an executable program. Pseudocode resembles, but should not be confused with, skeleton programs including dummy code, which can be compiled without errors. Flowcharts and UML charts can be thought of as a graphical alternative to pseudocode, but are more spacious on paper.

Example:C style pseudo code: void function bizzbuzz for (i = 1; i<=100; i++) { set print_number to true; if i is divisible by 3 print "Bizz"; set print_number to false; if i is divisible by 5 print "Buzz"; set print_number to false; if print_number, print i; print a newline; }

Program:# include <stdio.h> # include <conio.h> main( ) { int a=0; clrscr(); while( a<50) { a=a+1; printf(%d,a); } Getch(); }

Q. Write a program to find the address?


#include <stdio.h> int main() { int x; int *p;

/* A normal integer*/ /* A pointer to an integer ("*p" is an integer, so p must be a pointer to an integer) */

p = &x; /* Read it, "assign the address of x to p" */ scanf( "%d", &x ); /* Put a value in x, we could also use p here */ printf( "%d\n", *p ); /* Note the use of the * to get the value */ getchar(); }

Q. Write a program to insert a given list of no.


#include<stdio.h> void main() { int A[20], N, Temp, i, j; clrscr(); printf("\n\n\t ENTER THE NUMBER OF TERMS...: "); scanf("%d", &N); printf("\n\t ENTER THE ELEMENTS OF THE ARRAY...:"); for(i=0; i<N; i++) { gotoxy(25,11+i); scanf("\n\t\t%d", &A[i]); } for(i=1; i<N; i++) { Temp = A[i]; j = i-1; while(Temp<A[j] && j>=0) { A[j+1] = A[j]; j = j-1; } A[j+1] = Temp; } printf("\n\tTHE ASCENDING ORDER LIST IS...:\n"); for(i=0; i<N; i++) printf("\n\t\t\t%d", A[i]); getch(); }

Q. Write a program to sort a given list of no.?


#include<stdio.h> #include<dirent.h> #include<malloc.h> #include<string.h> void main (int argc,char * argv[]) { DIR * directory_pointer; struct dirent* entry; struct File list { char filename[64]; struct File * new; } start,*node,* previous, * new; if((directory_pointer=opendir(argv[1]))==NULL) printf("Error opening %s\n", argv[1]); else { start.next + NULL; while (entry = readdir (directory_pointer)) { /* Find the correct location */ previous= Start ;; node = start.next; while ((node) &&(strcmp(entry->d_name,node->filename)>0)) { node = node ->next; previous + previous->next; } new =(struct File List *) malloc(size File List)); if(new += = NULL) { printf("Insufficient memory to store list\n"); exit(1); } new ->next =node; previous ->next =new; strcpy(new->filename,entry->d_name); } closedir(directory_pointer); node = start.next; while (node) { printf("%s\n", node->filename); node = node->next; } } }

Q. Write a program to delete a no. from a list?


int delete_from_beg() { int el; if(head==NULL) { printf("\n can't delete "); return -1; } else { struct doubly *temp; temp=head; el=temp->info; head=temp->next; temp->next=NULL; head->prev=NULL; return el; } } //delete from end int delete_from_end() { int el; if(head==NULL) { printf("\n can't delete"); return -1; } else { struct doubly *temp; temp=head; while(temp->next!=NULL) temp=temp->next; el=temp->info; if(temp==head) head=NULL; else temp->prev->next=NULL; return el; } } // delete from any position int delete_at_pos(int item) { int el,flag=0; struct doubly *temp; if(head==NULL) {

printf("\n cant delete "); return -1; } else { temp=head; while(item>1) { item--; temp=temp->next; if(temp==NULL&& item>=1) { flag=1; break; } } if(flag==1) { el=-1; printf("\n cant delete at the specified location"); } else { if(temp==head) { el=temp->info; head=temp->next; } else { struct doubly *t; t=temp; el=temp->info; temp->prev->next=t->next; temp->next->prev=t->prev; } } } return el; } // where doubly is structure struct doubly { int data; struct doubly *prev,*next; };

Q. Write a program to merge two list?


typedef struct node { int info; struct node *NEXT; }*NODE;

NODE insert_front(int item, NODE first) { NODE temp; temp = ( struct node *) malloc( sizeof (struct node*)); temp -> info = item; temp -> NEXT = first; return temp; } void display(NODE first) { NODE temp; if(first == NULL) { printf("list is empty \n"); return; } printf("contents of linked list \n"); temp = first; while (temp!= NULL ) { printf("%d->",temp -> info); temp = temp->NEXT; } printf("\n"); }

NODE merger_list(NODE first1, NODE first2, NODE merger) { NODE merger_temp; while(first1!=NULL && first2!=NULL) { merger_temp = ( struct node *) malloc( sizeof (struct node*)); if(first1->info > first2->info) merger_temp->info = first1->info; else merger_temp->info = first2->info; merger_temp->NEXT = merger; } main()

{ NODE first1, first2, merger; first1 = NULL; first2 = NULL; merger = NULL; int choice, item; while(1) { printf("\n 1:Insert list1 \n 2: Insert list2 \n 3: display1 \n 4: display2 \n \n printf("enter choice:\n"); scanf ("%d",&choice); switch(choice) { case 1: printf("enter list1\n"); scanf("%d",&item); first1 = insert_front(item,first1); break; case 2: printf("enter list2\n"); scanf("%d",&item); first2 = insert_front(item,first2); case 3: display(first1); break; case 4: display(first2); break; case 5: merger_list(first1, first2, merger); case 6: display(merger); break; case 7: exit(0); default : printf("invalid data entered\n"); } }

5:merger_list

Q. What do you mean by sparse matrix? Explain it with example?


Conceptually, sparsity corresponds to systems which are loosely coupled. Consider a line of balls connected by springs from one to the next; this is a sparse system. By contrast, if the same line of balls had springs connecting each ball to all other balls, the system would be represented by a dense matrix. The concept of sparsity is useful in combinatorics and application areas such as network theory, which have a low density of significant data or connections. Huge sparse matrices often appear in science or engineering when solving partial differential equations. When storing and manipulating sparse matrices on a computer, it is beneficial and often necessary to use specialized algorithms and data structures that take advantage of the sparse structure of the matrix. Operations using standard dense matrix structures and algorithms are slow and consume large amounts of memory when applied to large sparse matrices. Sparse data is by nature easily compressed, and this compression almost always results in significantly less computer data storage usage. Indeed, some very large sparse matrices are infeasible to manipulate with the standard dense algorithms. void transpose (term a[], term b[]) /* b is set to the transpose of a */ { int n, i, j, currentb; n = a[0].value; /* total number of elements */ b[0].row = a[0].col; /* rows in b = columns in a */ b[0].col = a[0].row; /*columns in b = rows in a */ b[0].value = n; if (n > 0) { /*non zero matrix */ currentb = 1; for (i = 0; i < a[0].col; i++) /* transpose by columns in a */ for( j = 1; j <= n; j++) /* find elements from the current column */ if (a[j].col == i) { /* element is in current column, add it to b */

Q. What is the Linked List?


In computer science, a linked list is a data structure consisting of a group of nodes which together represent a sequence. Under the simplest form, each node is composed of a datum and a reference(in other words, a link) to the next node in the sequence; more complex variants add additional links. This structure allows for efficient insertion or removal of elements from any position in the sequence.

A linked list whose nodes contain two fields: an integer value and a link to the next node. The last node is linked to a terminator used to signify the end of the list. Linked lists are among the simplest and most common data structures. They can be used to implement several other common abstract data types, including stacks, queues, associative arrays, and symbolic, though it is not uncommon to implement the other data structures directly without using a list as the basis of implementation. The principal benefit of a linked list over a conventional array is that the list elements can easily be inserted or removed without reallocation or reorganization of the entire structure because the data items need not be stored contiguously in memory or on disk. Linked lists allow insertion and removal of nodes at any point in the list, and can do so with a constant number of operations if the link previous to the link being added or removed is maintained during list traversal. On the other hand, simple linked lists by themselves do not allow random access to the data, or any form of efficient indexing. Thus, many basic operations such as obtaining the last node of the list (assuming that the last node is not maintained as separate node reference in the list structure), or finding a node that contains a given datum, or locating the place where a new node should be inserted may require scanning most or all of the list elements. Each record of a linked list is often called an element or node. The field of each node that contains the address of the next node is usually called the next link or next pointer. The remaining fields are known as the data, information, value, cargo, or payload fields. The head of a list is its first node. The tail of a list may refer either to the rest of the list after the head, or to the last node in the list. In Lisp and some derived languages, the next node may be called the cdr (pronounced could-err) of the list, while the payload of the head node may be called the car. Post office box analogy The concept of a linked list can be explained by a simple analogy to real-world post office boxes. Suppose Alice is a spy who wishes to give a codebook to Bob by putting it in a post office box and then giving him the key. However, the book is too thick to fit in a single post office box, so instead she divides the book into two halves and purchases two post office boxes. In the first box, she puts the first half of the book and a key to the second box, and in the second box she puts the second half of the book. She then gives Bob a key to the first box. No matter how large the book is, this scheme can be extended to any number of boxes by always putting the key to the next box in the previous box. In this analogy, the boxes correspond to elements or nodes, the keys correspond to pointers, and the book itself is the data. The key given to Bob is the head pointer, while those stored

in the boxes are next pointers. The scheme as described above is a singly linked list (see below). Linear and circular lists In the last node of a list, the link field often contains a null reference, a special value used to indicate the lack of further nodes. A less common convention is to make it point to the first node of the list; in that case the list is said to be circular or circularly linked; otherwise it is said to be open or linear.

A circular linked list Singly, doubly, and multiply linked lists Singly linked lists contain nodes which have a data field as well as a next field, which points to the next node in the linked list.

A singly linked list whose nodes contain two fields: an integer value and a link to the next node In a doubly linked list, each node contains, besides the next-node link, a second link field pointing to the previous node in the sequence. The two links may be called forward(s) and backwards, ornext and prev(ious).

A doubly linked list whose nodes contain three fields: an integer value, the link forward to the next node, and the link backward to the previous node A technique known as XOR-linking allows a doubly linked list to be implemented using a single link field in each node. However, this technique requires the ability to do bit operations on addresses, and therefore may not be available in some high-level languages. In a multiply linked list, each node contains two or more link fields, each field being used to connect the same set of data records in a different order (e.g., by name, by department, by date of birth, etc.). (While doubly linked lists can be seen as special cases of multiply linked list, the fact that the two orders are opposite to each other leads to simpler and more efficient algorithms, so they are usually treated as a separate case.) In the case of a circular doubly linked list, the only change that occurs is that end, or "tail", of the said list is linked back to the front, or "head", of the list and vice versa. Sentinel nodes Main article: Sentinel node In some implementations, an extra sentinel or dummy node may be added before the first data record and/or after the last one. This convention simplifies and accelerates some listhandling algorithms, by ensuring that all links can be safely dereferenced and that every list (even one that contains no data elements) always has a "first" and "last" node. Empty lists

An empty list is a list that contains no data records. This is usually the same as saying that it has zero nodes. If sentinel nodes are being used, the list is usually said to be empty when it has only sentinel nodes. Hash linking The link fields need not be physically part of the nodes. If the data records are stored in an array and referenced by their indices, the link field may be stored in a separate array with the same indices as the data records. Linearly linked lists Singly linked lists Our node data structure will have two fields. We also keep a variable firstNode which always points to the first node in the list, or is null for an empty list. record Node { data; // The data being stored in the node Node next // A reference to the next node, null for last node } record List { Node firstNode // points to first node of list; null for empty list } Traversal of a singly linked list is simple, beginning at the first node and following each next link until we come to the end: node := list.firstNode while node not null (do something with node.data) node := node.next The following code inserts a node after an existing node in a singly linked list. The diagram shows how it works. Inserting a node before an existing one cannot be done directly; instead, one must keep track of the previous node and insert a node after it.

function insertAfter(Node node, Node newNode) // insert newNode after node newNode.next := node.next node.next := newNode Inserting at the beginning of the list requires a separate function. This requires updating firstNode. function insertBeginning(List list, Node newNode) // insert node before current first node newNode.next := list.firstNode

list.firstNode := newNode Similarly, we have functions for removing the node after a given node, and for removing a node from the beginning of the list. The diagram demonstrates the former. To find and remove a particular node, one must again keep track of the previous element.

function removeAfter(node node) // remove node past this one obsoleteNode := node.next node.next := node.next.next destroy obsoleteNode function removeBeginning(List list) // remove first node obsoleteNode := list.firstNode list.firstNode := list.firstNode.next // point past deleted node destroy obsoleteNode Notice that removeBeginning() sets list.firstNode to null when removing the last node in the list. Since we can't iterate backwards, efficient insertBefore or removeBefore operations are not possible. Appending one linked list to another can be inefficient unless a reference to the tail is kept as part of the List structure, because we must traverse the entire first list in order to find the tail, and then append the second list to this. Thus, if two linearly linked lists are each of length , list appending has asymptotic time complexity of languages, list appending is provided by the append procedure. . In the Lisp family of

Many of the special cases of linked list operations can be eliminated by including a dummy element at the front of the list. This ensures that there are no special cases for the beginning of the list and renders both insertBeginning() and removeBeginning() unnecessary. In this case, the first useful data in the list will be found at list.firstNode.next. Circularly linked list In a circularly linked list, all nodes are linked in a continuous circle, without using null. For lists with a front and a back (such as a queue), one stores a reference to the last node in the list. The nextnode after the last node is the first node. Elements can be added to the back of the list and removed from the front in constant time. Circularly linked lists can be either singly or doubly linked. Both types of circularly linked lists benefit from the ability to traverse the full list beginning at any given node. This often allows us to avoid storing firstNode and lastNode, although if the list may be empty we need a special representation for the empty list, such as

a lastNode variable which points to some node in the list or is null if it's empty; we use such a lastNode here. This representation significantly simplifies adding and removing nodes with a non-empty list, but empty lists are then a special case. Algorithms Assuming that someNode is some node in a non-empty circular singly linked list, this code iterates through that list starting with someNode: function iterate(someNode) if someNode null node := someNode do do something with node.value node := node.next while node someNode Notice that the test "while node someNode" must be at the end of the loop. If the test was moved to the beginning of the loop, the procedure would fail whenever the list had only one node. This function inserts a node "newNode" into a circular linked list after a given node "node". If "node" is null, it assumes that the list is empty. function insertAfter(Node node, Node newNode) if node = null newNode.next := newNode else newNode.next := node.next node.next := newNode Suppose that "L" is a variable pointing to the last node of a circular linked list (or null if the list is empty). To append "newNode" to the end of the list, one may do insertAfter(L, newNode) L := newNode To insert "newNode" at the beginning of the list, one may do insertAfter(L, newNode) if L = null L := newNode [edit]Linked lists using arrays of nodes Languages that do not support any type of reference can still create links by replacing pointers with array indices. The approach is to keep an array of records, where each record has integer fields indicating the index of the next (and possibly previous) node in the array. Not all nodes in the array need be used. If records are also not supported, parallel arrays can often be used instead. As an example, consider the following linked list record that uses arrays instead of pointers:

record Entry { integer next; // index of next entry in array integer prev; // previous entry (if double-linked) string name; real balance; } By creating an array of these structures, and an integer variable to store the index of the first element, a linked list can be built: integer listHead Entry Records[1000] Links between elements are formed by placing the array index of the next (or previous) cell into the Next or Prev field within a given element. For example: Index Next Prev Name Balance

Jones, John

123.45

-1

Smith, Joseph

234.56

2 (listHead) 4

-1

Adams, Adam

0.00

Ignore, Ignatius 999.99

Another, Anita 876.54

7 In the above example, List Head would be set to 2, the location of the first entry in the list. Notice that entry 3 and 5 through 7 are not part of the list. These cells are available for any additions to the list. By creating a List Free integer variable, a free list could be created to keep track of what cells are available. If all entries are in use, the size of the array would have to be increased or some elements would have to be deleted before new entries could be stored in the list.

The following code would traverse the list and display names and account balance: I: = list Head While I 0 // loop through the list Print I, Records [I].name, Records [I].balance // print entry I: = Records [I].next When faced with a choice, the advantages of this approach include:

The linked list is reloadable, meaning it can be moved about in memory at will, and it can also be quickly and directly serialized for storage on disk or transfer over a network. Especially for a small list, array indexes can occupy significantly less space than a full pointer on much architecture. Locality of reference can be improved by keeping the nodes together in memory and by periodically rearranging them, although this can also be done in a general store. Nave dynamic memory allocators can produce an excessive amount of overhead storage for each node allocated; almost no allocation overhead is incurred per node in this approach. Seizing an entry from a pre-allocated array is faster than using dynamic memory allocation for each node, since dynamic memory allocation typically requires a search for a free memory block of the desired size.

This approach has one main disadvantage, however: it creates and manages a private memory space for its nodes. This leads to the following issues:

It increases complexity of the implementation. Growing a large array when it is full may be difficult or impossible, whereas finding space for a new linked list node in a large, general memory pool may be easier. Adding elements to a dynamic array will occasionally (when it is full) unexpectedly take linear (O (n)) instead of constant time (although it's still an amortized constant). Using a general memory pool leaves more memory for other data if the list is smaller than expected or if many nodes are freed.

For these reasons, this approach is mainly used for languages that do not support dynamic memory allocation. These disadvantages are also mitigated if the maximum size of the list is known at the time the array is created.

Vous aimerez peut-être aussi