My problem:
The solution of my problem is:
Consider the smaller problem insert(head.next, e):
The solution of insert(head.next, e) is:
Suppose we have the solution of insert(head.next, e) avialable:
How can we use this solution to solve our original problem ?
Answer:
What remains: find a simple case to use a base case
Base case: (insert in an empty list)
Solution:
public static List insert( List head, List e ) { List helpSol; /* -------------------------------------------- Base case: insert at the tail of an empty -------------------------------------------- */ if ( head == null ) { e.next = null; // Mark e as the last list elem return(e); // e is the first list elem ! } else { /* =========================================================== Solve the problem USING the solution of a smaller problem =========================================================== */ helpSol = insert( head.next, e ); // Have "someone else" solve // this smaller problem head.next = helpSol; // Find MY solution using helpSol return head; // Return MY solution } } |
DEMO: /home/cs255001/demo/recursion/InsertList.java
public static List insert( List head, List e ) { /* -------------------------------------------- Base case: insert at the tail of an empty -------------------------------------------- */ if ( head == null ) { e.next = null; // Mark e as the last list elem return(e); // e is the first list elem ! } else { /* =========================================================== Solve the problem USING the solution of a smaller problem =========================================================== */ head.next = insert( head.next, e ); // Link directly to helpSol return head; // Return MY solution } } |
The Insert(head, p) function in ARM assembler:
Insert: /* ============================= Prelude: build stack frame ============================= */ push {lr} push {fp} mov fp, sp sub sp, sp, #0 // No local variables // if ( h == null ) ldr r0, [fp, #8] // r0 = h cmp r0, #0 bne else // e.next = null mov r0, #0 // r0 = null ldr r1, [fp, #12] // r1 = e str r0, [r1, #4] // e.next = null // return e ldr r0, [fp, #12] // r0 = e (return value) b postLude else: // h.next = Insert( h.next, e ); //// pass e ldr r0, [fp, #12] // r0 = e push {r0} // Pass e with stack //// pass h.next ldr r0, [fp, #8] // r0 = h ldr r0, [r0, #4] // r0 = h.next push {r0} // Pass h.next with stack bl Insert add sp, sp, #8 // Clean up 2 parameters //// Assign return value (in r0) to h.next ldr r1, [fp, #8] // r1 = h - can't use r0!! str r0, [r1, #4] // h.next = Insert(h.next,e) // return( h ); ldr r0, [fp, #8] // r0 = h (return value) postLude: // Postlude - clean up and return to caller mov sp, fp pop {fp} pop {pc} |
DEMO: /home/cs255001/demo/asm/9-list-recursion/ARM-Insert.s