LINKED LIST.MODULE 3

undefined
 
MODULE 3
 
LINKED LIST
1
 
Linked list is linear collection of data elements called nodes with
each node having 2 parts
INFORMATION
 of element
ADDRESS
 of next node in the list
 
Example
 
External ptr
2
 
Representation of linked list in memory
3
1
2
3
4
5
6
7
8
A
T
X
START
7
5
2
4
INFO
LINK
K
0
External ptr
 
creating a linked list
 
Array implementation of List
struct  listnode {
             char info;
             int link;
             };
struct  listnode  node[MAX_SIZE];
int ptr=-1;
 
Linked List using Dynamic variables
struct  listnode {
             char data;
             struct listnode * link;
             };
typedef struct  listnode *listptr;
Creation
listptr  ptr=NULL;
Testing
#define IS_EMPTY(ptr) (!(ptr))
Allocation
c
ptr=(listptr) malloc (sizeof(listnode));
 
Traversing a linked list
5
 
Algorithm: Traversing(LIST)
 
This algorithm traverses LIST. The variable PTR points to the
node currently being processed
Step 1 : Set PTR:=START
Step 2: Repeat step 3 and 4 while PTR != NULL
Step3:  Apply process to INFO[PTR]
Step 4 : Set PTR:=LINK[PTR]
[End of Step2 loop]
Step 5 :exit
 
Searching in a linked list
6
 
Searching in an unordered list
SEARCH ( LIST,START,ITEM,LOC)
 
LIST is a linked list. This algorithm finds the location LOC of the node
where ITEM first appears in the list, or sets LOC =NULL
Step 1: set PTR=START
Step2: repeat step 3 while PTR !=NULL
Step 3: If ITEM= INFO[PTR] then Set LOC:=PTR and exit
                Else
                     Set PTR:=LINK[PTR]
                [End of If structure]
[End of step 2 loop]
Step 4: set LOC:=NULL                           [unsuccessful search]
Step 5:exit
 
Searching in a linked list
7
 
Searching in an unordered list
SRCHSL (LIST,START,ITEM,LOC)
 
LIST is a sorted list. This algorithm finds the location LOC of the node where
ITEM first appears in the list, or sets LOC =NULL
Step 1: set PTR=START
Step2: repeat step 3 while PTR !=NULL
Step 3: If ITEM< INFO[PTR] then
                     Set PTR:=LINK[PTR]
                Else ITEM = INFO[PTR] then Set LOC:=PTR and exit
  
Else set LOC:=NULL and exit
                [End of If structure]
[End of step 2 loop]
Step 4: set LOC:=NULL                           [unsuccessful search]
Step 5:exit
 
Insert
8
 
 
 
 
     
Before insertion
 
 
 
 
 
  
     
After insertion
Eat        
.
 
External ptr
 
External ptr
9
 
3 cases
Insert at beginning
Insert after a given node
Insert in the sorted list
 
Insert at beginning
10
 
Algorithm: INSFIRST( INFO, LINK, START,AVAIL,ITEM)
This algorithm inserts ITEM as the first node in the list
1  [ 
OVERFLOW
? ] i
f AVAIL =NULL write OVERFLOW and Exit
2  [ Remove the first node from the AVAIL list]
       Set NEW:= AVAIL and AVAIL:=LINK[AVAIL]
3  Set INFO[NEW] := ITEM
4  Set LINK[NEW]:=START
5  Set START:=NEW
6 Exit
Eat        
.
 
start
 
start
 
Insert after a given node
11
 
Algorithm: INSLOC( INFO, LINK, START,AVAIL,LOC,ITEM)
This algorithm inserts ITEM after the given location LOC
1  [ 
OVERFLOW
? ] i
f AVAIL =NULL write OVERFLOW and Exit
2  [ Remove the first node from the AVAIL list]
       Set NEW:= AVAIL and AVAIL:=LINK[AVAIL]
3  Set INFO[NEW] := ITEM
4
If LOC=NULL then, Set LINK[NEW]:=START and START:=NEW
 
else
          Set LINK[NEW]:=LINK[LOC] and LINK[LOC]:=NEW
      [ End of If ]
5 Exit
Eat        
.
 
start
 
Inserting into the sorted list
12
 
Algorithm INSERT( INFO, LINK, START, AVAIL, ITEM)
This algorithm inserts ITEM into the sorted linked list
1.
Call FINDA(INFO, LINK, START, ITEM,LOC)
2.
Call INSLOC(INFO, LINK, START, AVAIL,LOC, ITEM)
3.
Exit
Procedure: FINDA(INFO, LINK, START, ITEM,LOC)
This procedure finds location LOC of the last node in a sorted list such that INFO[LOC] is less than
ITEM or Sets LOC:=NULL
1.
[ list empty? ] is START =NULL then Set LOC:=NULL and Return
2.
If ITEM < INFO[START] then Set LOC:=NULL and Return
3.
Set TRAIL:= START and PTR:=LINK[START]
4.
Repeat steps 5 and 6 while PTR !=NULL
5.
If ITEM< INFO[PTR] then Set LOC:= TRAIL and Return
 
[ End of if ]
6
Set TRAIL :=PTR and PTR:=LINK[PTR]
           [End of step 4 loop]
7         Set LOC:= TRAIL
8         Return
 
SINGLY LINKED LISTS
13
Linked list
 
An ordered sequence of nodes with links
 
The nodes do not reside in sequential locations
 
The locations of the nodes may change on different runs
ptr
14
 
1
 
2
 
3
 
4
 
5
 
6
 
7
 
8
 
A
 
T
 
X
 
START
7
 
0
 
2
 
4
 
INFO
 
LINK
 
AVAIL
5
 
6
 
8
 
3
 
1
 
0
 
Memory allocation – garbage collection
15
 
A special list which is maintained for the unused memory
cells is called as available list
The OS of computer periodically collects all the deleted
spaces onto the free storage list
The technique that does this collection is called garbage
collection
 
Application of linked list
16
 
As Data structure – insafter , Delafter Operations
To implement other data structures such as Stacks, Queue,
ordered list like polynomial etc.
 
Polynomials
17
 
 
  struct polynode {
      int coef;
      int expon;
      struct polynode * link;
  };
typedef polynode * poly_pointer;
 
 poly_pointer a, b, c;
 
Representation
 
Example
18
 
a= 3x
14
+ 2x
8
+ 1
b= 8x
14
- 3x
10
+ 10x
6
 
Adding Polynomials
 
3    14
 
2    8
 
1    0
 
a
 
8    14
 
-3  10
 
b
 
d
 
a->expon == b->expon
 
3    14
 
2    8
 
a
 
8    14
 
-3   10
 
b
 
11  14
 
d
 
a->expon < b->expon
 
NULL
19
 
Adding Polynomials
 
(
Continued
)
20
 
3    14
 
2    8
 
a
 
8    14
 
-3  10
 
b
 
11  14
 
a->expon > b->expon
 
-3  10
 
d
Algorithm for Adding Polynomials
21
poly_pointer padd(poly_pointer a, poly_pointer b)
{
    poly_pointer front, rear, temp;
    int sum;
    rear =(poly_pointer)malloc(sizeof(poly_node));
    if (IS_FULL(rear)) {
        fprintf(stderr, “The memory is full\n”);
        exit(1);
    }
    front = rear;
    while (a && b) {
        switch (COMPARE(a->expon, b->expon)) {
 
            case -1: 
/* a->expon < b->expon */
                attach(b->coef, b->expon, &rear);
                b= b->link;
                break;
            case 0: 
/* a->expon == b->expon */
                sum = a->coef + b->coef;
                if (sum) attach(sum,a->expon,&rear);
                a = a->link;    b = b->link;
                break;
            case 1: 
/* a->expon > b->expon */
                attach(a->coef, a->expon, &rear);
                a = a->link;
        }
    }
    for (; a; a = a->link)
        attach(a->coef, a->expon, &rear);
    for (; b; b=b->link)
        attach(b->coef, b->expon, &rear);
    rear->link = NULL;
    temp = front;  front = front->link;  free(temp);
    return front;
}
 
Delete extra initial node.
22
 
Representing Polynomials As Circularly Linked Lists
23
 
 
 
3    14
 
2    8
 
1    0
 
a
 
     -1
 
a
 
Zero polynomial
 
     -1
 
Represent 
polynomial
 as 
circular list with header node
.
 
(1) zero
 
(2) others
 
Padd Function
 
poly_pointer cpadd(poly_pointer a, poly_pointer b)
{
  poly_pointer starta, d, lastd;
  int sum, done = FALSE;
  starta = a;
  a = a->link;
  b = b->link;
  d = get_node();
  d->expon = -1;    lastd = d;
  do {
    switch (COMPARE(a->expon, b->expon)) {
      case -1: attach(b->coef, b->expon, &lastd);
               b = b->link;
               break;
24
 
 Padd
 
(
Continued
)
 
      case 0: if (starta == a) done = TRUE;
              else {
                sum = a->coef + b->coef;
                if (sum) attach(sum,a->expon,&lastd);
                a = a->link;   b = b->link;
              }
              break;
      case 1: attach(a->coef,a->expon,&lastd);
              a = a->link;
    }
  } while (!done);
  lastd->link = d;
  return d;
}
25
 
 
Sparse Matrices
 
 
new scheme
Each column (row): a circular linked list with a head node
26
 
 Sparse Matrices - Representation
 
head node
 
entry
 
a
ij
 
i
 
j
 
entry node
 
a
ij
 
# of head nodes = max{# of rows, # of columns}
 
27
 
Linked Representation for Matrix
 
4
 
4
 
1
 
0
 
12
 
2
 
1
 
-4
 
0
 
2
 
11
 
3
 
3
 
-15
 
1
 
1
 
5
 
Circular linked list
 
a
 
H0
 
H1
 
H2
 
H3
28
29
 
Doubly Linked List
 
Move in forward and backward direction.
 
Singly linked list (in one direction only)
How to get the preceding node during deletion or insertion?
Using 2 pointers
 
Node in doubly linked list
left link field (llink)
data field (item)
right link field (rlink)
30
 
Doubly Linked Lists
 
typedef struct node *node_pointer;
typedef struct node {
    node_pointer llink;
    element item;
    node_pointer rlink;
}
 
head node
 
llink   item   rlink
 
   
ptr
= ptr->rlink->llink
= ptr->llink->rlink
31
 
    ptr
 
*Figure 4.24:
Empty doubly linked circular list with head node (p.180)
32
 
                
 
node
 
newnode
 
node
 
*Figure 4.25: 
Insertion into an empty doubly linked circular list (p.181)
33
 
Insert
 
void dinsert(node_pointer node, node_pointer newnode)
{
    
(1) 
newnode->llink = node;
    
(2) 
newnode->rlink = node->rlink;
    
(3) 
node->rlink->llink = newnode;
    
(4) 
node->rlink = newnode;
}
 
head node
 
llink   item   rlink
 
(2)
 
(4)
 
(1)
 
(3)
34
 
Delete
 
 
void ddelete(node_pointer node, node_pointer deleted)
{
    if (node==deleted) printf(“Deletion of head node
                             not permitted.\n”);
    else {
        
(1) 
deleted->llink->rlink= deleted->rlink;
        
(2) 
deleted->rlink->llink= deleted->llink;
            free(deleted);
    }
}
 
head node
 
llink   item   rlink
 
(1)
 
(2)
35
 
Doubly Linked List
 
Move in forward and backward direction.
 
Singly linked list (in one direction only)
How to get the preceding node during deletion or insertion?
Using 2 pointers
 
Node in doubly linked list
left link field (llink)
data field (item)
right link field (rlink)
36
 
Doubly Linked Lists
 
typedef struct node *node_pointer;
typedef struct node {
    node_pointer llink;
    element item;
    node_pointer rlink;
}
 
head node
 
llink   item   rlink
 
   
ptr
= ptr->rlink->llink
= ptr->llink->rlink
37
 
    ptr
 
*Figure 4.24:
Empty doubly linked circular list with head node (p.180)
38
 
                
 
node
 
newnode
 
node
 
*Figure 4.25: 
Insertion into an empty doubly linked circular list (p.181)
39
 
Insert
 
void dinsert(node_pointer node, node_pointer newnode)
{
    
(1) 
newnode->llink = node;
    
(2) 
newnode->rlink = node->rlink;
    
(3) 
node->rlink->llink = newnode;
    
(4) 
node->rlink = newnode;
}
 
head node
 
llink   item   rlink
 
(2)
 
(4)
 
(1)
 
(3)
40
 
Delete
 
 
void ddelete(node_pointer node, node_pointer deleted)
{
    if (node==deleted) printf(“Deletion of head node
                             not permitted.\n”);
    else {
        
(1) 
deleted->llink->rlink= deleted->rlink;
        
(2) 
deleted->rlink->llink= deleted->llink;
            free(deleted);
    }
}
 
head node
 
llink   item   rlink
 
(1)
 
(2)
 
Circularly Linked Lists
41
 
3    14
 
2    8
 
1    0
 
ptr
 
ptr
 
avail
 
...
 
avail
 
temp
 
circular list vs. chain
Slide Note
Embed
Share

Explore the concept of linked lists, a linear collection of data elements represented as nodes with information and addresses to the next node. Learn about implementations, traversing, and searching algorithms in linked lists with detailed explanations and visuals.

  • Data Structures
  • Linked Lists
  • Algorithms
  • Memory Representation
  • Traversing

Uploaded on May 15, 2024 | 1 Views


Download Presentation

Please find below an Image/Link to download the presentation.

The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author. Download presentation by click this link. If you encounter any issues during the download, it is possible that the publisher has removed the file from their server.

E N D

Presentation Transcript


  1. LINKED LIST MODULE 3 1

  2. Linked list is linear collection of data elements called nodes with each node having 2 parts INFORMATION of element ADDRESS of next node in the list Example External ptr bat cat sat vat NULL 2

  3. Representation of linked list in memory External ptr X T A K NULL INFO LINK 1 A 5 2 3 START 7 T 2 4 K 0 5 6 X 4 7 8 3

  4. creating a linked list Array implementation of List struct listnode { char info; int link; }; struct listnode node[MAX_SIZE]; int ptr=-1; Linked List using Dynamic variables struct listnode { char data; struct listnode * link; }; typedef struct listnode *listptr; Creation listptr ptr=NULL; Testing #define IS_EMPTY(ptr) (!(ptr)) Allocation cptr=(listptr) malloc (sizeof(listnode));

  5. Traversing a linked list Algorithm: Traversing(LIST) This algorithm traverses LIST. The variable PTR points to the node currently being processed Step 1 : Set PTR:=START Step 2: Repeat step 3 and 4 while PTR != NULL Step3: Apply process to INFO[PTR] Step 4 : Set PTR:=LINK[PTR] [End of Step2 loop] Step 5 :exit 5

  6. Searching in a linked list Searching in an unordered list SEARCH ( LIST,START,ITEM,LOC) LIST is a linked list. This algorithm finds the location LOC of the node where ITEM first appears in the list, or sets LOC =NULL Step 1: set PTR=START Step2: repeat step 3 while PTR !=NULL Step 3: If ITEM= INFO[PTR] then Set LOC:=PTR and exit Else Set PTR:=LINK[PTR] [End of If structure] [End of step 2 loop] Step 4: set LOC:=NULL [unsuccessful search] Step 5:exit 6

  7. Searching in a linked list Searching in an unordered list SRCHSL (LIST,START,ITEM,LOC) LIST is a sorted list. This algorithm finds the location LOC of the node where ITEM first appears in the list, or sets LOC =NULL Step 1: set PTR=START Step2: repeat step 3 while PTR !=NULL Step 3: If ITEM< INFO[PTR] then Set PTR:=LINK[PTR] Else ITEM = INFO[PTR] then Set LOC:=PTR and exit Else set LOC:=NULL and exit [End of If structure] [End of step 2 loop] Step 4: set LOC:=NULL [unsuccessful search] Step 5:exit 7

  8. Insert External ptr bat cat sat vat NULL Before insertion External ptr bat cat sat vat NULL Eat . After insertion 8

  9. 3 cases Insert at beginning Insert after a given node Insert in the sorted list 9

  10. Insert at beginning Algorithm: INSFIRST( INFO, LINK, START,AVAIL,ITEM) This algorithm inserts ITEM as the first node in the list 1 [ OVERFLOW? ] if AVAIL =NULL write OVERFLOW and Exit 2 [ Remove the first node from the AVAIL list] Set NEW:= AVAIL and AVAIL:=LINK[AVAIL] 3 Set INFO[NEW] := ITEM 4 Set LINK[NEW]:=START 5 Set START:=NEW 6 Exit start bat cat sat vat NULL start Eat . 10

  11. Insert after a given node Algorithm: INSLOC( INFO, LINK, START,AVAIL,LOC,ITEM) This algorithm inserts ITEM after the given location LOC 1 [ OVERFLOW? ] if AVAIL =NULL write OVERFLOW and Exit 2 [ Remove the first node from the AVAIL list] Set NEW:= AVAIL and AVAIL:=LINK[AVAIL] 3 Set INFO[NEW] := ITEM If LOC=NULL then, Set LINK[NEW]:=START and START:=NEW else Set LINK[NEW]:=LINK[LOC] and LINK[LOC]:=NEW [ End of If ] 5 Exit start 4 bat cat sat vat NULL Eat . 11

  12. Inserting into the sorted list Algorithm INSERT( INFO, LINK, START, AVAIL, ITEM) This algorithm inserts ITEM into the sorted linked list 1. Call FINDA(INFO, LINK, START, ITEM,LOC) 2. Call INSLOC(INFO, LINK, START, AVAIL,LOC, ITEM) 3. Exit Procedure: FINDA(INFO, LINK, START, ITEM,LOC) This procedure finds location LOC of the last node in a sorted list such that INFO[LOC] is less than ITEM or Sets LOC:=NULL 1. [ list empty? ] is START =NULL then Set LOC:=NULL and Return 2. If ITEM < INFO[START] then Set LOC:=NULL and Return 3. Set TRAIL:= START and PTR:=LINK[START] 4. Repeat steps 5 and 6 while PTR !=NULL 5. If ITEM< INFO[PTR] then Set LOC:= TRAIL and Return [ End of if ] 6 Set TRAIL :=PTR and PTR:=LINK[PTR] [End of step 4 loop] 7 Set LOC:= TRAIL 8 Return 12

  13. SINGLY LINKED LISTS Linked list An ordered sequence of nodes with links The nodes do not reside in sequential locations The locations of the nodes may change on different runs ptr bat cat sat vat NULL 13

  14. INFO LINK 1 0 AVAIL 5 A 0 2 1 3 START 7 T 2 4 6 5 8 6 X 4 7 3 8 14

  15. Memory allocation garbage collection A special list which is maintained for the unused memory cells is called as available list The OS of computer periodically collects all the deleted spaces onto the free storage list The technique that does this collection is called garbage collection 15

  16. Application of linked list As Data structure insafter , Delafter Operations To implement other data structures such as Stacks, Queue, ordered list like polynomial etc. 16

  17. Polynomials Representation struct polynode { int coef; int expon; struct polynode * link; }; typedef polynode * poly_pointer; poly_pointer a, b, c; coef expon link 17

  18. Example a= 3x14+ 2x8+ 1 b= 8x14- 3x10+ 10x6 a 3 14 . 2 8 . 1 0 null b 8 14 . -3 10 . 10 6 null 18

  19. Adding Polynomials 2 8 1 0 3 14 NULL a -3 10 10 6 8 14 NULL b 11 14 a->expon == b->expon NULL d 3 14 2 8 1 0 NULL a -3 10 10 6 8 14 NULL b 11 14 a->expon < b->expon -3 10 NULL d 19

  20. Adding Polynomials(Continued) Adding Polynomials 2 8 3 14 1 0 NULL a -3 10 10 6 8 14 NULL b -3 10 11 14 2 8 NULL d a->expon > b->expon 20

  21. Algorithm for Adding Polynomials poly_pointer padd(poly_pointer a, poly_pointer b) { poly_pointer front, rear, temp; int sum; rear =(poly_pointer)malloc(sizeof(poly_node)); if (IS_FULL(rear)) { fprintf(stderr, The memory is full\n ); exit(1); } front = rear; while (a && b) { switch (COMPARE(a->expon, b->expon)) { 21

  22. case -1: /* a->expon < b->expon */ attach(b->coef, b->expon, &rear); b= b->link; break; case 0: /* a->expon == b->expon */ sum = a->coef + b->coef; if (sum) attach(sum,a->expon,&rear); a = a->link; b = b->link; break; case 1: /* a->expon > b->expon */ attach(a->coef, a->expon, &rear); a = a->link; } } for (; a; a = a->link) attach(a->coef, a->expon, &rear); for (; b; b=b->link) attach(b->coef, b->expon, &rear); rear->link = NULL; temp = front; front = front->link; free(temp); return front; } Delete extra initial node. 22

  23. Representing Polynomials As Circularly Linked Lists Represent polynomial as circular list with header node. (1) zero -1 a Zero polynomial (2) others a 1 0 -1 2 8 3 14 = + + 3 2 1 14 8 a x x 23

  24. Padd Function poly_pointer cpadd(poly_pointer a, poly_pointer b) { poly_pointer starta, d, lastd; int sum, done = FALSE; starta = a; a = a->link; b = b->link; d = get_node(); d->expon = -1; lastd = d; do { switch (COMPARE(a->expon, b->expon)) { case -1: attach(b->coef, b->expon, &lastd); b = b->link; break; 24

  25. Padd(Continued) case 0: if (starta == a) done = TRUE; else { sum = a->coef + b->coef; if (sum) attach(sum,a->expon,&lastd); a = a->link; b = b->link; } break; case 1: attach(a->coef,a->expon,&lastd); a = a->link; } } while (!done); lastd->link = d; return d; } 25

  26. Sparse Matrices 0 0 11 0 12 0 0 0 0 4 0 0 0 0 0 15 new scheme Each column (row): a circular linked list with a head node 26

  27. Sparse Matrices - Representation # of head nodes = max{# of rows, # of columns} down head right head node next row col down entry right entry node value entry j i aij aij 27

  28. Linked Representation for Matrix a H2 H3 H1 H0 4 4 0 2 11 1 1 5 1 0 12 2 1 -4 3 3 -15 Circular linked list 28

  29. Doubly Linked List Move in forward and backward direction. Singly linked list (in one direction only) How to get the preceding node during deletion or insertion? Using 2 pointers Node in doubly linked list left link field (llink) data field (item) right link field (rlink) 29

  30. Doubly Linked Lists typedef struct node *node_pointer; typedef struct node { node_pointer llink; element item; node_pointer rlink; } ptr = ptr->rlink->llink = ptr->llink->rlink head node llink item rlink 30

  31. ptr *Figure 4.24:Empty doubly linked circular list with head node (p.180) 31

  32. node node newnode *Figure 4.25: Insertion into an empty doubly linked circular list (p.181) 32

  33. Insert void dinsert(node_pointer node, node_pointer newnode) { (1) newnode->llink = node; (2) newnode->rlink = node->rlink; (3) node->rlink->llink = newnode; (4) node->rlink = newnode; } head node llink item rlink (1) (3) (2) (4) 33

  34. Delete void ddelete(node_pointer node, node_pointer deleted) { if (node==deleted) printf( Deletion of head node not permitted.\n ); else { (1) deleted->llink->rlink= deleted->rlink; (2) deleted->rlink->llink= deleted->llink; free(deleted); } } head node (1) llink item rlink (2) 34

  35. Doubly Linked List Move in forward and backward direction. Singly linked list (in one direction only) How to get the preceding node during deletion or insertion? Using 2 pointers Node in doubly linked list left link field (llink) data field (item) right link field (rlink) 35

  36. Doubly Linked Lists typedef struct node *node_pointer; typedef struct node { node_pointer llink; element item; node_pointer rlink; } ptr = ptr->rlink->llink = ptr->llink->rlink head node llink item rlink 36

  37. ptr *Figure 4.24:Empty doubly linked circular list with head node (p.180) 37

  38. node node newnode *Figure 4.25: Insertion into an empty doubly linked circular list (p.181) 38

  39. Insert void dinsert(node_pointer node, node_pointer newnode) { (1) newnode->llink = node; (2) newnode->rlink = node->rlink; (3) node->rlink->llink = newnode; (4) node->rlink = newnode; } head node llink item rlink (1) (3) (2) (4) 39

  40. Delete void ddelete(node_pointer node, node_pointer deleted) { if (node==deleted) printf( Deletion of head node not permitted.\n ); else { (1) deleted->llink->rlink= deleted->rlink; (2) deleted->rlink->llink= deleted->llink; free(deleted); } } head node (1) llink item rlink (2) 40

  41. Circularly Linked Lists circular list vs. chain ptr 2 8 1 0 3 14 avail ptr temp avail ... 41

More Related Content

giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#