0% found this document useful (0 votes)
1 views

Module-3_DS_2024

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
1 views

Module-3_DS_2024

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 84

Course Name: Data Structures and Applications

Course Code: BCS304

Module 3
Linked List
Doubly Linked List
• Definition:
Doubly linked list is homogeneous list of
zero or more nodes where each node consist
of exactly one data field and two link fields
Example

\0 A B C D \0

first
Creating a Doubly Linked list node
typedef struct listNode *listPointer;
typedef struct
{
listPointer llink;
float data;
listPointer rlink;
}listNode;
DLL : The basic operations
• The different operations on doubly linked list
are
– Inserting a node at the front end
– Inserting a node at the rear end

– Deleting a node at the front end


– Deleting a node at the rear end

– Displaying the contents


DLL:Inserting a node at the front end
Algorithm: listPointer insert_front_dll(int item,listPointer
Steps to follow first)
1. Allocate memory to {
the node temp listPointer temp;
2. Load the fields with temp=(listPointer)malloc(sizeof(listPointer));
suitable data temp->data=item;
temp->llink=temp->rlink=NULL;
3. Check list emptiness,
if(first!=NULL)
if list is empty make
{
the temp node as first temp->rlink=first;
4. If list is not empty, first->llink=temp;
link the temp node to }
first node of the return temp;
existing node }
DLL: Inserting a node at the rear end

Algorithm: listPointer insertRear_dll(int item,listPointer


first)
Steps to follow {
listPointer temp;
temp=(listPointer)malloc(sizeof(listPoinnter));
1. Allocate memory to the temp->data=item;
node temp
temp->llink=temp->rlink=NULL;
2. Load the fields with
suitable data of temp if(first==NULL)
3. Check list emptiness, if return temp;
list is empty make the else
temp node as first { listPointer cur=first;
4. If list is not empty, while(cur->rlink!=NULL)
search for the list’s last cur=cur->rlink;
node, once found: attach cur->rlink=temp;
the ‘temp’ node to it
temp->llink=cur;
return first;
DLL :Deleting a node at the front
Algorithm: end
Steps to follow listPointer deleteFront_dll(listPointer first)
{
1. Check for list emptiness, if list is if(first==NULL)
empty print suitable message {
printf(“List is Empty\n”):
return NULL;
}
1. If list is not empty, print the listPointer temp;
deleted data to the user in the temp=first;
front node and make the second temp=temp->rlink;
node as first node temp->llink=NULL;
printf(“The data deleted is %d\n”,first-
>data);
free(first);
first=NULL;
return temp;
}
end
listPointer delteRear_dll(listPointer first)
{ if(first==NULL)
Algorithm: printf(“List is Empty\n”);
{
Steps to follow return first;
1. If List is empty }
print the error if(first->rlink==NULL)
message { printf(“Data deleted is \n%d\n”,first->data);
2. If the list contains free(first); first=NULL;
only one delete it return NULL;
and return NULL }
3. If list contains listPointer cur=first,prev=NULL;
more than one while(cur->rlink!=NULL)
node: { prev=cur;
– Find the last cur=cur->rlink;
node }
– Assign the printf(“Data deleted is \n%d\n”,cur->data);
‘link’ field of prev->rlink=NULL;
the previous free(cur); cur=NULL;
node to NULL return first;
– Delete the last }
DLL: C function to display the list
content
Algorithm:
Steps to follow Display_DLL(listPointer first)
{ if(first==NULL)
1. Check for list
emptiness, if list is { printf(“List is Empty\n”);
empty print suitable return first;
message }
2. If list is not empty, listPointer temp=first;
print the data from printf(“The list contents are\n”);
first node to last while(temp!=NULL)
node
{
printf(“%d\t”,temp->data);
temp=temp->rlink;
}
}
Linked List with Header Node
• What is a Header Node?
Header node in a Linked List is a special node
which contains the address of the first node
with no data.
• Ex: Head NULL
Empty list

Head 2 CAT RAT NULL


Linked List with Header Node
• It is specially named as “Head”

• If the Header node contains any data it will be


always the “size of the List”
Linked List with Header Node
• Advantages of Header node
– The implementation of the basic operations
becomes easy with no preconditions checked in
Insertion.
– Renaming of “temp” as “first” is not required after
every insertion at front end.
– Size of the Linked list will be easily calculated (as
it is the only content of the data field of the Header
node).
Categories of the Linked list with
Header node
• Singly Linked List with Header node
• Doubly Linked List with Header node
• Circular Singly Linked List with Header node
• Circular Doubly Linked List with Header node
Basic operations
on
Linked List with Header Node

• Inserting a node at the Front end


• Inserting a node at the Rear end

• Deleting a node at the Front end


• Deleting a node at the Rear end

• Displaying the list contents


SLL with Header node: C function to
insert a node at the front end
Algorithm: Steps to follow
listPointer insert_front(int item, listPointer
Algorithm:isert_front_SLL_HN head)
//Input:data to be inserted as {
//item and the name of the list //as listPointer temp;
head
temp=(listPointer)malloc(sizeof(listPointer));
//Output: Linked list “head”
temp->info=item;
//after inserting the data
temp->link=NULL;
BEGIN
temp->link=head->link;
1.Allocate memory to the node
temp head->link=temp;
2.Load the fields with suitable return head;
data }
3. Create the links between :
– Head node and the temp node
– Temp node and the first node of
the existing list
END
Algorithm:
Steps to follow SLL with Header node : C
Algorithm:
Insert_rear_SLL_HN function to insert a node at the
rear
//Input: Data to be inserted as end listPointer insert_rear(int item,listPointer head)
//item and the name of the list {
//as head listPointer temp;
//Output: Linked list “head” temp=(listPointer)malloc(sizeof(listPointer));
//after inserting the data temp->data=item;
temp->link=NULL;
BEGIN listPointer cur=head;
1.Allocate memory to the node while(cur->link!=NULL)
temp
{
2. Load the fields with suitable
data of temp
cur=cur->link;
3.Find the last node of the list
}
and then insert the temp node cur->link=temp;
next to it return head;
4. Return the address of the
Head node. }
END
SLL with Header node: C function to
delete a node at the front end
Algorithm:
listPointer delete_front_SLL(listPointer first)
Steps to follow {
listPointer temp;
if(head->link==NULL)
1. Check for list {
emptiness, if list is printf(“List is Empty\n”);
empty print suitable return first;
message }
temp=head->link;
head->link=temp->link;
1. If list is not empty, printf(“Deleted data is \n %d \n”,temp-
print the deleted data >data);
to the user in the
free(temp);
front node and make
the second node as temp=NULL;
first node return head;
}
SLL with header node: C function to delete a
node at the rear end
Algorithm:Steps to follow listPointer delete_rear(listPointer head)
Algorithm:
Insert_rear_SLL_HN
{
//Input: Data to be inserted as if(head->link==NULL)
//item and the name of the list { printf(“List is empty: Can not delete\n”);
//as head return head;
//Output: Linked list “head”
}
//after inserting the data
listPointer prev=NULL,cur=head->link;
BEGIN
1.Allocate memory to the node while(cur->link!=NULL)
temp { prev=cur;
2. Load the fields with suitable cur=cur->link;
data of temp
}
3.Find the last node and previous
node of the list prev->link=NULL;
4.Insert NULL into link field of printf(“Deleted data is \n %d \n”,cur->data);
previous node and delete current free(cur);
node cur=NULL;
5.Return the address of the Head return head;
node.
END }\*end of function*\
SLL with header node: C function to display the
list

display(listPointer head)
Algorithm: Steps to follow {
listPointer temp;
● Algorithm: if(head->link==NULL)
display_SLL_HN {
● //Input: Data to be printf(“List is Empty\n”);
inserted as //item and the return;
name of the list as //head }
● //Output: Linked list {
else
“head” after
temp=head->link;
● //inserting the data printf(“The Linked List contents are\n”);
while(temp!=NULL)
● BEGIN {
1. Check list emptiness: printf(“%d\t”,temp->data);
if list is empty print temp=temp->link;
suitable message, else go to }
next step }
2. Display the content of }
the list from first node to
last node
● END
Circular Linked List
• Definition:
Circular Linked List is a linear homogeneous list
of zero or more nodes where the last node is followed
by the first node
• Example:

first A B C D
Circular Singly Linked List with
Header Node
• Definition:
Circular Singly Linked List is a linear
homogeneous list of zero or more nodes with a special
node called the “head”; where the last node is
followed by the head node and each node consisting
of exactly one link field
• Example:
head 3 B C D
Circular Doubly Linked List with Header
Node
• Definition:
Circular Linked List is a linear homogeneous list
of zero or more nodes with a special node called the
“head”; where the last node is followed by the head
node and each node consisiting of exactly two link
fields
• Example:
head 1 2 3
Basic operations
• Inserting a node at the front end
• Inserting a node at the rear end

• Deleting a node at the front end


• Deleting a node at the rear end

• Displaying the list


Circular DLL with Header node:C function to
insert node at front end
listPointer inertFront_CDLL(ListPointer head)
Algorithm: Steps to follow { listPointer temp,cur;
Algorithm: inertFront_CDLL temp=(listPointer)malloc(sizeof(listPointer));
//Input: the name of the Circular
doubly printf(“Enter the item to be stored\n”);
//linked list as “head” scanf(“%d”,&item);
//Output: the newly created list “head”
//after inserting the data at front end temp->data=item;
BEGIN temp->llink=temp->rlink=NULL;
1. Allocate memory to node “temp”
2. Read the data to be stored cur=head->rlink;
3. Load the fields of the node “temp”
with suitable data head->rlink=temp;
4. Identify the first node of the list as temp->llink=head;
“cur”
temp->rlink=cur;
5. Link the temp node to head node
cur->llink=temp;
and temp node to current node
6.Return the head node
END return head;
}
Circular DLL with Header node:C function to
insert node at rear end

Algorithm: Steps to follow listPointer inertRear_CDLL(ListPointer head)


{ listPointer temp,cur;
Algorithm: inertRear_CDLL
temp=(listPointer)malloc(sizeof(listPointer));
//Input: the name of the Circular
doubly
printf(“Enter the item to be stored\n”);
//linked list as “head”
scanf(“%d”,&item);
//Output: the newly created list “head”
//after inserting the data at front end
BEGIN temp->data=item;
1. Allocate memory to node “temp” temp->llink=temp->rlink=NULL;
2. Read the data to be stored
3. Load the fields of the node “temp” cur=head->llink;
with suitable data
4. Identify the last node of the list as head->llink=temp;
“cur” temp->rlink=head;
5. Link the temp node to head node temp->llink=cur;
and temp node to current node cur->rlink=temp;
6. Return the head node return head;
END }
Circular DLL with Header node:C function to
delete node at front end
listPointer deleteFront_CDLL(ListPointer head)
Algorithm: Steps to follow
{
Algorithm: deleteFront_CDLL
if(head->rlink==head)
//Input: the name of the Circular
doubly {
printf(“List is empty\n”);
//linked list as “head”
return head;
//Output: the newly created list “head”
//after inserting the data at front end }
BEGIN listPointer cur=head->rlink, next=cur->rlink;
1. Check for the List emptiness: if list
is empty print the suitable error head->rlink=next;
message and return the control; next->llink=head;
otherwise goto next step
2. Identify the first and second node printf(“Deleted data is %d\n”, cur->data);
of the list as “cur” and “next” free(cur);
respectively
cur=NULL;
3. Link the “head” and “next” node
4. Delete the cur node
return head;
5.Return the head node
}
END
Circular DLL with Header node:C function to
delete node at front end
listPointer inertRear_CDLL(ListPointer head)
Algorithm: Steps to follow {
if(head->rlink==head)
Algorithm: inertFront_CDLL
{
//Input: the name of the Circular
doubly printf(“List is empty\n”);
//linked list as “head” return head;
//Output: the newly created list “head” }
//after inserting the data at front end listPointer cur=head->llink, prev=cur->llink;
BEGIN
1. Check for the List emptiness: if list is head->llink=prev;
empty print the suitable error message prev->rlink=head;
and return the control; otherwise goto
next step printf(“Deleted data is %d\n”, cur->data);
2. Identify the last and last but one node of free(cur);
the list as “cur” and “prev” respectively
cur=NULL;
3. Link the “head” and “prev” node
4. Delete the cur node
return head;
5.Return the head node END
}
Circular DLL with Header node:C function
to delete node at front end
void inertRear_CDLL(ListPointer head)
Algorithm: Steps to follow {
if(head->rlink==head)
Algorithm: display_CDLL {
//Input: the name of the Circular printf(“List is empty\n”);
doubly return head;
//linked list as “head” }
//Output: the newly created list “head” listPointer temp=head->rlink;
//after inserting the data at front end printf(“The list contents are\n”);
BEGIN while(temp!=head)
1. Check for the List emptiness: if list {
is empty print the suitable error
printf(“%d\t”,temp->data);
message and return the control;
otherwise goto next step temp=temp->temp->rlink;
2. Identinfy the first node as temp }
3. Print the data from the first node to }
the last node of the list
END
Additional operations on Linked List
• List of certain additional operation
– Concatenation of two linked list
– Reversing a linked list
– Searching a key element in linked list
– Insertion of data to either left or right to the key
found
– Deletion of data to either left or right to the key
found
C function to concatenate two list
listPointer concatenate(listPointer first,listPointer second)
{
if(first==NULL) //checking on first list existance
return second;
if(second==NULL) //checking on second list existance
return first;
listPointer cur=first;
while(cur->link!=NULL) //identifying end of the first list
cur=cur->link;
cur->link=second; //list concatenated at the end of first list
return first;
}
C function to Reverse a list
listPointer reverse(listPointer first)
{
listPointer cur,temp;
cur=NULL;
while(first!=NULL)
{
temp=first->link;
first->link=cur;
cur=first;
first=temp;
}
return cur;
}
C function to search a key in list
void searchKey(listPointer first,int key)
{
listPointer temp=first;
while(temp!=NULL)
{
if(temp->data==key)
{
printf(“Key found in the list\n”);
break;
}
temp=temp->link;
}
if(temp==NULL)
{
printf(“Key not found in the list\n”);
}
C function to insert data to left of key
void isert_left_to_key(listPointer first,int key,int item)
{
listPointer cur=first,prev=NULL;
while(cur!=NULL)
{ if(cur->data==key)
{ listPointer temp=(listPointer)malloc(sizeof(listPointer));
temp->data=item;temp->link=NULL;
prev->link=temp;
temp->link=cur;
break;
}
prev=cur;
cur=cur->link;
}
if(cur==NULL)
{ printf(“Key not found in the list, hence insertion is not possible\n”);
C function to insert data to right of key found
void insert_Right_to_Key(listPointer first,int key,int item)
{ listPointer cur=first;
while(cur!=NULL)
{ if(cur->data==key)
{ litPointer next=cur->link;
listPointer temp=(listPointer)malloc(sizeof(listPointer));
temp->data=item;temp->link=NULL;
cur->link=temp;
temp->link=next;
break;
}
cur=cur->link;
}
if(cur==NULL)
{ printf(“Key not found in the list, hence insertion is not possible\n”);
}
Linked Stacks
• Stack data structure created using Linked List
• Procedure
– Stacks prefer the data should be entered at one
end and deleted at the same end
– Since Linked List has two ends, we can use any
one end
• Insert the data and delete the data at front end i.e.,
– Pick Insert front and Delete front operations of Linked list
• Insert the data and delete the data at rear end i.e.,
– Pick Insert rear and Delete rear operations of Linked list
Linked Queues
• Queues data structure created using Linked List
• Procedure
– Queues prefer the data should be entered at one end and
deleted at the other end
– Since Linked List has two ends, we can use any both
ends
• Insert the data at rear end and delete the data at front end i.e.,
– Pick Insert rear and Delete front operations of Linked list
• Insert the data at front end and delete the data at rear end i.e.,
– Pick Insert front and Delete rear operations of Linked list
POLYNOMIAL
• Definition
Polynomial is a collection of terms, each
term taking the form
axe
where, a is the coefficient, x is the variable and
e is the exponent
• Example
A(x)= 40x500 + 4x3 - 3x2 +20
B(x)= 5x6 + 2x2 +1
Polynomial Representation
• Polynomial could be stored in two ways into
memory of a computer

1. Using Structure consisting of an array


2. Using Array of Structures
Storage: Using Structure consisting of an
Array
● #define MAX_DEGREE 101
typedef struct
● {
● int degree;
● float coef[MAX_DEGREE];
● } polynomial;

● polynomial A,B;

• advantage: easy implementation


• disadvantage: waste space when sparse
Storage: Using Array of Structures
• To overcome the disadvantage of the previous storage,
we can use one global array to store all the polynomials
• Structure definition #define
MAX_DEGREE 101 typedef
struct
{
int degree;
float coef;
} polynomial;
polynomial P [MAX_DEGREE];
Data structure 2: use one global array to store all polynomials
A(X)=2X1000+1
B(X)=X4+10X3+3X2+1 Array representation of two polynomials
starta finisha startb finishb avail

coef

exp

0 1 2 3 4 5 6
specification representation
poly <start, finish>
A <0,1>
B <2,5>
Trees

Root
Dusty

Honey Bear Brandy

Brunhilde Terry Coyote Nugget

Gill Tansey Tweed Zoe Crocus Primrose Nous Belle

leaf
Definition of Tree

A tree is a finite set of one or more nodes


such that:
There is a specially designated node called
the root.
The remaining nodes are partitioned into n>=0
disjoint sets T1, ..., Tn, where each of these sets
is a tree.
We call T1, ..., Tn the subtrees of the root.
Level and Depth

Level
node (13)
degree of a node
leaf (terminal) A 1
nonterminal 3 1
parent
children B C D 2
2 2 1 2 3 2
sibling
E G H I J 33
30 F 30
degree of a tree (3)
ancestor 2 31 30 30
level of a node
K
height of a tree (4) 0 40 L 4 0
M
4 4
Terminology

• The degree of a node is the number of subtrees of the node


• – The degree of A is 3; the degree of C is 1.
• The node with degree 0 is a leaf or terminal node.
• A node that has subtrees is the parent of the roots of the subtrees.
• The roots of these subtrees are the children of the node.
• Children of the same parent are siblings. The ancestors of a node
are all the nodes along the path from the root to the node.
Representation of Trees

List Representation
– ( A ( B ( E ( K, L ), F ), C ( G ), D ( H ( M ), I, J ) )
– The root comes first, followed by a list of sub-trees

data link 1 link 2 ... link n

How many link fields are


needed in such a representation?
Left Child - Right Sibling

data
A left child right sibling

B C D

E F G H I J

K L M
* Left child-right child tree representation of a tree

E C

G D
K F

L H

M I

J
Binary Trees

• A binary tree is a finite set of nodes that is either empty or


consists of a root and two disjoint binary trees called the left
subtree and the right subtree.
• Any tree can be transformed into binary tree.
• – by left child-right sibling representation
• The left subtree and the right subtree are distinguished.
Samples of Trees

Complete Binary Tree

A A 1 A

B B 2 B C

C Skewed Binary Tree


3 D E F G
D

4 H I
E 5
Maximum Number of Nodes in BT

● The maximum number of nodes on level i of a binary tree is 2i-1, i>=1.


● The maximum nubmer of nodes in a binary tree of depth k is 2k-1, k>=1.

Prove by induction.
k
2i 1

2k i 1
1
Relations between Number of Leaf Nodes
and Nodes of Degree 2
For any nonempty binary tree, T, if n0 is the number of leaf nodes
and n2 the number of nodes of degree 2, then n0=n2+1
proof:
Let n and B denote the total number of nodes & branches in T.
Let n0, n1, n2 represent the nodes with no children
single child, and two children respectively.
n= n0+n1+n2, B+1=n, B=n1+2n2 ==> n1+2n2+1= n n1+2n2+1=
n0+n1+n2 ==> n0=n2+1
Full BT VS Complete BT

k
A full binary tree of depth k is a binary tree of depth k having 2 -1
nodes, k>=0.
A binary tree with n nodes and depth k is complete iff its nodes
correspond to the nodes numbered from 1 to n in the full binary
tree of depth k.
A A

B C B C

D E F G D E F G

I H I J K L M N O
H
Complete binary tree Full binary tree of depth 4
Binary Tree Representations

If a complete binary tree with n nodes (depth = log n + 1) is


represented sequentially, then for any node with index i, 1<=i<=n,
we have:
– parent(i) is at i/2 if i!=1. If i=1, i is at the root and has no parent.
– left_child(i) ia at 2i if 2i<=n. If 2i>n, then i has no left child.
– right_child(i) ia at 2i+1 if 2i +1 <=n. If 2i +1 >n, then i has no right
child.
Sequential Representation
[1] A
(1) waste space
(2) insertion/deletion [2] B
A [1] A [3] C
[2] problem
B [4] D
[3] --
B [5] E
[4]
C A [6] F
[5]
-- [7] G
C [6]
-- [8] H
[7] B C [9] I
D [8] --
[9] D
. -- D E F G
E
[16]
.
E
H I
Linked Representation

typedef struct node *tree_pointer;


typedef struct node {
int data;
tree_pointer left_child, right_child;
};

data
left_child data right_child

left_child right_child
Binary Tree Traversals

Let L, V, and R stand for moving left, visiting the node, and moving
right.
There are six possible combinations of traversal
– LVR, LRV, VLR, VRL, RVL, RLV
Adopt convention that we traverse left before right, only 3 traversals
remain
– LVR, LRV, VLR
– inorder, postorder, preorder
Arithmetic Expression Using BT

+ inorder traversal
A/ B * C * D + E
infix expression
* E
preorder traversal
+ ** /AB C D E
* D prefix expression
postorder traversal
AB/ C* D*E +
/ C
postfix expression
level order traversal
A B + * E * D / CAB
Inorder Traversal (recursive version)

void inorder(tree_pointer ptr)


/* inorder tree traversal */
{
A/ B * C * D + E
if (ptr) {
inorder(ptr->left_child);
printf(“%d”, ptr->data);
indorder(ptr->right_child);
}
}
Preorder Traversal(recursive version)

void preorder(tree_pointer ptr)


/* preorder tree traversal */
{
+ * * /AB C D E
if (ptr) {
printf(“%d”, ptr->data);
preorder(ptr->left_child);
predorder(ptr->right_child);
}
}
Postorder Traversal(recursive version)

void postorder(tree_pointer ptr)


/* postorder tree traversal */
{
AB / C * D * E +
if (ptr) {
postorder(ptr->left_child);
postdorder(ptr->right_child);
printf(“%d”, ptr->data);
}
}
Iterative Inorder Traversal

(using stack)
void iter_inorder(tree_pointer node)
{
int top= -1; /* initialize stack */
tree_pointer stack[MAX_STACK_SIZE];
for (;;) {
for (; node; node=node->left_child)
add(&top, node);/* add to stack */
node= delete(&top);
/* delete from stack */
if (!node) break; /* empty stack */
printf(“%D”, node->data);
node = node->right_child;
}
} O(n)
Trace Operations of Inorder Traversal

Call of inorder Value in root Action Call of inorder Value in root Action
1 + 11 C
2 * 12 NULL
3 * 11 C printf
4 / 13 NULL
5 A 2 * printf
6 NULL 14 D
5 A printf 15 NULL
7 NULL 14 D printf
4 / printf 16 NULL
8 B 1 + printf
9 NULL 17 E
8 B printf 18 NULL
10 NULL 17 E printf
3 * printf 19 NULL
Level Order Traversal
(using queue)

void level_order(tree_pointer ptr)


/* level order tree traversal */
{
int front = rear = 0;
tree_pointer queue[MAX_QUEUE_SIZE];
if (!ptr) return; /* empty queue */
addq(front, &rear, ptr);
for (;;) {
ptr = deleteq(&front, rear);
if (ptr) {
printf(“%d”, ptr->data);
if (ptr->left_child)
addq(front, &rear,
ptr->left_child);
if (ptr->right_child)
addq(front, &rear,
ptr->right_child);
}
else break;
} + * E * D / CAB
}
Copying Binary Trees

tree_poointer copy(tree_pointer original)


{
tree_pointer temp;
if (original) {
temp=(tree_pointer) malloc(sizeof(node));
if (IS_FULL(temp)) {
fprintf(stderr, “the memory is full\n”);
exit(1);
}
temp->left_child=copy(original->left_child);
temp->right_child=copy(original->right_child)
temp->data=original->data;
return temp;
} postorder
return NULL;
}
Equality of Binary Trees
the same topology and data

int equal(tree_pointer first, tree_pointer second)


{
/* function returns FALSE if the binary trees first and
second are not equal, otherwise it returns TRUE */

return ((!first && !second) || (first && second &&


(first->data == second->data) &&
equal(first->left_child, second->left_child) &&
equal(first->right_child, second->right_child)))
}
Propositional Calculus Expression
• A variable is an expression.
• If x and y are expressions, then ¬x, x y,
x y are expressions.
• Parentheses can be used to alter the normal order
of evaluation (¬ > > ).
• Example: x1 (x2 ¬x3)
• satisfiability problem: Is there an assignment to
make an expression true?
(x1 ¬x2) (¬ x1 x3)
¬x3
(t,t,t)
(t,t,f)
(t,f,t)
(t,f,f)
(f,t,t) X3
(f,t,f)
(f,f,t) X1 X3
(f,f,f)

2n possible combinations X2 X1
for n variables
postorder traversal (postfix evaluation)
node structure
left_child data value right_chil
d

typedef emun {not, and, or, true, false } logical;


typedef struct node *tree_pointer;
typedef struct node {
tree_pointer list_child;
logical data;
short int value;
tree_pointer right_child;
};
First version of satisfiability algorithm

for (all 2n possible combinations) {


generate the next combination;
replace the variables by their values;
evaluate root by traversing it in postorder;
if (root->value) {
printf(<combination>);
return;
}
}
printf(“No satisfiable combination \n”);
Post-order-eval function
void post_order_eval(tree_pointer node)
{
/* modified post order traversal to evaluate a
propositional calculus tree */
if (node) {
post_order_eval(node->left_child);
post_order_eval(node->right_child);
switch(node->data) {
case not: node->value =
!node->right_child->value;
break;
case and: node->value =
node->right_child->value &&
node->left_child->value;
break;
case or: node->value =
node->right_child->value | |
node->left_child->value;
break;
case true: node->value = TRUE;
break;
case false: node->value = FALSE;
}
}
}
Threaded Binary Trees

Two many null pointers in current representation of binary


trees
n: number of nodes
number of non-null links: n-1 total links:
2n
null links: 2n-(n-1)=n+1
Replace these null pointers with some useful “threads”.
Threaded Binary Trees(Continued)

If ptr->left_child is null,
replace it with a pointer to the node that would be
visited before ptr in an inorder traversal

If ptr->right_child is null,
replace it with a pointer to the node that would be
visited after ptr in an inorder traversal
A Threaded Binary Tree

root A
dangling
B C

dangling D E F G

inorder traversal:
H I H, D, I, B, E, A, F, C, G
Data Structures for Threaded BT
left_thread left_child data right_child right_thread

TRUE FALSE

TRUE: thread FALSE: child


typedef struct threaded_tree
*threaded_pointer;
typedef struct threaded_tree {
short int left_thread;
threaded_pointer left_child;
char data;
threaded_pointer right_child;
short int right_thread; };
Memory Representation of A Threaded BT

root --
f f

f A f

f B f f C f

f D f t E t t F t t G

t H t t I t
Next Node in Threaded BT

threaded_pointer insucc(threaded_pointer
tree)
{
threaded_pointer temp;
temp = tree->right_child;
if (!tree->right_thread)
while (!temp->left_thread)
temp = temp->left_child;
return temp;
}
Inorder Traversal of Threaded BT

void tinorder(threaded_pointer tree)


{
/* traverse the threaded binary tree
inorder */
threaded_pointer temp = tree;
for (;;) {
temp = insucc(temp);
O(n) if (temp==tree) break;
printf(“%3c”, temp->data);
}
}
Inserting Nodes into Threaded BTs

Insert child as the right child of node parent


– change parent->right_thread to FALSE
– set child->left_thread and child->right_thread
to TRUE
– set child->left_child to point to parent
– set child->right_child to parent->right_child
– change parent->right_child to point to child
Examples

Insert a node D as a right child of B.


root root

A A
(1)
B parent B parent
(3)
child child
C D C D
(2)
empty
*Figure 5.24: Insertion of child as a right child of parent in a threaded binary tree (p.217

(3)

(2) (1)

(4)

nonempty
Right Insertion in Threaded BTs

void insert_right(threaded_pointer parent,


threaded_pointer child)
{
threaded_pointer temp;
(1)child->right_child = parent->right_child;
child->right_thread = parent->right_thread;
= parent; case (a)
(2)child->left_child
child->left_thread = TRUE;
(3)parent->right_child = child;
parent->right_thread = FALSE;
if (!child->right_thread) { case (b)
(4)temp = insucc(child);
temp->left_child = child;
}
}

You might also like