32
SC417: DS & A Linear Data Structures Dhammika Elkaduwe PGIS & Department of Computer Engineering Faculty of Engineering University of Peradeniya Dhammika Elkaduwe SC417: DS & A Linear Data Structures

simple data structures

Embed Size (px)

DESCRIPTION

data structures and algorithms lecture notes

Citation preview

  • SC417: DS & ALinear Data Structures

    Dhammika Elkaduwe

    PGIS & Department of Computer EngineeringFaculty of Engineering

    University of Peradeniya

    Dhammika Elkaduwe SC417: DS & A Linear Data Structures

  • What is to come

    I Look at some simple data structures

    I Most of it you know and have used before :)

    I Mostly a recap of what was discussed

    Dhammika Elkaduwe SC417: DS & A

  • Linked list

    Limitation of arrays:

    I Need to know the size at the start! (at least some goodestimate)

    I Can not go beyond that!

    I (Keep note of the start of the array, can compute address ofany other element from there)

    Advantages of arrays:

    I Contiguous in memory (good cache locality if accessedsequentially)

    I Very limited bookkeeping is required (only need to know thestart of the array and its size )

    Alternative Linked list Used when we do not know the size inadvance and/or the size varies a lot! (need to think beforeselecting)

    Dhammika Elkaduwe SC417: DS & A

  • Linked list ...

    I Head points to the firstelement (ideal forsequential)

    I Add/remove items asrequired

    I Each element contains apointer to the next

    I No limit on how manyelements we can have

    I Additional storage forpointers

    In your program you need to store, on an average N integers. Inthe worst case this can be 2N. Should you use an array or linkedlist? Explain. (assume 32bit addresses).

    Dhammika Elkaduwe SC417: DS & A

  • Linked list in C

    struct linked_node {

    int data;

    struct linked_node * next;

    };

    typedef struct linked_node node_t;

    typedef node_t ** list_t;

    I Head points to the start of the linked list node, so headshould be pointer to a node

    I We should be able to change the value of head, so we need apointer of the head itself

    Dhammika Elkaduwe SC417: DS & A

  • Linked list in C, cnt ...

    list_t create_list(void)

    {

    list_t tmp = malloc(sizeof(node_t *));

    assert(tmp); // program cannot run if we get NULL

    *tmp = NULL;

    return tmp;

    }

    I Allocate memory for a node **

    I (see the text in the previous slide to know why we need **)

    I Make it point to NULL, indicating an empty list

    Dhammika Elkaduwe SC417: DS & A

  • Linked list in C, cnt ...

    int add(list_t list, int data)

    {

    node_t * tmp = malloc(sizeof(node_t));

    if(tmp) { // we have a new node, add

    tmp -> data = data;

    tmp -> next = *list;

    *list = tmp;

    return 0;

    }

    return -1; // no new node

    }

    I This function adds the given element as the head of thecurrent list

    I add can fail when there is no more memory, so returns an intto indicate whether the operation was successful or not.

    I (you can also use something like assert and make add returnvoid) Dhammika Elkaduwe SC417: DS & A

  • Linked list in C, cnt ...

    int remove(list_t list, int *data)

    {

    if(*list) {

    node_t *tmp = *list;

    *data = tmp -> data;

    *list = tmp -> next;

    free(tmp);

    return 1; // there were elements in the list

    }

    return 0; // no elements in the list

    }

    I Remove can fail, there might not be any elements to removeI Need to return the actual value and return success as wellI Typical solution in such situation is to return the success and

    store the result in a variable (int *data)

    Dhammika Elkaduwe SC417: DS & A

  • Typical interface of a Linked list

    First, comment on the idea of an interface;

    I Describes the behavior/operations of the data structure

    I Typically hides the implementation (more on this later)

    I Good idea for developing complex programs

    Linked list interface:

    I Add adds the given element to the listI remove removes the head of the given listI Delete delete all the elements of the listI Duplicate, addLast, addIndex ...

    Dhammika Elkaduwe SC417: DS & A

  • Simple application of a linked list

    int main()

    {

    int i;

    list_t list = create_list();

    for(i=0; i

  • Linked list in Java interface

    from:http://docs.oracle.com/javase/7/docs/api/java/util/LinkedList.html

    I add(E e)

    I add(int index, E e)

    I addFirst(E e)

    I contains(E e)

    I get(int index)

    I ...

    Note: Somewhat advanced than the simple structure wediscussed. Stemming from programmer needs! You might needdifferent representations to support implementing the aboveinterface (example: two pointers to find head and tail.)

    Dhammika Elkaduwe SC417: DS & A

  • Linked list variations

    Some issues of singly-linked list and variations to resolve issues:I Difficult to remove from the middle (you know the

    element/node, and want remove)I Doubly-linked list: Each node has two pointers: next and

    previous.

    I You need to worry about corner casesI Circular-linked list: Last node points to the first node

    I Combination of both variations: Circular-doubly-linked list

    Dhammika Elkaduwe SC417: DS & A

  • Coding exercise

    int remove_element(list_t list, int data)

    {

    }

    I the function remove the given item from the list

    I return 1 if found and deleted, 0 otherwise

    I how will you test this function?

    Dhammika Elkaduwe SC417: DS & A

  • Coding exercise

    int add_to_tail(list_t list, int data)

    {

    }

    I Add the given item as the last element of the list

    I how will you test this function?

    I If you run the same main function as before what will you seenow

    I what is the time complexity of this function?

    Dhammika Elkaduwe SC417: DS & A

  • Queue data structure

    Basic idea:

    I First-in First-out (FIFO) data structure

    I Linked list with tail insert and head removal

    should we have a doubly-linked list for this?should we have a circular-linked list for this?

    I Or can be implemented using an array

    Queue operations:

    I add(E e)

    I remove(E e)

    I peek()

    Used when every you need FIFO processing.Think of some Examples?

    Dhammika Elkaduwe SC417: DS & A

  • Priority Queues

    Oder or removal depends on priority

    I Internally the list is kept sorted. When adding a new elementadd to its correct place. (recall insertion sort)(insert O(N),removal O(1))

    I Else we can add to the tail and locate the element with thehighest priority when removing? (insert O(1), removal O(N))

    I Which method is better? Why?

    I Can we better this? (heap data structure)

    Dhammika Elkaduwe SC417: DS & A

  • Trivial priority queues in C

    add the element to the correct place! remove the first element

    int add(queue_t list, data_t data)

    {

    /* think of the cases,

    * draw some diagrams before coding !!

    */

    }

    Dhammika Elkaduwe SC417: DS & A

  • Trivial priority queues in C

    add the element to the correct place! remove the first element

    int add(queue_t list, data_t data)

    {

    node_t * tmp = malloc(sizeof(node_t));

    if(!tmp) return -1;

    tmp -> data = data;

    node_t * pre, *curr;

    pre = curr = *list;

    while(curr != NULL && curr -> data < data) {

    pre = curr;

    curr = curr -> next;

    }

    if(pre == *list) *list = tmp;

    else pre -> next = tmp;

    tmp -> next = curr;

    return 0;

    }

    Dhammika Elkaduwe SC417: DS & A

  • Using the queue

    The main function:

    int main()

    {

    int i;

    queue_t q = create_queue();

    for(i=0; i

  • The stack data structure

    Basic idea:

    I list of items that are accessible from only one end

    I Last-In First-Out (LIFO) data structure

    I Two main operations: push and pop

    I Other operations: isEmpty, peek, isFull ..

    I Can be implemented using arrays or linked lists

    Dhammika Elkaduwe SC417: DS & A

  • Stack application

    int factorial(int x) {

    if(x == 1) return 1;

    return x * factorial(x-1);

    }

    I A stack is used to postponeobligations, which must laterbe fulfilled in reverse order.

    I Recall implementing towerof Hanoi using non-recursiveimplementation.

    Dhammika Elkaduwe SC417: DS & A

  • Stack: The interface

    /* interface */

    stack_t create_stack(void);

    int push(stack_t, data_t);

    int pop(stack_t, data_t *);

    int isEmpty(stack_t);

    The interface can be implemented using array or linked list

    Dhammika Elkaduwe SC417: DS & A

  • Stack: Implementation based on array 1

    stack_t create_stack(void)

    {

    stack_t tmp = malloc(sizeof(struct stack));

    tmp -> index = 0;

    return tmp;

    }

    int isEmpty(stack_t s)

    {

    return s -> index == 0;

    }

    Dhammika Elkaduwe SC417: DS & A

  • Stack: Implementation based on array 2

    int push(stack_t s, data_t d)

    {

    if(s -> index == MAX) return -1;

    s -> data[s -> index ++] = d;

    return 0;

    }

    int pop(stack_t s, data_t *d)

    {

    if(isEmpty(s)) return 0;

    *d = s -> data[--s -> index];

    return 1;

    }

    Dhammika Elkaduwe SC417: DS & A

  • Stack: Implementation of interface using linked list

    Can you implement the same interface using an linked list?

    /* interface */

    stack_t create_stack(void);

    int push(stack_t, data_t);

    int pop(stack_t, data_t *);

    int isEmpty(stack_t);

    Try this as homework!

    Dhammika Elkaduwe SC417: DS & A

  • Use of a stack: Example 1: Converting to binary

    Convert the first argument into binary:

    int main()

    {

    stack_t s = create_stack();

    int a = data, rem, i;

    while(a >= 1) {

    rem = a % 2;

    assert(!push(s, rem));

    a = a / 2;

    }

    printf("%d in Binary = ");

    while(pop(s, &i)) printf("%d", i);

    printf("\n");

    }

    Dhammika Elkaduwe SC417: DS & A

  • Use of a stack: Example 2: Check brackets

    Algorithm:

    I Scan the string from left to right

    I When you find an opening bracket push it

    I When you find closing bracket pop and see if it matches

    I At the end of the string, stack should be empty.

    int checkBalance(char *str)

    {

    /* implement the rest */

    Dhammika Elkaduwe SC417: DS & A

  • Use of a stack: Example 2: Check brackets code

    int checkBal(char *str)

    {

    int len = strlen(str);

    int i, b;

    stack_t s = create_stack();

    for(i=0; i

  • Different types of expressions

    Expression type Example

    Postfix a b +Infix a + bPrefix + a b

    I In a postfix evaluation format for an arithmetic expression, anoperator comes after its operands.

    I In a infix evaluation format for an arithmetic expression, anoperator comes between its operands.

    I In a prefix evaluation format for an arithmetic expression, anoperator comes before its operands.

    Dhammika Elkaduwe SC417: DS & A

  • Infix to postfix

    Algorithm:I Read the expression from left to rightI If you find a operator push to stack until the operand has less

    precedence than the one on top of the stack.I When the operator has less precedence pop till stack is empty

    or operator has higher precedenceI Operands are put as is.I If the stack is not empty, pop them.

    Expression Output Stack

    A + B * C - DA + B * C - D AA + B * C - D A B +A + B * C - D A B C + *A + B * C - D A B C * + -A + B * C - D A B C * + D -

    Dhammika Elkaduwe SC417: DS & A

  • Evaluation of a postfix expression

    Algorithm:I Read the expression from left to rightI push the operands to stackI when you find an operator, pop two operands from the stack,

    do the operating and push the result.I At the end of the expression, stack should have only one value

    which is the evaluation of the expression.

    Original expression: A + B * C - D

    Expression Stack Current Operation

    A B C * + D -A B C * + D - A B CA B C * + D - A B * CA B C * + D - A (B * C)A B C * + D - A + (B * C)A B C * + D - A + (B * C) DA B C * + D - A + (B * C) - D

    Dhammika Elkaduwe SC417: DS & A

  • Exercises

    1. Implement a C function int evaluate(char * postfixExpression)which will evaluate the given postfix expression

    2. Implement a C function char * evaluate(char *postfixExpression) which will convert the infix expression intopostfix.

    3. Implement a solution for the tower of Hanoi without usingrecursion.

    Dhammika Elkaduwe SC417: DS & A