Professional Documents
Culture Documents
Function Pointers
A function pointer is a variable that stores the address of a function that can later be
called through that function pointer. This is useful because functions encapsulate
behavior. For instance, every time you need a particular behavior such as drawing a line,
instead of writing out a bunch of code, all you need to do is call the function. But
sometimes you would like to choose different behaviors at different times in essentially
the same piece of code. Read on for concrete examples.
A much nicer way of allowing the user to choose how to sort the data is simply to let the
user pass in a function to the sort function. This function might take two pieces of data
and perform a comparison on them. We'll look at the syntax for this in a bit.
Callback Functions
Another use for function pointers is setting up "listener" or "callback" functions that are
invoked when a particular event happens. The function is called, and this notifies your
code that something of interest has taken place.
Why would you ever write code with callback functions? You often see it when writing
code using someone's library. One example is when you're writing code for a graphical
user interface (GUI). Most of the time, the user will interact with a loop that allows the
mouse pointer to move and that redraws the interface. Sometimes, however, the user will
click on a button or enter text into a field. These operations are "events" that may require
a response that your program needs to handle. How can your code know what's
happening? Using Callback functions! The user's click should cause the interface to call a
function that you wrote to handle the event.
To get a sense for when you might do this, consider what might happen if you were using
a GUI library that had a "create button" function. It might take the location where a
button should appear on the screen, the text of the button, and a function to call when the
button is clicked. Assuming for the moment that C (and C++) had a generic "functions
pointer" type called function, this might look like this:
The key to writing the declaration for a function pointer is that you're just writing out the
declaration of a function but with (*func_name) where you'd normally just put
func_name.
Ans:
Ans –
#include<conio.h>
#include<stdio.h>
void main()
{ struct student
{ int roll;
Char name[20];
}
} std[5]; //declaring an array of structure
Trees
For example, a tree-like organization charts often used to represent the lines of
responsibility in a business as shown in Figure. The president of the company is shown at
the top of the tree and the vice-presidents are indicated below her. Under the vice-
presidents we find the managers and below the managers the rest of the clerks. Each clerk
reports to a manager. Each manager reports to a vice-president, and each vice-president
reports to the president.
It just takes a little imagination to see the tree in Figure. Of course. The tree is
upside-down. However, this is the usual way the data structure is drawn. The president is
called the root of the tree and the clerks are the leaves.
Clearly, in order to compute all the totals. It is necessary to consider the salary of
every employee. Therefore, an implementation of this computation must visit all the
employees in the tree. An algorithm that systematically visits all the items in a tree is
called a tree traversal.
In the same chapter we consider several different kinds of trees as well as several
different tree traversal algorithms. In addition. We show how trees can be used to
represent arithmetic expressions and how we can evaluate an arithmetic expression by
doing a tree traversal. The following is a mathematical definition of a tree:
3. A designated node of the set, r, is called the root of the tree: and
4. The remaining nodes are partitioned into n≥ O subsets T, T. …Tn each of which is a
tree for convenience, we shall use the notation T= {r. T, T, …T} denote the tree T.
It follows from Definition that the minimal tree is a tree comprised of a single root node.
For example Ta = {A}.
How do Ta Tb. & Tc resemble their arboreal namesake? The similarity becomes
apparent when we consider the graphical representation of these trees shown in Figure.
To draw such a pictorial representation of a tree, T = {r. T1 ,T2, …Tn, beside each other
below the root. Finally, lines are drawn from rto the roots of each of the subtrees.
T1T2…….Tn
The inverted pictorial representation of trees is probably due to the way that
genealogical lineal charts are drawn. A lineal chart is a family tree that shows the
descendants of some person. And it is from genealogy that much of the terminology
associated with tree data structures is taken.
Figure shows one representation of the tree Tc defined in Equation. In this case,
the tree is represented as a set of nested regions in the plane. In fact, what we have is a
Venn diagram which corresponds to the view that a tree is a set of sets.
Binary Tree
Used to implement lists whose elements have a natural order (e.g. numbers) and
either (a) the application would like the list kept in this order or (b) the order of elements
is irrelevant to the application (e.g. this list is implementing a set).
Each element in a binary tree is stored in a "node" class (or struct). Each node
contains pointers to a left child node and a right child node. In some implementations, it
may also contain a pointer to the parent node. A tree may also have an object of a second
"tree" class (or struct) which as a header for the tree. The "tree" object contains a pointer
to the root of the tree (the node with no parent) and whatever other information the
programmer wants to squirrel away in it (e.g. number of nodes currently in the tree).
In a binary tree, elements are kept sorted in left to right order across the tree. That
is if N is a node, then the value stored in N must be larger than the value stored in left-
child(N) and less than the value stored in right-child(N). Variant trees may have the
opposite order (smaller values to the right rather than to the left) or may allow two
different nodes to contain equal values.
Hash Tables
A very common paradigm in data processing involves storing information in a
table and then later retrieving the information stored there. For example, consider a
database of driver’s license records. The database contains one record for each driver’s
license issued. Given a driver’s license number. we can look up the information
associated with that number. Similar operations are done by the C compiler. The
compiler uses a symbol table to keep track of the user-defined symbols in a Java
program. As it compiles a program, the compiler inserts an entry in the symbol table
every time a new symbol is declared. In addition, every time a symbol is used, the
compiler looks up the attributes associated with that symbol to see that it is being used
correctly.
Hash tables are a very practical way to maintain a dictionary. As with bucket sort,
it assumes we know that the distribution of keys is fairly well-behaved.
Once you have its index. A hash function is a mathematical function which maps
keys to integers.
In bucket sort, our hash function mapped the key to a bucket based on the first
letters of the key. "Collisions" were the set of keys mapped to the same bucket. If the
keys were uniformly distributed. then each bucket contains very few keys!
The resulting short lists were easily sorted, and could just as easily be searched
We examine data structures which are designed specifically with the objective of
providing efficient insertion and find operations. In order to meet the design objective
certain concessions are made. Specifically, we do not require that there be any specific
ordering of the items in the container. In addition, while we still require the ability to
remove items from the container, it is not our primary objective to make removal as
efficient as the insertion and find operations.
Ideally we would’ build a data structure for which both the insertion and find
operations are 0(1) in the worst case. However, this kind of performance can only be
achieved with complete a priori knowledge. We need to know beforehand specifically
which items are to be inserted into the container. Unfortunately, we do not have this
information in the general case. So, if we cannot guarantee 0(1) performance in the worst
case, then we make it our design objective to achieve 0(1) performance in the average
case.
In the previous section, we consider two searchable containers-the ordered list and
the sorted list. In the case of an ordered list, the cost of an insertion is 0(1) and the cost of
the find operation is O(n). For a sorted list the cost of insertion is O(n) and the cost of the
find operation is O(log n) for the array implementation.
Clearly, neither the ordered list nor the sorted list meets our performance
objectives. The essential problem is that a search, either linear or binary, is always
necessary. In the ordered list, the find operation uses a linear search to locate the item. In
the sorted list, a binary search can be used to locate the item because the data is sorted.
However, in order to keep the data sorted, insertion becomes O(n).
In order to meet the performance objective of constant time insert and find
operations. we need a way to do them without performing a search. That is, given an item
x, we need to be able to determine directly from x the array position where it is to be
stored.
back (tail).Deque is sometimes written dequeue, but this use is generally deprecated in
technical literature or technical writing because dequeue is also a verb meaning "to
remove from a queue". Nevertheless, several libraries and some writers, such as Aho,
Hopcroft, and Ullman in their textbook Data Structures and Algorithms, spell it dequeue.
DEQ and DQ are also used.
This differs from the queue abstract data type or First-In-First-Out List (FIFO), where
elements can only be added to one end and removed from the other. This general data
class has some possible sub-types:
• An input-restricted deque is one where deletion can be made from both ends,
but input can only be made at one end.
• An output-restricted deque is one where input can be made at both ends, but
output can be made from one end only.
Both the basic and most common list types in computing, the queues and stacks can
be considered specializations of deques, and can be implemented using deques.
Circular queues
6. With the help of a suitable numerical example, describe the following concepts of
a Binary Search Tree:
A) Analysis of BST
Ans:
DEF: A binary tree in which the nodes are labeled with elements of an ordered dynamic
set and the following BST property is satisfied: all elements stored in the left subtree of
any node x are less than the element stored at x and all elements stored in the right
subtree of x are greater than the element at x.
An Example: shows a binary search tree. Notice that this tree is obtained by inserting the
values 13, 3, 4, 12, 14, 10, 5, 1, 8, 2, 7, 9, 11, 6, 18 in that order, starting from an empty
tree.
Note that inorder traversal of a binary search tree always gives a sorted sequence of the
values. This is a direct consequence of the BST property. This provides a way of sorting a
given sequence of keys: first, create a BST with these keys and then do an inorder
traversal of the BST so created.
Note that the highest valued element in a BST can be found by traversing from the root in
the right direction all along until a node with no right link is found (we can call that the
rightmost element in the BST).
The lowest valued element in a BST can be found by traversing from the root in the left
direction all along until a node with no left link is found (we can call that the leftmost
element in the BST).
Search is straightforward in a BST. Start with the root and keep moving left or right
using the BST property. If the key we are seeking is present, this search procedure will
lead us to the key. If the key is not present, we end up in a null link.
… or equivalent Haskell:
This operation requires O(log n) time in the average case, but needs O(n) time in the
worst case, when the unbalanced tree resembles a linked list (degenerate tree).
Insertion
Insertion begins as a search would begin; if the root is not equal to the value, we search
the left or right subtrees as before. Eventually, we will reach an external node and add the
value as its right or left child, depending on the node's value. In other words, we examine
the root and recursively insert the new node to the left subtree if the new value is less
than the root, or the right subtree if the new value is greater than or equal to th
Tree is one of the most efficient data structure used in a computer program. There
are many types of tree. Binary tree is a tree that always have two branches, Red-Black-
Trees, 2-3-4 Trees, AVL Trees, etc. A well balanced tree can be used to design a good
searching algorithm.
Spanning trees
A spanning tree of a graph is just a subgraph that contains all the vertices and is a
tree. A graph may have many spanning trees; for instance the complete graph on four
vertices
Now suppose the edges of the graph have weights or lengths. The weight of a tree
is just the sum of weights of its edges. Obviously, different trees have different lengths.
The problem: how to find the minimum length spanning tree?
The standard application is to a problem like phone network design. You have a
business with several offices; you want to lease phone lines to connect them up with each
other; and the phone company charges different amounts of money to connect different
pairs of cities. You want a set of lines that connects all your offices with a minimum total
cost. It should be a spanning tree, since if a network isn’t a tree you can always remove
some edges and save money.
A less obvious application is that the minimum spanning tree can be used to
approximately solve the traveling salesman problem. A convenient formal way of
defining this problem is to find the shortest path that visits each point at least once. Note
that if you have a path visiting all points exactly once, it’s a special kind of tree. For
instance, in the example above, twelve of sixteen spanning trees are actually paths. If you
have a path visiting some vertices more than once, you can always drop some edges to
get a tree. So in general the MST weight is less than the TSP weight, because it’s a
minimization over a strictly larger set.
On the other hand, if you draw a path tracing around the minimum spanning tree,
you trace each edge twice and visit all points, so the TSP weight is less than twice the
MST weight. Therefore this tour is within a factor of two of optimal.
Telecommunication problem
Given a set of computers and a set of wires running between pairs of computers,
what is the minimum number of machines whose crash causes two given machines to be
unable to communicate? (The two given machines will not crash.)
Graph: The vertices of the graph are the computers. The edges are the wires
between the computers. Graph problem: minimum dominating sub-graph.
Knight moves
Graph: The graph here is harder to see. Each location on the chessboard
represents a vertex. There is an edge between two positions if it is a legal knight move.
Graph Problem: Single Source Shortest Path.