bi201: linux and shell programming lecture 05b: data...

34
BI201: Linux and Shell Programming Lecture 05B: Data Structure in C (1) Maoying,Woo [email protected] Dept. of Bioinformatics & Biostatistics Shanghai Jiao Tong University Spring, 2015 Maoying BI201

Upload: phungngoc

Post on 07-May-2019

218 views

Category:

Documents


0 download

TRANSCRIPT

BI201: Linux and Shell Programming

Lecture 05B: Data Structure in C (1)

Maoying,[email protected]

Dept. of Bioinformatics & BiostatisticsShanghai Jiao Tong University

Spring, 2015

Maoying BI201

Data structures

A data structure is a particular organization of data inmemory.

grouping related items togetherconvenient to program and efficient to execute the data

An array is one kind of data structureHere, we will introduce some data structures:

Linked list: Singly Linked List, Double linked list, CircularListQueueStack, HeapBinary tree, Bineary search treeHashingGraph, NetworkSuffix array, Suffix tree

Maoying BI201

Linked List

A linked list is an ordered collection of nodes, each ofwhich contains some data, connected using pointers.

Each node points to the next node in the list.The first node in the list is called the head.The last node in the list is called the tail, which points toNULL.

Maoying BI201

Linked list vs. Array

A linked list can only be accessed sequentiallyFor instance, to find the 5th element, you must start fromthe head and follow the links through four other nodes.Advantages of linked list:

Dynamic sizeEase of adding or removing nodes from the list (by addingor redirect links)

Drawback of linked list:Random access is not allowed.Extra memory space for the pointers

Maoying BI201

Linked list: Representation

A linked list is represented by a pointer to the first node(head).If the linked list is empty, the value of head is NULL.Each node in a list consists of at least two parts:(1) data(2) pointer to the next node

1 struct node2 {3 int data;4 struct node *next;5 };67 struct node* head = NULL;

Maoying BI201

Simple linked list

1 #include <stdio.h>2 #include <stdlib.h>3 struct node4 {5 int data;6 struct node *next;7 };89 int main()

10 {11 struct node* head = NULL;12 struct node* second = NULL;13 struct node* third = NULL;1415 head = (struct node*)malloc(sizeof(struct node));16 second = (struct node*)malloc(sizeof(struct node));17 third = (struct node*)malloc(sizeof(struct node));1819 head->data = 1; head->next = second;20 second->data = 2; second->next = third;21 third->data = 3; third->next = NULL;22 return 0;23 }

Maoying BI201

Linked list: Traversal

1 void printList(struct node *node)2 {3 while (node != NULL)4 {5 printf("%d ", node->data);6 node = node->next;7 }8 }9

10 int main()11 {12 ...;13 printList(head);1415 return 0;16 }

Maoying BI201

Linked list: Inserting a node

A node can be added in three ways:At the front of the linked list.

After a given node.

At the end of the linked list.

Maoying BI201

Add a node at the front

1 void push(struct node** head, int new)2 {3 /* 1. allocate node */4 struct node* new_node = (struct node*)malloc(sizeof(struct node));56 /* 2. put in the data */7 new_node->data = new;89 /* 3. make next of new node as head */

10 new_node->next = (*head);1112 /* 4. move the head to point to the new */13 (*head) = new_node;14 }

Maoying BI201

Add a node after a given node

1 void insertAfter(struct node* prev_node, int new)2 {3 /* 1. check if the given prev_node is NULL */4 if (prev_node == NULL)5 {6 printf("The given node cannot be NULL.\n");7 return;8 }9

10 /* 2. allocate new node */11 struct node* new_node = (struct node*)malloc(sizeof(struct node));1213 /* 3. put in the data */14 new_node->data = new;1516 /* 4. make next of new node as next of prev_node */17 new_node->next = prev_node->next;1819 /* 5. move the next of prev_node as new_node */20 prev_node->next = new_node;21 }

Maoying BI201

Add a node at the end

1 void apend(struct node** head, int new)2 {3 /* 1. allocate node */4 struct node* new_node = (struct node*)malloc(sizeof(struct node));56 struct node *last = *head;78 /* 2. put in the data */9 new_node->data = new;

1011 /* 3. the new node point to NULL */12 new_node->next = NULL;1314 /* 4. if the linked list is empty, make the new node as head */15 if (*head == NULL) *head = new_node;1617 /* 5. else traverse till the last node */18 while (last->next != NULL)19 last = last->next;2021 /* 6. change the next of last node */22 last->next = new_node;23 }

Maoying BI201

Linked list: Add nodes

1 int main()2 {3 struct node* head = NULL;45 /* Insert 6, list becomes 6->NULL */6 append(&head, 6);78 /* Insert 7 at the beginning, list becomes 7->6->NULL */9 push(&head, 7);

10 push(&head, 1);1112 /* Insert 4 at the end. */13 append(&head, 4);1415 /* insert 8, after 7 */16 insertAfter(head->next, 8);1718 /* traversal */19 printf("The linked list is: ");20 printList(head);2122 return 0;23 }

Maoying BI201

Linked list: Deleting a node

Find previous node of the node to be deleted.Change next of previous node.Free memory for the node to be deleted.

1 void deleteNode(struct node **head, int key)2 {3 /* store head node */4 struct node* temp = *head, *prev;56 /* if head holds the key to be deleted */7 if (temp != NULL && temp->data == key) {8 *head = temp->next;9 free(temp);

10 }1112 /* search for the key */13 while (temp != NULL && temp->data != key) {14 prev = temp;15 temp = temp->next;16 }1718 if (temp == NULL) {19 printf("Not exists");20 exit(1);21 }2223 prev->next = temp->next;24 free(temp);25 }

Maoying BI201

Find the length of a linked list

Iterative solution:(1) Initialize count = 0.(2) Initialize a node pointer current = head(3) While current != NULL

(a) current = current->next(b) count++

(4) Return count.

Recursive solution:

1 int getCount(head) {2 if (head == NULL) return 0;3 else return getCount(head->next) + 1;4 }

Maoying BI201

getSize(): Iterative solution

1 int getSize(struct node* head)2 {3 int count = 0;4 struct node* current = head;5 while (current != NULL)6 {7 count++;8 current = current->next;9 }

10 return count;11 }1213 int main()14 {15 struct node* head = NULL;16 push(&head, 1); push(&head, 3);17 push(&head, 1); push(&head, 5);18 push(&head, 4);1920 printf("size of linked list is %d\n", getSize(head));2122 return 0;23 }

Maoying BI201

getCount(): Recursive solution

1 int getCount(struct node* head)2 {3 if (head == NULL) return 0;4 return getCount(head->next) + 1;5 }67 int main()8 {9 struct node* head = NULL;

10 push(&head, 1); push(&head, 3);11 push(&head, 5); push(&head, 4);12 push(&head, 9);1314 printf("count of nodes is %d\n", getCount(head));1516 return 0;17 }

Maoying BI201

Search an element in a linked list

Iterative solution:(1) Initialize a node pointer, current = head(2) While current != NULL

(a) If current->key == key, return true(b) current = current->next

(3) return false

Recursive solution:(1) If head == NULL, return false(2) If head->data == key, return true(3) Else return search(head->next, key)

Maoying BI201

Search an element: Iterative solution

1 bool search(struct node* head, int key)2 {3 struct node* current = head;4 while (current != NULL)5 {6 if (current->data == key)7 return true;8 current = current->next;9 }

10 return false;11 }12 int main()13 {14 struct node* head = NULL;15 int x = 21;16 push(&head, 10); push(&head, 30);17 push(&head, 11); push(&head, 21)18 push(&head, 49);19 search(head, 21)?printf("Yes\n") : printf("No\n");2021 return 0;22 }

Maoying BI201

Search an element: Recursive solution

1 bool search(struct node* head, int key)2 {3 if (head == NULL) return false;4 if (head->data == key) return true;56 return search(head->next, key);7 }8 int main()9 {

10 struct node* head = NULL;11 int x = 21;12 push(&head, 10); push(&head, 30);13 push(&head, 11); push(&head, 21)14 push(&head, 49);15 search(head, 21)?printf("Yes\n") : printf("No\n");1617 return 0;18 }

Maoying BI201

Getting Nth node

1 int getNth(strut node* head, int index)2 {3 struct node* current = head;4 int count = 0;5 while (current != NULL)6 {7 if (count == index) return current->data;8 count++;9 current = current->next;

10 }11 assert(0);12 }13 int main()14 {15 struct node* head = NULL;16 push(&head, 1); push(&head, 4);17 push(&head, 12); push(&head, 13);18 push(&head, 21);1920 printf("Element at index 3 is %d\n", getNth(head, 3));21 return 0;22 }

Maoying BI201

Reverse a linked list

1 static void reverse(struct node** head) {2 struct node* prev = NULL;3 struct node* current = *head;4 struct node* next;5 while (current != NULL) {6 next = current->next;7 current->next = prev;8 prev = current;9 current = next;

10 }11 *head = prev;12 }13 int main() {14 struct node* head = NULL;15 push(&head, 20); push(&head, 4);16 push(&head, 15); push(&head, 21);17 push(&head, 65);18 printList(head);19 reverse(&head);20 printList(head);2122 return 0;23 }

Maoying BI201

Reverse: Recursive solution

(1) Divide the list into twoparts: first and rest

(2) Call reverse for the rest

(3) Link rest to first

(4) Fix head pointer

Maoying BI201

Recursive Reverse Solution

1 void recursiveReverse(struct node** head)2 {3 struct node* first;4 struct node* rest;56 if (*head == NULL) exit;78 first = *head;9 rest = first->next;

10 // list has only one node11 if (rest==NULL) exit;12 // reverse the rest list and put the first at the end13 recursiveReverse(&rest);14 first->next->next = first;1516 first->next = NULL;1718 *head = rest;1920 }

Maoying BI201

Circular Linked List

Circular linked list is a linked list where nodes areconnected to form a circle. There is no NULL at the end. Acircular linked list can be singly linked list or doubly linkedlist.

Advantages:Any node can be starting point.Useful for implementation of queue.Useful in applications to repeatedly go around the list.Circular doubly linked lists are used for implementation ofadvanced data structures like Fibonacci heap.

Maoying BI201

Doubly linked list (DLL)

A doubly linked list contains an extra pointer, typicallycalled prev pointer, together with next pointer, and datawhich are there in singly linked list.

Advantages:A DLL can be traversed in both directions.The delete operation in DLL is more efficient.

Disadvantages:Extra space for prev pointer.Extra operations for prev to be maintained.

Maoying BI201

Stack

Stack is a linear data structure which follows a particularorder in which the operations are performed. The ordermay be LIFO (Last In First Out) or FILO (First In Last Out).Three basic operations:

push: Adds an item in the stack. If the stack is full, thenthrow an overflow exception.pop: Removes an item from the stack. The items arepopped in the reversed order in which they are pushed. Ifthe stack is empty, throw an underflow exception.peek: Get the topmost item.

Stack can be implemented either by array, or by linked list.

Maoying BI201

Stack implementation using array (1)

1 struct stack {2 int top;3 unsigned capacity;4 int* array;5 };67 struct Stack* createStack(unsigned capacity) {8 struct Stack* stack = (struct Stack*)malloc(sizeof(struct Stack));9 stack->capacity = capacity;

10 stack->top = -1;11 stack->array = (int*)malloc(stack->capacity*sizeof(int));12 return stack;13 }1415 int isFull(struct Stack* stack) {16 return stack->top == stack->capacity-1;17 }1819 int isEmpty(struct Stack* stack) {20 return stack->top == -1;21 }

Maoying BI201

Stack implementation using array (2)

1 void push(struct Stack* stack, int item) {2 if (isFull(stack)) return;3 stack->array[++stack->top] = item;4 printf("%d pushed to stack\n", item);5 }67 void pop(struct Stack* stack) {8 if (isEmpty(stack)) return INT_MIN;9 return stack->array[stack->top--];

10 }1112 int peek(struct Stack* stack) {13 if (isEmpty(stack)) return INT_MIN;14 return stack->array[stack->top];15 }1617 int main() {18 struct Stack* stack = createStack(100);19 push(stack, 10); push(stack, 20);20 push(stack, 30);2122 printf("%d popped from stack\n", pop(stack));23 printf("Top item is %d\n", peek(stack));2425 return 0;26 }

Maoying BI201

Stack implementation using linked list (1)

1 struct StackNode {2 int data;3 struct StackNode* next;4 };56 struct StackNode* newNode(int data) {7 struct StackNode* stackNode =8 (struct StackNode*)malloc(sizeof(struct StackNode));9 stackNode->data = data;

10 stackNode->next = NULL;11 return stackNode;12 }1314 int isEmpty(struct StackNode *root) {15 return !root;16 }

Maoying BI201

Stack implementation using linked list (2)

1 void push(struct StackNode** root, int data)2 {3 struct StackNode* stackNode = newNode(data);4 stackNode->next = *root;5 *root = stackNode;6 printf("%d pushed to stack\n", data);7 }89 void pop(struct StackNode** root) {

10 if (isEmpty(*root)) return INT_MIN;11 struct StackNode* temp = *root;12 *root = (*root)->next;13 int popped = temp->data;14 free(temp);1516 return popped;17 }1819 int peek(struct StackNode* root) {20 if (isEmpty(root)) return INT_MIN;21 return root->data;22 }2324 int main()25 {26 struct StackNode* root = NULL;27 push(&root, 10); push(&root, 20);28 push(&root, 30);29 printf("%d popped from stack\n", pop(&root));30 printf("Top element is %d\n", peek(root));3132 return 0;33 } Maoying BI201

Queue

Queue is a linear structure which follows a particular orderin which the operations are performed. The order is FIFO(First In First Out).The difference between stacks and queues is in removing.

In a stack, we remove the item the most recently addedIn a queue, we remove the item the least recently added

Operations on queue:enqueue: adds an item to the queue.dequeue: removes an item from the queue.front: get the front item from queuerear: get the last item from queue.

The queue can be implemented in array.

Maoying BI201

Queue implementation using array (1)

1 struct Queue {2 int front, rear, size;3 unsigned capacity;4 int* array;5 };6 struct Queue* createQueue(unsigned capacity) {7 struct Queue* queue = (struct Queue*)malloc(sizeof(struct Queue));8 queue->capacity = capacity;9 queue->front = queue->size = 0;

10 queue->rear = capacity - 1;11 queue->array = (int*)malloc(queue->capacity * sizeof(int));12 return queue;13 }14 int isFull(struct Queue* queue) {15 return (queue->size == queue->capacity);16 }17 int isEmpty(struct Queue* queue) {18 return (queue->size == 0);19 }

Maoying BI201

Queue implementation using array (2)

1 void enqueue(struct Queue* queue, int item) {2 if (isFull(queue) return;3 queue->rear = (queue->rear + 1)%queue->capacity;4 queue->array[queue->rear] = item;5 queue->size++;6 printf("%d enqueued to queue\n", item);7 }8 int dequeue(struct Queue* queue) {9 if (isEmpty(queue)) return INT_MIN;

10 int item = queue->array[queue->front];11 quue->front = (queue->front+1)%queue->capacity;12 queue->size--;13 return item;14 }1516 int front(struct Queue* queue){17 if (isEmpty(queue)) return INT_MIN;18 return queue->array[queue->front];19 }2021 int rear(struct Queue* queue) {22 if (isEmpty(queue)) return INT_MIN;23 return queue->array[queue->rear];24 }

Maoying BI201

Queue implementation using array (3)

1 int main()2 {3 struct Queue* queue = createQueue(1000);4 enqueue(queue, 10); enqueue(queue, 20);5 enqueue(queue, 30); enqueue(queue, 40);6 printf("%d dequeued from queue\n", dequeue(queue));7 printf("Front item is %d\n", front(queue));8 pirntf("Rear item is %d\n", rear(queue));9

10 return 0;11 }

Maoying BI201