400 likes | 414 Views
הרצאה 20: מבני נתונים. מערך דינאמי, קבוצה, מחסנית. מבני נתונים - Data structures. מבנה נתונים הוא דרך לאחסון נתונים במחשב. יעילות של מבנה נתונים נמדדת בכמות הזיכרון הדרוש לתחזוק שלו, וכן בזמן (= מספר פעולות מעבד) הדרוש לביצוע פעולות בסיסיות במבנה, כגון הכנסה והוצאת נתונים, חיפוש, וכו'.
E N D
הרצאה 20: מבני נתונים מערך דינאמי, קבוצה, מחסנית
מבני נתונים - Data structures • מבנה נתונים הוא דרך לאחסון נתונים במחשב. • יעילות של מבנה נתונים נמדדת בכמות הזיכרון הדרוש לתחזוק שלו, וכן בזמן (= מספר פעולות מעבד) הדרוש לביצוע פעולות בסיסיות במבנה, כגון הכנסה והוצאת נתונים, חיפוש, וכו'. • אלגוריתמים רבים עוסקים בשמירה ועיבוד נתונים, ולכן מבני נתונים הוא ענף מחקר חשוב במדעי המחשב.
ארגז הכלים • אחת הבעיות המרכזיות שהמחשב עוזר לנו בהן היא שמירת וניהול כמויות מידע ענקיות • ישנן דרכים שונות לגשת לנתונים, חלקן יעילות יותר מהאחרות • ישנם מבני נתונים שונים שעונים על צרכים שונים • נרצה לצבור מספר מבני נתונים בסיסיים כך שנוכל לבחור מהם לפי תכונותיהם
פעולות מעניינות • הכנסת נתון • שליפת הנתון האחרון שהוכנס • שליפת הנתון הראשון שהוכנס • שליפת הנתון המינימלי • שליפת נתון בעל מפתח מסוים • מעבר על כל הנתונים • עדכון נתון • הקמת המבנה
סוגי יעילות • Best case • Worst case • Average case • Space/time
מבנה נתונים אבסטרקטי • נפגוש בקורס מספר מבני מתונים. נבדיל בין ההגדרה המופשטת של מבני הנתונים להגדרה הקונקרטית שלו. • מבנה נתונים מופשט (ADT - Abstract Data Type) הוא תיאור מופשט של הפעולות של מבנה הנתונים. • מבנה נתונים קונקרטי הוא המימוש בפועל של מבנה הנתונים המופשט.
מבני נתונים: קונקרטי \ אבסטרקטי קונקרטי: לפי מימוש. מופשט: לפי תכונות. מופשטים: קבוצה,מחסנית, תור ... קונקרטי: setAsArray
מבנה נתונים אבסטרקטיAbstract Data Type (ADT) • הפשטה של מבנה נתונים - תאור סוג הנתונים והפעולות שהמבנה יכול לבצע, מבלי לתאר את המימוש. • דוגמה: תור (Queue) • הטיפוס Queue מתאר תור בשיטת FIFO (First In First Out). • הפעולות שניתן לבצע: • enqueue: הכנסת איבר לסוף התור. • dequeue: הוצאת איבר מראש התור. • isEmpty: בדיקה האם התור ריק.
מערך • רוצים לתאר במבנה נתונים מערך בעל קיבולת משתנה. • נשתמש בממשק בכדי לתאר את הפעולות שניתן לבצע על מערך: publicinterface Array{ public Object get(int i); publicvoid set(int i, Object data); publicint size(); }
מימוש מערך בעל קיבולת קבועה publicclass FixedSizeArray implements Array { private Object[] arr; public FixedSizeArray(int size){ arr = new Object[size]; } publicint size() {returnarr.length ;} public Object get(int i) {returnarr[i];} publicvoid set(int i, Object data) { arr[i] = data; } } //class FixedSizeArray
מימוש מערך בעל קיבולת משתנה publicclass DynamicArray implements Array { private Object[] arr; public DynamicArray(){ arr = new Object[0]; } publicint size() {return Integer.MAX_VALUE;} public Object get(int i) { if (i < arr.length) returnarr[i]; elsereturnnull; }
מימוש מערך בעל קיבולת משתנה publicvoid set(int i, Object data) { ensureCapacity(i+1); arr[i] = data; } privatevoid ensureCapacity(int capacity){ if (capacity > arr.length){ Object[] tmpArr = new Object[capacity]; for (int j=0; j<arr.length; j=j+1){ tmpArr[j] = arr[j]; } arr = tmpArr; } } } //class DynamicArray
קבוצה • דוגמה פשוטה נוספת היא מבנה הנתונים קבוצה. publicinterface Set{ publicvoid add(Object data); publicvoid remove(Object data); publicboolean contains(Object data); publicint size(); }
מימוש קבוצה בעזרת מערך publicclass SetAsArray implements Set { private Array arr; private intsize; public SetAsArray(){ arr = new DynamicArray(); size = 0; } publicvoid add(Object data) { if (!contains(data)){ arr.set(size, data); size = size+1; } }
מימוש קבוצה בעזרת מערך publicvoid remove(Object data) { int i = indexOf(data); if (i>=0){ arr.set(i, arr.get(size-1)); arr.set(size-1, null); size = size-1; } } publicboolean contains(Object data) { return indexOf(data) >= 0; } publicint size() {returnsize;}
מימוש קבוצה בעזרת מערך privateint indexOf(Object data) { if (data != null){ for (int i=0; i<size; i=i+1){ if (arr.get(i).equals(data)) return i; } } return -1; } } //class SetAsArray
ADT - מחסנית • דוגמאות: • מגשים בקפיטריה. • מנגנון הקריאה לפונקציות. • שמירת פעולות ב-text editor
ADT - מחסנית publicinterface Stack { publicvoid push(Object o); public Object pop(); publicboolean isEmpty(); }
מחסנית הקריאות f(x) {return g(x) + 1} g(x) {return h(x) + 1} h(x) {return x}
מימוש המחסנית publicclass StackAsArray implements Stack { private Array arr; privateintnumOfElements; public StackAsArray(Array arr){ this.arr = arr; numOfElements = 0; } public StackAsArray(){ this(new DynamicArray()); } publicboolean isEmpty() {returnnumOfElements == 0;}
מימוש המחסנית publicvoid push(Object o) { arr.set(numOfElements, o); numOfElements = numOfElements+1; } public Object pop() { if (isEmpty()) thrownew RuntimeException ("Cannot pop from an empty stack."); numOfElements = numOfElements-1; Object res = arr.get(numOfElements); arr.set(numOfElements, null); return res; } } //class StackAsArray
זריקת חריגה "מדוייקת" יותר public Object pop() { if (isEmpty()) thrownewEmptyStackException(); numOfElements = numOfElements-1; Object res = arr.get(numOfElements); arr.set(numOfElements, null); return res; } כאשר EmptyStackException היא מחלקה המרחיבה RuntimeException. יש לייבא: import java.util.EmptyStackException;
דוגמת שימוש I: מאסטר יודה! publicstatic String yoda(String[] sentence){ String res = ""; Stack st = new stackAsArray(); for(int i=0;i<sentence.length;i++){ st.push(sentence[i]); } while(!st.isEmpty()){ res = res + " " + st.pop(); } res = res + "?"; return res; }
דוגמת שימוש I: מאסטר יודה! publicstaticvoid main(String[] args) { String[] sentence = {"it", "isn't", "funny!"}; System.out.println(yoda(sentence)); } funny! isn't it?
Wrappers • Float, Integer, Double, Byte, Long, Short, Boolean, and Character • Examples Character c = new Character('a'); Integer x = new Integer(5); int y = x.intValue(); Object z = x;
דוגמת שימוש II: סוגריים מאוזנים publicstaticboolean checkBalanced(String input){ Stack st = new stackAsArray(); for (int i=0;i<input.length();i++){ char c = input.charAt(i); if (c =='(' | c == '[' | c =='{'){ st.push(new Character(c)); } elseif (c==')' | c==']' | c=='}') if (st.isEmpty()|| !matches(((Character)st.pop()).charValue(),c)) returnfalse; } return(st.isEmpty ()); }
השיטה matches publicstaticboolean matches(char c1, char c2){ return ((c1=='(' & c2==')') | (c1=='[' & c2==']') | (c1=='{' & c2=='}')); }
דוגמת שימוש II: סוגריים מאוזנים input: a((b{c})[d])e i = 0
דוגמת שימוש II: סוגריים מאוזנים input: a((b{c})[d])e i = 1 (
דוגמת שימוש II: סוגריים מאוזנים input: a((b{c})[d])e i = 2 ((
דוגמת שימוש II: סוגריים מאוזנים input: a((b{c})[d])e i = 3 ((
דוגמת שימוש II: סוגריים מאוזנים input: a((b{c})[d])e i = 4 {((
דוגמת שימוש II: סוגריים מאוזנים input: a((b{c})[d])e i = 5 {((
דוגמת שימוש II: סוגריים מאוזנים input: a((b{c})[d])e i = 6 ((
דוגמת שימוש II: סוגריים מאוזנים input: a((b{c})[d])e i = 7 (
דוגמת שימוש II: סוגריים מאוזנים input: a((b{c})[d])e i = 8 [(
דוגמת שימוש II: סוגריים מאוזנים input: a((b{c})[d])e i = 9 [(
דוגמת שימוש II: סוגריים מאוזנים input: a((b{c})[d])e i = 10 (
דוגמת שימוש II: סוגריים מאוזנים input: a((b{c})[d])e i = 11
דוגמת שימוש II: סוגריים מאוזנים input: a((b{c})[d])e i = 12