งานนำเสนอกำลังจะดาวน์โหลด โปรดรอ

งานนำเสนอกำลังจะดาวน์โหลด โปรดรอ

List, Stack, Queue 2018/9/21.

งานนำเสนอที่คล้ายกัน


งานนำเสนอเรื่อง: "List, Stack, Queue 2018/9/21."— ใบสำเนางานนำเสนอ:

1 List, Stack, Queue 2018/9/21

2 List It is about putting things in a sequence. Example: A1,A2,A3,…,An
first last 2018/9/21

3 What can we do with a list
Find – find a specified member. Insert – insert a new member at a specified position. findKth – return the kth element. Remove – remove a specified element from list. Head – return the first member. Tail – return the list without its first member. Append – combine 2 lists. 2018/9/21

4 What if we create a list from an array?
Do not forget that an array needs us to specify its length. Find -> O(n) Because we need to search from the first element of the list. findKth –O(1) We can use index to find the kth element directly. Insert and remove may take a long time Because all members may be shifted. ตัวอย่างของการใช้เวลาตอน insert -- ถ้าเราใส่สมาชิกไปที่หัวอาร์เรย์ ส่วนอื่นๆในช่องถัดไปก็ต้องเลื่อนช่องหมด ทำให้กินเวลามาก การ delete ก็เช่นเดียวกัน ถ้าเราเอาส่วนหัวอาร์เรย์ออก ส่วนอื่นๆก็ต้องเลื่อนขึ้นมาทุกๆช่อง 2018/9/21

5 Linked list Find -> O(n) findKth(i) -> O(i)
A1 A3 A2 node Find -> O(n) because we still need to start at the biginning of the list. findKth(i) -> O(i) Because we cant use array index any more. Linked list คือมี object (เรียกอีกอย่างว่า node) ที่เก็บค่าหรือ object ตัวอื่นไว้ แล้วมี reference ต่อกันเป็นทอดๆ ตัวสุดท้ายจะไม่มี reference ไปถึงอะไร (เรียกอีกอย่างว่า มี reference เป็น null) 2018/9/21

6 Linked list (cont.) The original list When A2 is removed.
Deletion is easier (no need to shift members) We only need to point reference over to the next node. The original list A1 A3 A2 When A2 is removed. การเปลี่ยน pointer (หรือ reference) เพื่อลบ A2 ออก ทำได้ดังนี้ เก็บตัว pointer ที่ชี้จาก A2 ไปเอาไว้ในตัวแปร แล้วให้ A2 ชี้ไปที่ null (จริงๆไม่ต้องให้ A2 ชี้ไปที่ null ก็ได้เพราะ pointer นี้ก็ไม่ทำให้เข้าถึง A2 ได้อยู่ดี) เอา pointer ที่ชี้ไปที่ A2 เปลี่ยนไปเป็นตัวแปรที่เก็บไว้ ถ้าเอา A2 ออกแล้ว เมื่อไม่มี reference เข้าถึง A2 ได้อีก Java จะลบ A2 ไปเองเพราะมี garbage collection A1 A2 A3 2018/9/21

7 Linked list (cont 2.) Insertion is also similar.
The original list After inserting x between A2 and A3. A1 A3 A2 x การ insert x ก็จะใช้การเปลี่ยน pointer (หรือ reference) เอา pointer จาก A2 ชี้ไปที่ x เอา pointer จาก x ชี้ไปที่ A3 2018/9/21

8 Insert -> a small problem
Inserting the first member is different from inserting others. No other node pointing to x. Need the former A1 reference to point to x. A1 A3 A2 x ถ้าเราทำการ insert ของลงไปข้างหน้าโนดแรก หลักการยังเหมือนเดิม ต่างกันตรงรายละเอียด เนื่องจากไม่มี node ที่อยู่ก่อน A1 ดังนั้นจึง set pointer จากโนดนั้นไม่ได้ แต่เราสามารถตั้งค่า pointer จาก x มาได้ แล้วจึงตั้งค่า pointer จากหัวลิสต์ A1 มาที่ x เพื่อให้เป็นหัวลิสต์ใหม่ จริงๆแล้วการเอาของออกจากหัวลิสต์ก็จะทำให้ต้องโค้ดในกรณีพิเศษเหมือนกัน The code needs to be different from other insertions. 2018/9/21

9 We can avoid such special case.
We have a dummy node (or header) at the front of the list. With this solution, every node will have a node in front, therefore all codes will be the same. A1 A3 A2 header Empty list 2018/9/21

10 Code: node class ListNode { // Constructors
ListNode( Object theElement ) this( theElement, null ); } ListNode( Object theElement, ListNode n ) element = theElement; next = n; theElement หน้านี้แสดง constructor โดยมีตัวที่สองเป็นหลัก ตัวแรกเมื่อถูกเรียกใช้ก็จะไปเรียกตัวที่สองอีกต่อหนึ่ง เพียงแค่ให้ตัวที่ชี้ไปโนดถัดไปชี้ไปที่ null แทน n ที่ชี้ไปคือโนดอีกตัวนั่นเอง ตัว instance variable อยู่หน้าถัด Point to n. theElement 2018/9/21

11 // Friendly data; accessible by other package routines Object element;
ListNode next; } Instance variables 2018/9/21

12 List iterator Is an object pointing to a node we are interested in.
Why do we have to write this class separate from list? We can keep an interested node in our list anyway, right? It’s because If we use iterator, we can keep a general form of list separate from any interested node. 2018/9/21

13 Code: iterator public class LinkedListItr {
ListNode current; //interested position /** theNode any node in the list */ LinkedListItr( ListNode theNode ) current = theNode; } หน้านี้เป็น constructor ของ iterator โดยเราสร้าง iterator ขึ้นมาให้ชี้ไปยังโนดที่เราสนใจทันที 2018/9/21

14 /** see if current has passed the last element of the list.
true if current is null */ public boolean isPastEnd( ) { return current == null; } /** item stored in current, or null if * current is not in a list. public Object retrieve( ) return isPastEnd( ) ? null : current.element; 2018/9/21

15 * move current to the next position in the list.
/** * move current to the next position in the list. * If current is null, do nothing. */ public void advance( ) { if( !isPastEnd( ) ) current = current.next; } 2018/9/21

16 Code: linked list public class LinkedList { private ListNode header;
public LinkedList( ) header = new ListNode( null ); } public boolean isEmpty( ) return header.next == null; ต้องบอกว่าโค้ดที่เราแสดง เป็น linked list ที่สร้างขึ้นเอง ในจาวาจะมี linked list กับ iterator อยู่แล้ว ซึ่งจะซับซ้อนกว่านี้ แต่ก็สร้างด้วยหลักการเดียวกัน ซึ่งเราจะได้เห็นในบทต่อๆไป ในโค้ดนี้เราจะใช้ dummy node 2018/9/21

17 /** make the list empty.*/ public void makeEmpty( ) {
header.next = null; } /** * return iterator that points to the header node. */ public LinkedListItr zeroth( ) return new LinkedListItr( header ); 2018/9/21

18 public LinkedListItr first( ) {
/* return iterator that points to the node next to header (can be null if the list is empty.)*/ public LinkedListItr first( ) { return new LinkedListItr( header.next ); } /** insert a new node following the position pointed to by p. x item to be in the new node. p iterator of the position before the new node. */ public void insert( Object x, LinkedListItr p ) if( p != null && p.current != null ) p.current.next = new ListNode( x, p.current.next ); ตอน insert ต้องเช็คว่า p มีตัวตน และชี้ไปที่โนดหนึ่งจริงหรือเปล่า ไม่งั้นจะทำไม่ได้ การเปลี่ยน pointer เพื่อการ insert จะเหมือนที่แสดงในรูปตอนแรก เพียงแต่เราเข้าถึงโนดที่อยู่ก่อนตัวที่จะเติมลงไป ได้โดยใช้ iterator 2018/9/21

19 * @param x object that we want to find.
/** x object that we want to find. iterator that points to the first node that has x. *If x is not in the list, the iterator points to null. * */ public LinkedListItr find( Object x ) { /* 1*/ ListNode itr = header.next; /* 2*/ while( itr != null && !itr.element.equals( x ) ) /* 3*/ itr = itr.next; /* 4*/ return new LinkedListItr( itr ); } นี่เป็นการวนลูปเรื่อยๆ โดยเริ่มจากโนดแรกที่มีของ จนกว่าจะเจอ x หรือสิ้นสุดลิสต์ แล้วจึงสร้าง iterator ที่ชี้ไปยังที่ที่ x อยู่ (หรือชี้ไปที่ null ถ้า x ไม่อยู่ในลิสต์เลย) 2018/9/21

20 * return iterator that points to a node before the first
/** * return iterator that points to a node before the first *node that has x. If there is no x in the list, return iterator *that points to the last node in the list. */ public LinkedListItr findPrevious( Object x ) { /* 1*/ ListNode itr = header; /* 2*/ while( itr.next != null && !itr.next.element.equals( x ) ) /* 3*/ itr = itr.next; /* 4*/ return new LinkedListItr( itr ); } การวนลูปจะเกือบเหมือนกับ find เพียงแต่ว่า ใช้ itr.next แทน itr เพื่อให้ตรวจสอบได้ยังโนดถัดไป เมื่อเจอ x ในโนดถัดไป จะได้ รีเทิร์น iterator ที่ชี้ไปโนดปัจจุบัน(ซึ่งอยู่ก่อน x พอดี) ส่วนถ้าไม่เจอ x เราก็ยังได้รู้ว่าโนดถัดไปจะเป็น null เราจะได้รีเทิร์น iterator ที่ชี้ไปโนดปัจจุบันซึ่งเป็นโนดสุดท้ายพอดี 2018/9/21

21 * remove the first node with x from the list.
/** * remove the first node with x from the list. x is the item to be removed from the list. */ public void remove( Object x ) { LinkedListItr p = findPrevious( x ); if( p.current.next != null ) //mean x is found because // p is not the last member. p.current.next = p.current.next.next; //move reference //over x } 2018/9/21

22 public static void printList( LinkedList theList ) {
if( theList.isEmpty( ) ) System.out.print( "Empty list" ); else LinkedListItr itr = theList.first( ); for( ; !itr.isPastEnd( ); itr.advance( ) ) System.out.print( itr.retrieve( ) + " " ); } System.out.println( ); นี่เป็นการพิมพ์เนื้อในของแต่ละโนดเรียงไปจนหมด โดยใช้การลูปที่ iterator ตั้งแต่สมาชิกตัวแรกของลิสต์จนถึงสมาชิกตัวสุดท้าย ใช้เมธอดของ iterator ทั้งหมด 2018/9/21

23 Doubly linked list Node has extra instance variable:
Previous : point to the node in front. This works the same way as next, but pointing in a different direction. We can search both ways. Additional time to change pointers. 2018/9/21

24 Insert: doubly linked list
A1 A3 A2 X 1 newnode 3 2 4 P การ insert ใน doubly linked list เป็นขั้นตอนดังนี้ newnode.next = p.next; newnode.previous = p.next.previous; p.next.previous = newnode; p.next = newnode; 2018/9/21

25 Remove: doubly linked list
A1 A3 A2 2018/9/21

26 Circular Linked list Last node points to the first node.
no dummy node needed. We can even make it into a doubly linked list. 2018/9/21

27 linked list example Let us want to store a polynomial
We can use array, using index i to store the coefficient of a0 a1 a2 2018/9/21

28 Using array to store polynomial
When adding polynomials a0 a1 a2 a0 a1 a2 The answer comes from the addition of corresponding slots, as shown. 2018/9/21

29 Using array to store polynomial (2)
multiplying two polynomial a0 a1 a2 Each slot multiplies every slot of the other polynomial, then all results are added. If there are many terms with 0 coefficient, there will be so many multiplication with 0. Waste of time. 2018/9/21

30 use linked list instead
Reduce the number of 0. Save space. Example: 5x75+11x125+8 5 75 11 125 8 header coefficient Power of x 2018/9/21

31 Skip list A node can have more than one “next” pointers.
The extra pointers point to other parts of the list. 2 6 8 5 122 15 In this example, every node has a pointer to next. A node in a position that is divisible by two will also have a pointer pointing to the next node with that quality. Same for a node in a position divisible by four. วิธีการหาของในลิสต์แบบนี้เริ่มจากการหาด้วยลิงค์ระดับสูงสุด (กระโดดข้ามมากที่สุด) ก่อน ถ้าไล่ตามลิงค์ระดับสูงสุดหาจนหมดลิสต์แล้วยังไม่เจอ ก็เริ่มหาใหม่โดยใช้ลิงค์ระดับที่ต่ำลงมา ทำเช่นนี้ไปเรื่อยๆ ถ้าระหว่างที่หา เกิดเจอโนดที่ต้องอยู่ข้างหลังโนดที่เราต้องการแน่ๆ ก็ให้ย้อนกลับมาหนึ่งโนด แล้วเริ่มการค้นหาจากโนดนั้นโดยใช้ลิงค์ระดับที่ต่ำลงระดับที่ต่ำลงมา จากรูป ถ้าเราต้องการหา 15 เริ่มแรกใช้ลิงค์ระดับสูงมาดูที่ 8 แล้วดูตัวถัดไป แต่ว่ามันเกิน 15 ดังนั้นเราจึงเริ่มที่ 8 แล้วหาด้วยลิงค์ระดับต่ำลงมา จึงเจอ 15 จะเห็นว่าใช้การตามลิงค์เป็นจำนวนน้อยครั้งกว่าการตามลิงค์ตั้งแต่สมาชิกตัวแรก ในกรณีที่หาของเจอ เวลาเฉลี่ยนั้นเป็น O(log n) ส่วนกรณีที่แย่ที่สุดนั้นเกิดจากการหาไม่เจอซึ่งต้องทำให้เริ่มหาใหม่จากลิงค์ระดับต่ำสุด ซึ่งกินเวลา O(n) 2018/9/21

32 Skip list problem Inserting and removing an element will cause all pointers structure to be changed. Too hard to do. Usually only the number of pointers for each level is enforced. Example: a 20 node list. Level 0 –> 20 nodes Level 1– > 10 nodes Level 2 -> 5 nodes Level 3 -> 2 nodes ถ้าเราจะให้มีลิงค์ 4 ระดับ โดยระดับ n เริ่มจากโนดลำดับที่ 2n และลิงค์ข้ามไปเป็นจำนวน 2n โนด สมมติว่ามีจำนวนโนดตอนเริ่มต้นอยู่ 20 โนด จะต้องมีโนดที่มีลิงค์ระดับต่างๆดังนี้ ระดับที่ 0 –> 20 โนด เพราะระดับล่างสุดต้องเป็นลิงค์ลิสต์แบบปกติ ระดับที่ 1 – >10 โนด ระดับที่ 2 –> 5 โนด ระดับที่ 3 –> 2 โนด ถ้าเราถือว่าไม่นับโนดซ้ำ จะมีโนด ระดับที่ 2 –> 5-2 = 3 โนด ระดับที่ 1 -> 10 – 2-3 = 5 โนด ระดับที่ 0 -> = 10 โนด ในการเติมโนดใหม่เข้าไป ให้สุ่มตัวเลขจาก 1 ถึง 20 มา ถ้าตัวเลขนั้นอยู่ระหว่าง 1 ถึง 10 ก็ให้ใส่โนดที่มีลิงค์ระดับที่ 0 ถ้าตัวเลขนั้นอยู่ระหว่าง 11 ถึง 15 ก็ให้ใส่โนดที่มีลิงค์ถึงระดับที่ 1 ถ้าเป็นเลข 16 ถึง 18 ก็ให้ใส่โนดที่มีลิงค์ถึงระดับที่ 2 2018/9/21

33 Skip list problem (cont)
The number of nodes in the example: Level 3 -> 2 nodes Level 2 -> 5-2 = 3 nodes Level 1 -> = 5 nodes Level 0 -> = 10 nodes When adding a new node, random a number between 1 and 20. 1 to 10 -> add the node with link level 0. 11 to 15 -> add the node with link level 1. And so on. 2018/9/21

34 Self-Organizing List Put the data just viewed in front of the list, or
Swap the node just viewed with a node in front, or Putting elements according to access frequency, or Use a specific ordering scheme, such as alphabetically ordered. Good for searching. If we cannot find an element within a certain number of steps, we will know that the element is not in a list. 2018/9/21

35 Self-Organizing List(cont.)
Adam Drozdek (he has a book on data structure) found that Putting the most recently viewed data in front of a list yields the same speed as ordering the list by data access frequency. Faster than swapping the node just viewed with a node in front. Using a specific ordering scheme. 2018/9/21

36 Multilist or Sparce Matrix
Example: data of all students and all subjects taught by our university. We must be able to: Find all subjects a particular student is taking. Find all students enroll in a particular subject. We can use a 2D array to create a table of students and subjects. But there will be lots of empty spaces. A medical student and an engineering student surely enroll in different subjects. We can fix this problem by making a 2D list. 2018/9/21

37 Student 1 2 3 Subj 1 2 3 ให้มีโนดว่างอยู่ในลิสต์ เป็นตัวบอกการมีอยู่ของนิสิตและวิชา ถ้าเราต้องการหานิสิตที่เรียนวิชา 1 ทั้งหมดก็ให้ตามลิงค์ไปจากเฮดเดอร์ของวิชา 1 (ซ้ายไปขวาในรูป) พอเจอโนดก็เก็บพอยต์เตอร์ที่ชี้ไปโนดนี้ไว้ก่อน(สมมติว่าเก็บในตัวแปร t) แล้วจึงหาชื่อนิสิตโดยการตามลิงค์ในแนวดิ่งจนเจอเฮดเดอร์ที่บอกชื่อนิสิต จากนั้นก็ตามลิงค์จาก t ต่อไป วิธีนี้จะมีปัญหาตรงที่ต้องตามลิงค์แนวดิ่งไปเรื่อยๆ จนกว่าจะเห็นเฮดเดอร์ ซึ่งอาจจะนานได้(แต่จริงๆไม่น่าจะเกิดขึ้นเพราะนิสิตจะลงทะเบียนเรียนวิชาเป็นสัดส่วนน้อยมากเมื่อเทียบกับจำนวนวิชาทั้งหมดในจุฬา) ถ้าต้องการประหยัดเวลาก็ให้เก็บลิงค์ที่ชี้ไปยังเฮดเดอร์โดยตรงในทุกๆโนด หรือเก็บชื่อวิชาและนิสิตไว้ในทุกๆโนด ซึ่งจะทำให้เปลืองที่ในการเก็บมากขึ้น(แต่ก็ยังน้อยกว่าการใช้อาร์เรย์สองมิติ) 2018/9/21

38 graph Sparce table Node directory 2018/9/21 B A C A B C D E E D A B E
วิธีที่ง่ายที่สุดคือการสร้างตารางขึ้นมาแล้วสร้างลิงค์ลิสต์แบบที่ทำกับตารางสปาร์ซ ในรูปนี้ ข้อมูลลิงค์ในแนวตั้งและแนวนอนนั้นเหมือนกัน เราจึงสามารถตัดลิงค์ในแนวหนึ่งทิ้งได้ ถ้าเป็นกราฟลูกศรมีทิศทางเดียว ตารางจะไม่สมมาตร ทำให้ต้องใช้ข้อมูลทั้งสองแกน นอกจากนี้ยังมีวิธีอื่นที่เป็นที่นิยมใช้ในการเก็บข้อมูลของกราฟ เช่น การใช้โนดไดเร็กทอรี่ หรือพูดง่ายๆคือ ลิงค์ลิสต์ที่ลิงค์ไปยังอาร์เรย์ของโนด C Node directory 2018/9/21

39 stack Are divided into levels. We can only insert and remove things one way. (LIFO = last in, first out) What can we do: Push – put an object at the top. Pop – remove the top most element. Top – return the top element without removing anything. A B C จริงๆ stack ก็คือลิสต์ทางเดียวนั่นเอง ดังนั้นเราสามารถทำ stack ขึ้นจากลิสต์ได้ หรือทำจากอาร์เรย์ก็ได้ 2018/9/21

40 Making a stack from list
Push = insert new object next to header. Pop = remove object next to header. If the list is originally empty, we can Do nothing, or throw exception. Top = return an element in the node next to header. 2018/9/21

41 Stack code Modified from linked list private ListNode top;
For simplicity, we do not have a header in this example. We can make a stack even though we do not have header. public class StackFromLinkedList { private ListNode top; public StackFromLinkedList( ){ top = null; } ให้มีตัวแปร top ที่เก็บโนดบนสุดของ stack ไว้ตลอดเวลา 2018/9/21

42 * @return always return false. */ public boolean isFull( ) {
/** always return false. */ public boolean isFull( ) { return false; } true if stack is empty, otherwise return false. public boolean isEmpty( ) return top == null; สังเกตว่า stack ที่ว่าง คือ stack ที่ไม่มีส่วน top 2018/9/21

43 Top does not change stack.
public void makeEmpty( ) { top = null; } /** top of stack, or null if empty. */ public Object top( ) if( isEmpty( ) ) return null; return top.element; Top does not change stack. Can choose to throw exception. 2018/9/21

44 Just moving the pointer over.
/** * remove element on top of stack. Underflow if stack is empty. */ public void pop( ) throws Underflow { if( isEmpty( ) ) throw new Underflow( ); top = top.next; } Can choose to do nothing. Just moving the pointer over. 2018/9/21

45 * @return popped item, or null if the stack is empty. */
/** * top() and pop() popped item, or null if the stack is empty. */ public Object topAndPop( ) { if( isEmpty( ) ) return null; Object topItem = top.element; top = top.next; return topItem; } Can choose to throw exception. 2018/9/21

46 Old node New node /** * put new element on top of stack.
x element we want to put in stack. */ public void push( Object x ) { top = new ListNode( x, top ); } เวลาของทุกๆเมธอดเป็นค่าคงที่หมด เพราะไม่มีอะไรที่เกี่ยวกับขนาดของ stack เลย Old node New node New top points to old top. 2018/9/21

47 Stack weakness When popped out, an element disappear forever.
We need to keep elements in extra variables, or another stack. 2018/9/21

48 Creating stack with array
Do not forget that we need to specify array size. Let a stack have arrayBody topIndex – index of the top element. (-1 if the stack is empty.) 2018/9/21

49 Code: stack made from array
public class StackFromArray { private Object [ ] arrayBody; private int topIndex; static final int DEFAULT_CAPACITY = 10; public StackFromArray( ) { this( DEFAULT_CAPACITY ); } 2018/9/21

50 * create a stack, specifying its capacity.
/** * create a stack, specifying its capacity. capacity number of elements the * stack can hold. */ public StackFromArray( int capacity ) { arrayBody = new Object[ capacity ]; topIndex = -1; } การสร้างสแตกนั้นก็คือการสร้างอาร์เรย์แล้วใส่ค่าที่ถูกต้องให้กับ topIndex นั่นเอง โดยถือว่าค่า -1 หมายถึงสแตกว่าง 2018/9/21

51 public boolean isEmpty( ) { return topIndex == -1; }
public boolean isFull( ) return topIndex == arrayBody.length - 1; public void makeEmpty( ) topIndex = -1; จะเห็นว่า isFull ในนี้ไม่เหมือนกับตอนใช้ linked list ตอนนี้เราใช้อาร์เรย์แล้ว ดังนั้นจึงมีเนื้อที่จำกัด 2018/9/21

52 Can choose to throw exception.
public Object top( ) { if( isEmpty( ) ) return null; return arrayBody[ topIndex ]; } /** * remove top element from stack. Underflow if the stack is empty. */ public void pop( ) throws Underflow throw new Underflow( ); arrayBody[ topIndex-- ] = null; Can choose to throw exception. Set to null Then move index 2018/9/21

53 * Remove top element from stack and return that element.
/** * Remove top element from stack and return that element. object on top of stack or null if the stack is empty. */ public Object topAndPop( ) { if( isEmpty( ) ) return null; Object topItem = top( ); arrayBody[ topIndex- - ] = null; return topItem; } Can choose to throw exception. 2018/9/21

54 * @param x object to put on top of tack.
/** * put x in stack if the stack is not full x object to put on top of tack. Overflow if the stack is full. */ public void push( Object x ) throws Overflow { if( isFull( ) ) throw new Overflow( ); arrayBody[ ++topIndex ] = x; } move index and then put x in. 2018/9/21

55 Using stack (1) Balancing check Check bracket pair. Read program text.
If see “(“ , put it in stack. If see “)”, pop top of stack. Print error if do not find “(“ in stack when reading “)”. When finish, if stack is not empty -> error too. 2018/9/21

56 Using stack (2) Postfix expression (reverse polish)
[7+(8*9)+5]*10 = * * We can use stack to evaluate a postfix expression: Read a number -> push to stack. Read an operator -> pop numbers in the stack and use the operator on the numbers. 9 Example: reading the first three numbers. 8 7 2018/9/21

57 put the result back in stack. Pop two numbers, multiply.
When reading * put the result back in stack. Pop two numbers, multiply. 9 8 72 7 7 Then read 5 in normally. read +, pop the top two and add them. 5 5 72 72 77 7 7 7 2018/9/21

58 The same for the second +.
77 7 84 Reading 10 normally. When reading *, pop the top two and * them. 10 10 84 84 840 answer 2018/9/21

59 Using stack (3) Change infix to postfix
Operand -> output it right away. operator -> keep it on stack. Keep “(“ on stack too. When reading “)”-> pop and output continuously until we find “)”. Let’s see an example. 2018/9/21

60 a+b*c+(d*e+f)*g read a,+,b -> put a and b in output. Put + on top of stack. + a b read * and read c -> put * on top of stack. Put c in output. * + a b c read + -> must pop equal (or more) priority operator out to output, before we push the + on top of stack. + a b c * + 2018/9/21 new

61 + pushed in after popping equal (or more) priority operators.
read “(“ and d -> put “(“ into stack, waiting for “)”. We put d to output. ( + a b c * + d Then, reading * and e. * ( + a b c * + d e + pushed in after popping equal (or more) priority operators. Next, + and f * ( + a b c * + d e * f 2018/9/21

62 Next is “)” -> pop everything up to “(“.
+ Pop ( + a b c * + d e * f + Next are * and g -> push * into stack. Put g to output. * + a b c * + d e * f + g No more input, we pop everything on stack to output. a b c * + d e * f + g * + 2018/9/21

63 Using stack (4) Change infix to prefix If reading a number from input:
Put that number in our operand stack. If reading an operator: If operator stack is empty, push it in. If the operator is “(“, push it in the operator stack. If the operator has more priority than the operator on top of the operator stack, push it in the operator stack. 2018/9/21

64 If the operator has equal or less priority than the operator on top of the stack:
Pop an operator from the operator stack. Pop operands used by popped operators from the operand stack. Put the operator first, followed by the operands. The latest one is put first. Put the result in the operand stack. If the operator is “)”, or if we cannot read from input any further, follow step 4 until the top of the operand stack becomes “(“. Then pop that “(“ out. 2018/9/21

65 –b+sqrt(b*x – d*a*c)/(e*a)
First, read – ,b. put each one in its stack. Operand stack Operator stack b - read +. Because + has equal priority to – (which is on the operator stack), we need to pop – out and put - with its operand. -b + 2018/9/21

66 Then read sqrt and “(“. Sqrt is just like a method
Then read sqrt and “(“. Sqrt is just like a method. Therefore it has more priority than other operations. We push it in stack. We also put “(“ in stack. -b ( sqrt + Next are b, *, x. we can push all of them. x ( sqrt + b -b * 2018/9/21

67 *bx ( sqrt + -b - a ( sqrt + d - *bx -b *
Next is –. Because – is less important than *, we must pop * out and work with it. *bx ( sqrt + -b - Then read d, *, a. * is more important than -, therefore we can push it in stack. We can also push d and a. a ( sqrt + d - *bx -b * 2018/9/21

68 *da ( sqrt + - *bx -b * (new)
Next we read *. This time another * is on top of the stack. We then must pop stack and push result back. *da ( sqrt + - *bx -b * (new) Then read c and push it (no drawing this time). 2018/9/21

69 ( sqrt + - *bx -b **dac sqrt + -b -*bx**dac / + -b sqrt - *bx**dac
Then read “)”. Pop stack and arrange operators and operands until we find “(“. Then remove “(“. ( sqrt + - *bx -b **dac Then pop – out. sqrt + -b -*bx**dac Then read / -> less priority than sqrt. Therefore we pop sqrt to work. / + -b sqrt - *bx**dac 2018/9/21

70 / + -b sqrt - *bx**dac e ( / + -b sqrt - *bx**dac e ( a *
Then read ( and e. Push them. / + -b sqrt - *bx**dac e ( Then read * and a. Push them. / + -b sqrt - *bx**dac e ( a * 2018/9/21

71 + -b/ sqrt - *bx**dac*ea
Then read “)”. Pop * to work and remove the bracket. / + -b sqrt - *bx**dac *ea Now we finish input reading. We then pop operators to work with operands. First, pop /. + -b / sqrt - *bx**dac*ea Then pop +. The overall result is on the operand stack. + -b/ sqrt - *bx**dac*ea 2018/9/21

72 Using stack (5) Store method call data
Local variables of a method must be stored independently, to prevent name clash with variables in other methods. Must store the return point of a method. We can create a stack to store a method data. activation record or stack frame 2018/9/21

73 method1(){ method2(); } method2(){ method3(); top method3(){ …
main (){ method1(); top method3’s info method2’s info method1’s info 2018/9/21

74 Careful with method There is a form of recursion which wastes stack.
It is called tail recursion. recursive call on the last line of a method. myAlgo(ListNode p){ if (p == null) return; //do something myAlgo(p.next); } For each call, it just call another method without. Each stack will not contain any data- a waste. 2018/9/21

75 fixing tail recursion Let compiler handle it or Write a loop instead.
myAlgo(ListNode p){ while(true){ if (p == null) return; //do something p = p.next; } 2018/9/21

76 Queue It is a list. But we can put things in at the back only (enqueue). And we can remove things from the front only (dequeue). We can implement queue using A modified list array 8 4 3 6 7 back front 2018/9/21

77 Enqueue and dequeue for queue built from array (1)
enqueue(x) size++ back++ theArray[back] = x dequeue() size- - front++ 2018/9/21

78 Enqueue and dequeue for queue built from array (2)
Be careful. Fix it by making the index go round. 8 4 3 6 7 10 back front Cannot Enqueue even though there are spaces at the front. 9 8 4 3 6 7 10 back front 2018/9/21

79 Enqueue and dequeue for queue built from array (3)
when back = front-1, a queue can be either empty or full. Therefore we have size. Fix error when Adding an item to a full queue. Dequeue an empty queue. 2018/9/21

80 public class QueueArray{ private Object [ ] theArray;
private int size; private int front; private int back; static final int DEFAULT_CAPACITY = 10; public QueueArray( ) { this( DEFAULT_CAPACITY ); } public QueueArray( int capacity ) theArray = new Object[ capacity ]; makeEmpty( ); 2018/9/21

81 public boolean isEmpty( ) { return size == 0; }
public boolean isFull( ) return size == theArray.length; public void makeEmpty( ) size = 0; front = 0; back = -1; 2018/9/21

82 Can throw exception. Can throw exception. public Object getFront( ) {
if( isEmpty( ) ) return null; return theArray[ front ]; } /*return an item at the front of the queue, delete that item. Return null if the queue is empty.*/ public Object dequeue( ){ size--; Object frontItem = theArray[ front ]; theArray[ front ] = null; front = increment( front ); return frontItem; Can throw exception. Can throw exception. 2018/9/21

83 * put x at the back of queue.
/** * put x at the back of queue. x object to be put in the queue. Overflow if the queue is full. */ public void enqueue( Object x ) throws Overflow { if( isFull( ) ) throw new Overflow( ); back = increment( back ); theArray[ back ] = x; size++; } 2018/9/21

84 * increment array index, allowing the index to go round *the array.
/** * increment array index, allowing the index to go round *the array. x array index, must be a legal index. x+1, or 0 if x is the at the back of the array. */ private int increment( int x ) { if( ++x == theArray.length ) x = 0; return x; } 2018/9/21

85 double-ended queue insertFirst(Object o): put o at the front.
insertLast(Object o): put o at the back. removeFirst(): remove the front element. removeLast(): remove the last element. first(): return the first element. last(): return the last element. size(): return the queue size. isEmpty(): test if the queue is empty. 2018/9/21

86 stack size() isEmpty() top() last() push(x) insertLast(x) pop()
double-ended queue size() isEmpty() top() last() push(x) insertLast(x) pop() removeLast() 2018/9/21

87 queue size() isEmpty() getFront() first() enqueue(x) insertLast(x)
double-ended queue size() isEmpty() getFront() first() enqueue(x) insertLast(x) dequeue() removeFirst() 2018/9/21

88 Queue usage printer Jobs waiting at a printer can jump queue according to job priority. Supermarket queue simulation. Used queue simulation to decide whether to increase service size. Call center queue. 2018/9/21

89 Supermarket queue We can find an average waiting time. queue paying
2018/9/21

90 If customer come at time -> 30, 40, 60,110, 170
Waiting time for the 2nd customer. Waiting time for the 3rd customer. A11 A2 A3 D2 A4 D3 A5 1st customer paying 2nd customer paying 2018/9/21


ดาวน์โหลด ppt List, Stack, Queue 2018/9/21.

งานนำเสนอที่คล้ายกัน


Ads by Google