32
บทที1 ในบทนี้เราจะมาเรียนวาทําไมถึงตองเรียนเกี่ยวกับโครงสรางขอมูล จริง ผมจะสอนตัว โครงสรางขอมูลไปเลยก็ได แตวาเดี๋ยวพวกเราจะหมดแรงจูงใจที่จะเรียนเพราะไมรูวาจะเอาไป ใชทําอะไร ทําไมตองเรียนโครงสรางขอมูล เอาละ ขอผมเริ่มเลยก็แลวกัน ทําไม เราจึงตองเรียนโครงสรางขอมูล เหตุผลใหญ มีอยูสอง ประการ คือ 1. จะไดรูจักโครงสรางขอมูลที่ใชกันอยูในปจจุบัน โครงสรางขอมูลที่ใชกันอยูในปจจุบัน ลวนมีพื้นฐานมาจากโครงสรางขอมูลที่ผมจะสอนในหนังสือเลมนี้ทั้งสิ้น ดังนั้น เมื่อเรา เรียนรูโครงสรางขอมูลพื้นฐานแลว เราก็สามารถเขาใจ code ตาง ไดงายขึ้นเมื่อเราไป ทํางานกับคนอื่น และยังสามารถนําโครงสรางพื้นฐานเหลานี้มาดัดแปลงใชในโปรแกรม ของเราเองโดยไมตองเสียเวลาสรางโครงสรางขอมูลใหมทั้งหมด 2. จะไดสามารถเลือกใชโครงสรางขอมูลไดอยางถูกตองเหมาะสมกับงาน เหมาะสมอยางไร เหมาะสมตรงไหน เดี๋ยวมีตัวอยางใหดู ที่ผมวาเหมาะสมนั้นหมายความวาเราสามารถหา ขอมูลที่ตองการไดเร็วจากโครงสรางขอมูลที่เราเลือก ในงานหนึ่งเราอาจเลือกใช โครงสรางขอมูลไดจากหลายโครงสราง แตวาอาจมีเพียงโครงสรางขอมูลชนิดเดียวที่ใช เวลาในการดึงขอมูลที่เราตองการนอยกวาโครงสรางขอมูลชนิดอื่น ดังตัวอยางตอไปนีสมมติเราเลือกเก็บจํานวนเต็มหาจํานวน (1 ถึง 5) ลงในโครงสรางขอมูล เราอาจเก็บไดดังนีคือ บททีโครงสรางขอมูลกับโปรแกรม

1 บทที่ โครงสร างข อมูลกับโปรแกรมvishnu/datastructure/aj...2 โครงสร างข อม ลก บโปรแกรม

  • Upload
    others

  • View
    9

  • Download
    0

Embed Size (px)

Citation preview

Page 1: 1 บทที่ โครงสร างข อมูลกับโปรแกรมvishnu/datastructure/aj...2 โครงสร างข อม ลก บโปรแกรม

บทท 1

ในบทนเราจะมาเรยนวาทาไมถงตองเรยนเกยวกบโครงสรางขอมล จรง ๆ ผมจะสอนตวโครงสรางขอมลไปเลยกได แตวาเดยวพวกเราจะหมดแรงจงใจทจะเรยนเพราะไมรวาจะเอาไปใชทาอะไร

ทาไมตองเรยนโครงสรางขอมล เอาละ ขอผมเรมเลยกแลวกน ทาไม เราจงตองเรยนโครงสรางขอมล เหตผลใหญ ๆ มอยสองประการ คอ

1. จะไดรจกโครงสรางขอมลทใชกนอยในปจจบน โครงสรางขอมลทใชกนอยในปจจบนลวนมพนฐานมาจากโครงสรางขอมลทผมจะสอนในหนงสอเลมนทงสน ดงนน เมอเราเรยนรโครงสรางขอมลพนฐานแลว เรากสามารถเขาใจ code ตาง ๆ ไดงายขนเมอเราไปทางานกบคนอน และยงสามารถนาโครงสรางพนฐานเหลานมาดดแปลงใชในโปรแกรมของเราเองโดยไมตองเสยเวลาสรางโครงสรางขอมลใหมทงหมด

2. จะไดสามารถเลอกใชโครงสรางขอมลไดอยางถกตองเหมาะสมกบงาน เหมาะสมอยางไร เหมาะสมตรงไหน เดยวมตวอยางใหด ทผมวาเหมาะสมนนหมายความวาเราสามารถหาขอมลทตองการไดเรวจากโครงสรางขอมลทเราเลอก ในงานหนงเราอาจเลอกใชโครงสรางขอมลไดจากหลายโครงสราง แตวาอาจมเพยงโครงสรางขอมลชนดเดยวทใชเวลาในการดงขอมลทเราตองการนอยกวาโครงสรางขอมลชนดอน ดงตวอยางตอไปน

สมมตเราเลอกเกบจานวนเตมหาจานวน (1 ถง 5) ลงในโครงสรางขอมล เราอาจเกบไดดงน คอ

บทท โครงสรางขอมลกบโปรแกรม

Page 2: 1 บทที่ โครงสร างข อมูลกับโปรแกรมvishnu/datastructure/aj...2 โครงสร างข อม ลก บโปรแกรม

2 โครงสรางขอมลกบโปรแกรม วศวกรรมคอมพวเตอร จฬาฯ

• ทางเลอกท 1 คอ เรยงเกบใส Sorted Linked List โดยมจดเรมตนการคนขอมลท P (ขอใหดรป 1.1ไปกอนยงไมตองคดมาก)

(นคอสญลกษณบอกวาไมมการเชอมตอไปยงสมาชกตวอนแลว)

รป 1.1: Sorted Linked list ซงเกบจานวนเรยงลาดบ 5 จานวน

• ทางเลอกท 2 (รป 1.2) คอ เราอาจเกบใสโครงสรางขอมลแบบตนไม (tree) ตอไปผมจะขอเรยกวา tree ไปตลอดเพราะพอพดถง “ตนไม” ทไร ผมจะนกถงตนไมจรง ๆ ทกท ให tree นมจดเรมการคนหาท P เหมอนกน ในภาพเปน Binary Search Tree (คอ เรยงขอมลจากนอยไปมาก ใหพวกเราสงเกตลกษณะกพอ เดยวคอยเรยนจรง ๆ อกท)

รป 1.2: Binary Search Tree ซงเกบจานวนเรยงลาดบ 5 จานวน

• ทางเลอกท 3 (รป 1.3) คอ เราอาจเกบใส Heap ซงเปน tree แบบหนง (ในภาพคอ Maxheap ซงเอาจานวนทมากทสกไวบนสดเสมอ)

จรง ๆ ยงใชโครงสรางขอมลไดอกหลายแบบเพอเกบเลข 1 ถง 5 แตผมจะเอาแค 3 แบบทกลาวมาเปรยบเทยบกนเทานน ถางานของเราคอ การดงเอาขอมลตวทมากทสดมาใชเรอย ๆ เราควรจะเลอกโครงสรางขอมลตวไหน ทกคนคงจะเหนชดแลววา ถาใช Sorted Linked List เราตอง

P

1

11

11 2 3 5 4

2

1 4

3 5

P

Page 3: 1 บทที่ โครงสร างข อมูลกับโปรแกรมvishnu/datastructure/aj...2 โครงสร างข อม ลก บโปรแกรม

Data Structure ทาไมตองเรยนโครงสรางขอมล 3

ทาการตรวจสอบขอมลเปนจานวน 5 ครง จากซายไปขวา ขอมลตวทคามากทสดจะอยทตาแหนงสดทาย (รป 1.4)

รป 1.3: Ma xheap ซงเกบจานวนเรยงลาดบ 5 จานวน

รป 1.4: ขนตอนการหาจานวนทคามากทสดจาก Sorted Linked List

ถาเปน Binary Search Tree จะตองทาการตรวจสอบขอมล 3 ครง ขอมลตวทคามากทสดจะอยทตาแหนงขวาสดของ tree (รป 1.5) แตถาเปน Maxheap เราเอา 5 มาจากจดเรมตน P ไดเลย ไมตองเสยเวลาหา

จะเหนไดวาการเลอกโครงสรางขอมลมผลตอความเรวของโปรแกรมจรง ๆ เทานทกคนกรวาทาไมถงตองเรยนแลวนะ แตการเปรยบเทยบความเรวในการหาขอมลนน ทางทฤษฎมวธวเคราะหอยหลายแบบ ไมใชแคทางาย ๆ อยางดรปแลวตอบ

ครงท 2

P 5

4 3

2 1

ครงท 3 ครงท 4

11 2 3 5 4

จดเรมตน

ครงท 1 (ดวาตรงนกดหรอยง)

ครงท 5 ถงตรงน หางกด จงรวาเลขทอยในบลอคทผานมา เปนเลขตวสดทาย

Page 4: 1 บทที่ โครงสร างข อมูลกับโปรแกรมvishnu/datastructure/aj...2 โครงสร างข อม ลก บโปรแกรม

4 โครงสรางขอมลกบโปรแกรม วศวกรรมคอมพวเตอร จฬาฯ

รป 1.5: ขนตอนการหาจานวนทคามากทสดจาก Binary Search Tree

การคานวณความเรวของโปรแกรม ในการหาความเรวในการทางานของโปรแกรม เรามกจะไมไดเหนรป แตเหนเปน code เลยมากกวา เราจะสามารถมองความเรวของโปรแกรมจากการด code เลยไดอยางไร

กอนทจะทาได เราตองมาเรยนรเรองทฤษฎเสยกอน เราจะเรมจากนยามแรกทเปนพนฐานในการคดความเรวของ code

นยามท 1-1

Big O

))(()( NfONT = ถา )()( NcfNT ≤ โดยม c กบ 0N เปนคาคงทและ 0NN ≥

นยามนเปนการบอกวา )(NT มคาไมเกนเทาใด เมอ N มคามาก หรออกนยหนงคอการบอกวา )(NT มการเตบโตอยางไร

ตวอยางท 1-1

เมอ NNT 339)( = และ

2

1 4

3 5

P ครงท 1 (ดวากดหรอยง)

ครงท 2

ครงท 3

Page 5: 1 บทที่ โครงสร างข อมูลกับโปรแกรมvishnu/datastructure/aj...2 โครงสร างข อม ลก บโปรแกรม

Data Structure การคานวณความเรวของโปรแกรม 5

2)( NNf =

ถาให 3390 =N และ 1=c

กอนอนเราสามารถจะเหนไดทนทวา 200 1339 NN ∗≤

(โดย 0339N คอ )( 0NT และ 201 N∗ คอ )( 0Nfc∗ )

เปนไปตามนยามของ Big O เพราะฉะนน )())(()( 2NONfONT ==

แตวานกไมใชเพยงคาตอบเดยว

ด NNT 339)( = ใหดจะเหนวา NNT 340)( ≤ ดวยนนา (โดยตอนนให NNf =)( )

∴ )(NT กเทากบ )(NO ดวย

อยางนกมคา Big O เกนหนงคาตอบส แลวเราควรตอบตวไหนด

ใหตอบเปนคาทนอยทสด เพราะคาทนอยทสด คอคาทเราเอามาใชจรงๆในการคดความเรวของ

โปรแกรม (อยาพงงง รอดตวอยางตอไป) เพราะฉะนนคาตอบของขอนคอ )(NO

แลว )(NO มนเกยวอะไรกบการหาความเรวในการ execute ของ code ขอใหเราดตวอยางตอไป

ตวอยางท 1-2

จงหาเวลาในการ run code ตอไปน

sigmaOfSquare(int n) // calculate ∑=

N

ii

1

2

1: int tempSum; 2: tempSum = 0; 3: for (int i=1;i<=n;i++) 4: tempSum += i*i; 5: return tempSum;

Page 6: 1 บทที่ โครงสร างข อมูลกับโปรแกรมvishnu/datastructure/aj...2 โครงสร างข อม ลก บโปรแกรม

6 โครงสรางขอมลกบโปรแกรม วศวกรรมคอมพวเตอร จฬาฯ

จากตวอยางน กอนอนเรามาลองคดเวลาในการ run เปน unit ด ดทละบรรทดไปเลย บรรทดท 1: int tempSum;

นคอการ declare variable ผมสมมตใหการทาอยางนใชเวลา 1 unit (เราตองสมมตเวลา เพราะนเปนการดจาก code เราไมได run โปรแกรมแลวจบเวลาจรง ๆ แตการสมมตแบบนคอแนวทางในการวเคราะหโปรแกรมดวยตวเราเอง) บรรทดท 2 และ 5: tempSum = 0; return tempSum; ในทง 2 บรรทดน แตละบรรทดมการกระทาอยางเดยว ใหถอวาใชเวลาบรรทดละ 1 unit บรรทดท 3: for (int i=1;i<=n;i++) คราวนจะตางกบบรรทดกอน ๆ เพราะเปน loop เรามาดวา for loop นทาอะไรบาง

1. set i ใหมคาเรมตนเปน 1 - เปนการ initialize คา i ทาแคครงเดยวเทานน เพราะฉะนน เราใหใชเวลา 1 unit

2. ทดสอบวา i <= n หรอไม - นจะเปนการทดสอบกอนเขา loop นบตงแตแรกเรมคอ i มคาเปน 1 สวนการ ทดสอบครงสดทาย คอ ตอนทจะเขา loop ไมไดเปนครงแรก นนคอ เมอ i มคาเปน n+1 เพราะฉะนน การ ทดสอบทงหมดตองทา n+1 ครง เราใหเปนหนวยเวลา n+1 unit

3. เพมคา i เปนคาทมากกวาเดมอย 1- นจะเปนการเพมคา i ทกครงกอนขน loop ใหม ครงแรกจะเกดตอนท i เทากบ 1 สวนครงสดทายจะเกดขนตอนท i เทากบ n และจะเปลยนคา i เปน n+1 (พอเปน n+1 กจะเขา loop ไมไดอก) เพราะฉะนน การเพมคา i นจะม n ครง เราใหเปนหนวยเวลาเทากบ n unit

จากทกๆขนตอนในบรรทดน รวมแลวใชเวลา 1 + n+1 + n = 2n + 2

บรรทดท 4: tempSum += i*i; ตว tempSum += i*i; นอยใน loop จากการดบรรทดท 3 เราทราบแลววาจะมการเพมคา

ทงหมด n ครง เพราะฉะนน statement น กตองมการ execute n ครง เชนกน แต statement นทาอะไรบางในการผาน loop แตละครง

1. มการคณ 1 ครง - ใหเปนเวลา 1 unit

Page 7: 1 บทที่ โครงสร างข อมูลกับโปรแกรมvishnu/datastructure/aj...2 โครงสร างข อม ลก บโปรแกรม

Data Structure การคานวณความเรวของโปรแกรม 7

2. มการบวก 1 ครง - ใหเปนเวลา 1 unit 3. มการทา assignment 1 ครง -ใหเปนเวลา 1 unit

ในเมอผาน loop ทงหมด n ครง เวลาทงหมดของ statement ในบรรทดนจงเปน (1 + 1 + 1)*n = 3n unit เมอรวมเวลาทก unit ของทงโปรแกรม เราจะไดเวลารวมเทากบ 1 + 1 + 1 + (2n + 2) + 3n = 5n + 5 unit

โปรแกรมแคนยงเสยเวลาในการกะ running time ขนาดน ดงนน โปรแกรมใหญ ๆ ยงไมตองพดถง ดงนน ถาจะคานวณ running time ของโปรแกรมใหรวดเรวเราจาเปนตองใชการประมาณอยางคราว ๆ กวาน นนคอตองใช Big O นนเอง

สาหรบโปรแกรมน สวนทจะโดน execute มากทสดกคอ สวนท loop นนเอง เวลาในการ run สวนอนจะนอยมากเมอเทยบกบสวนทเปน loop ซงทาซาไปประมาณ n ครง ดงนนเราสามารถประมาณ running time ของ code นในเทอมของ Big O ไดคอ

Running time = )(nO เราสามารถตรวจสอบความถกตองของคาประมาณนได จากการทเรารวา running time จรง ๆ เทากบ 5n + 5 เราจะไดวา

)(55 nOn =+ ซงจากนยามของ Big Oเราจะได

ncn ∗≤+ 55 , โดย 6=c

จากตวอยาง 1-2 จะเหนไดวา เราสามารถหา Big O ไดจากการด for loop เทานนเอง ผมจะสรปหลกของการด loop ใหดงตอไปน For Loop: คา Big O คอ จานวนครงท loop ทาซาโดยใชตวแปรเปนหลก ในตวอยาง 1-2 นกคอ n Nested Loop: เอาคา Big O ของ loop แตละชนมาคณกน อยางเชนถามโปรแกรม

Page 8: 1 บทที่ โครงสร างข อมูลกับโปรแกรมvishnu/datastructure/aj...2 โครงสร างข อม ลก บโปรแกรม

8 โครงสรางขอมลกบโปรแกรม วศวกรรมคอมพวเตอร จฬาฯ

1: for (i = 1; i <= n; i++) 2: for (j = 1; j <= n; j++) 3: statements;

คา Big O จะเปน )( nnO ∗ ทางทฤษฏ เราสามารถเขยนนยามออกมาไดดงตอไปน

นยามท 1-2 ถา ))(()(1 NfONT = และ ))(()(2 NgONT =

∴ ))()(()()( 21 NgNfONTNT ∗=∗ สาหรบ code ในตวอยางนนน NNgNf == )()( Statement ทเรยงตอกนแตละบรรทด: เอาคา Big O ของแตละ statement มาเทยบหาตวทมากทสด ตวอยางเชน ถามโปรแกรม 1: for (i = 0; i <= n; i++) 2: statement1; 3: for (j = 0; j <= n; j++) 4: for (k = 0; k <= n; k++) 5: statement2;

code นเกดจากการเรยง for loop ท 1 และ for loop ท 2 Big O รวม คอ )( 2nO ซงเปนของ loop 2 ทไมคดเวลาจาก loop แรก กเพราะวาไมมนยสาคญเลยเมอเทยบกบ loop 2 ทางทฤษฏ เราสามารถเขยนนยามของการหา running time จาก Statement ทเรยงตอกนแตละบรรทดออกมาไดดงตอไปน

นยามท 1-3 ถา ))(()(1 NfONT = และ ))(()(2 NgONT =

∴ )))((),((max()()( 21 NgONfONTNT =+

ประโยคแบบมเงอนไข: ถาม Code

Page 9: 1 บทที่ โครงสร างข อมูลกับโปรแกรมvishnu/datastructure/aj...2 โครงสร างข อม ลก บโปรแกรม

Data Structure การคานวณความเรวของโปรแกรม 9

1: if (condition) 2: Statement1 3: Else 4: Statement2

เวลาในการ run ของโปรแกรมนคอ เวลาในการ run ทมากทสดระหวางเวลาในการ run ของ statement 1 และ statement 2 เราไมรวา statement ไหนจะถกเลอกกนแน ดงนนตองเลอกตวทแยกวาไวกอน ตอนน เรารวธหา Big O ของ code แลว กอนทจะมาเรยนนยามตอไป เรามาลองดตวอยางการหาเวลาในการ run ของ code ทเปน recursion (recursion คอ โปรแกรมทเรยกตวเองเรอย ๆ แต input ทใชตองขนาดลดลงเรอย ๆ จนถงขนาดพนฐานทจะไมเรยกตวเองอก ไมงนจะไมมวน run จนจบ)

ตวอยางท 1-3 จงหาเวลาในการ run ของ code ตอไปน ทงแบบหนวย unit และ Big O 1: My method (int n) 2: if (n == 1) 3: return 1; 4: else 5: return 2*mymethod(n – 1) + 1; 6: 7:

กอนอน เรามาด Big O กอน การ run ของโปรแกรมน จานวนครงทคณและบวกจะขนอยกบคาของ n (คอ จานวนครงของการเรยกใช method นนเอง เพราะฉะนน Big O กคอ )(nO ) มขอสงเกตวาแมวาเราจะเปลยน code ใหใช iteration แทน recursion แลวกตาม (code ขางลางนคอแบบทใช iteration นนคอใช loopแทนการเรยกใช method) โปรแกรมนกจะยงมคา Big O เปน )(nO เหมอนเดม

Page 10: 1 บทที่ โครงสร างข อมูลกับโปรแกรมvishnu/datastructure/aj...2 โครงสร างข อม ลก บโปรแกรม

10 โครงสรางขอมลกบโปรแกรม วศวกรรมคอมพวเตอร จฬาฯ

1: mymethod (int n) 2: int result = 1; 3: int i = n; 4: while (i > 1) 5: result = 2 * result + 1; 6: i = i-1; 7: 8: return result; 9:

แตการใช recursion จะสนเปลอง memory เพราะการเรยกใช method ในแตละครงตองเสยเนอทใน memory เพอสราง activation record ใหม (รป 1.6) คราวน มาลองคดเปน unit time ดเลนๆ (ดจาก code ตอนทา recursion นะ) ถาเราให )(nA คอ จานวน operation ทเกดขน เมอม input คอ n (เราจะใหจานวน operation ทาหนาทเปน unit time ของเรานนเอง)

รป 1.6: สงทเกดขนท memory เมอมการเรยกใช method จากตวอยาง 1.4

2)1( =∴A (คา 2 นมาจาก 2 operations ซง operation แรกคอการทดสอบคาวา 1=n หรอไม สวน operation ทสองคอการ return คา 1 แลว A(2) จะเปนเทาไรละ เราสามารถนบจานวน Operation ไดดงน

=)2(A ทดสอบ if (n = = 1) มาแลว (1 operation) + การคณ (1 operation) + การบวก (1 operation) + )1(A + การ return (1 operation)

4)1()2( +=∴ AA

Mymethod(n) Mymethod(n) Mymethod(n-1)

Page 11: 1 บทที่ โครงสร างข อมูลกับโปรแกรมvishnu/datastructure/aj...2 โครงสร างข อม ลก บโปรแกรม

Data Structure การคานวณความเรวของโปรแกรม 11

)3(A กจะมรปแบบเชนเดยวกนคอ =)3(A ทดสอบ if(n = = 1) มาแลว + การคณ + การบวก + )2(A + การ return

4)2()3( +=∴ AA จะสงเกตไดวา 4)1()( +−= NANA โดยม 2)1( =A นคอ สมการของความสมพนธเวยนเกด ซงเราสามารถทาเปนรปแบบปดไดเพอหาคา unit time ทแทจรง จากการสงเกต เราจะได

4)4()5( += AA 444)4)1(( ++++= A , ใชการคล

)1()4(4)5( AA += 242)1(4)( −=+−=∴ nnnA

เพอความแนใจในรปแบบปดทเราหาได เราสามารถพสจนใหเหนวา 24)( −= nnA มคาเทากบ 2)1(,4)1()( =+−= AnAnA โดยวธการอปนยทางคณตศาสตร Base case: (n=1) เราแทนคาจากสมการรปแบบปดของเรา จะไดวา 22)1(4)1( =−=A ซงผลลพธตรงกบนยามแรก Inductive hypothesis: ตงสมมตฐานวา 24 −n มคาเทากบ 4)1( +−nA ตองพสจน: ใหไดวา 4)(2)1(4 +=−+ nAn จงจะถอวา 24 −n เปนรปแบบปดทถกตอง สมการ 4)(2)1(4 +=−+ nAn น เราสามารถจดใหเปน 4]4)1([424 ++−=+− nAn ไดดวยการกระจาย และนยามของความสมพนธเวยนเกด

Page 12: 1 บทที่ โครงสร างข อมูลกับโปรแกรมvishnu/datastructure/aj...2 โครงสร างข อม ลก บโปรแกรม

12 โครงสรางขอมลกบโปรแกรม วศวกรรมคอมพวเตอร จฬาฯ

เรารจากขอสมมตฐานวา 24 −n มคาเทากบ 4)1( +−nA เพราะฉะนนจากสมการขางบนน เราสามารถสรปไดอยางชดเจนวา

4)(2)1(4 +=−+ nAn แสดงวา 24)( −= nnA คอจานวน operation (ในแบบ unit time) ทถกตอง

ขอสงเกต: คา 24 −n ทไดนกสอดคลองกบคา )(nO ทเราไดตอนแรก เพราะฉะนนจะเหนไดวาการหา running time ดวย Big O มความสะดวกรวดเรวกวาการหาแบบ unit time อยมาก ตอนน ทกคนคงจะมความเขาใจเกยวกบ Big O แลว การเลอกใชโครงสรางขอมลสาหรบงานหนง ๆ จงจาเปนตองคานงถงคา Big O ในการ run ดวย ตอไปนจะเปนตวอยางของปญหาปญหาหนงซงเราสามารถใชการเปรยบเทยบ Big O ของ code ในการเลอกโปรแกรมทเหมาะสมทสดสาหรบการแกปญหาน

ตวอยางท 1-4 การแกปญหา Maximum Subsequence Sum มหลายวธ เราจะนาเสนอวธตาง ๆ และวเคราะหวาวธไหนเหมาะสมทสด โดยเปรยบเทยบ Big O ของแตละวธ (ตวอยางนเปนการเปรยบเทยบ Big O ของ algorithms ไมไดเกยวกบโครงสรางขอมลโดยตรง แตอยางทแสดงในตวอยาง 1.1 โครงสรางขอมลแตละชนดให Big O ตางกน) กอนอน เราตองรวา ปญหา Maximum Subsequence Sum นนคออะไร ถามจานวนเตม nAAAA ,...,, 321

Maximum Subsequence Sum คอ คา ∑=

j

ikkA ทมคามากทสด นนกคอ ผลบวกของจานวน

ตดกน (เรมหรอจบตรงไหนกได ขอใหเปนจานวนทตดกนกพอ) ทมคามากทสด อยางเชน ถาม -2, 11, -6, 16, -5, 7 ผลรวมของ 11, -6, 16 คอ 21 ผลรวมนกดมตวเลขมาก (ตามสญชาตญาณ) แตทมากทสดจรงๆ กคอ จาก 11, -6, 16, -5, 7 ซงรวมแลวได 23 คานแหละคอ Maximum Subsequence Sum

Page 13: 1 บทที่ โครงสร างข อมูลกับโปรแกรมvishnu/datastructure/aj...2 โครงสร างข อม ลก บโปรแกรม

Data Structure การคานวณความเรวของโปรแกรม 13

ตอนน เมอเรารนยามของปญหานแลว มาดวธแกปญหานในแบบตาง ๆ วธท 1 1: int maxSubSum01 ( int [] a) 2: int maxSum = 0; 3: for (int i = 0; i < a.length; i++) 4: for (int j = i; j < a.length; j++) 5: int theSum = 0; 6: for (int k = i; k <= j; k++) 7: theSum += a[k]; 8: 9: if (theSum > maxSum) 10: maxSum = theSum; 11: 12: 13: return maxSum; 14: 15:

คา Big O เมอดจากตวโปรแกรมแลว จะมคาเทากบ )( 3NO เพราะคา max ของ loop 3 ชน คอ N3 แตทาไมถงนานขนาดน เรามาดขนตอนของวธนกน วธนคอการด array แลวเกบผลบวกของตาแหนงตดกนบน array โดย i เปน index ของจานวนแรก และ j เปน index ของจานวนสดทาย คา i กบ j จะเปลยนไปเรอยๆจนครอบคลมทกความเปนไปได สมมตเราม array ของจานวนเตม 4 หลกคอ -2, 11, -6 และ 4 เมอ i = 0, j = 0, k = 0:

theSum = -2 maxSum ยงคงเปน 0 ในการ loop หา theSum ครงตอไป j ไดกลายเปน 1 เพราะฉะนนคาท k เปนไดจะม 2 คา คอ 0 กบ 1 เมอ i = 0, j = 1, k = 0: คาตางๆยงคงเหมอนเดม

-2 11 -6 4

Page 14: 1 บทที่ โครงสร างข อมูลกับโปรแกรมvishnu/datastructure/aj...2 โครงสร างข อม ลก บโปรแกรม

14 โครงสรางขอมลกบโปรแกรม วศวกรรมคอมพวเตอร จฬาฯ

เมอ i = 0, j = 1, k = 1:

theSum = -2 + 11 = 9 สวน maxSum = 9 ในการ loop หา theSum ครงตอไป j จะกลายเปน 2 เพราะฉะนน คา k ทเปนไดกจะมไดตงแต 0 ถง 2 เมอ i = 0, j = 2, k = 0:

theSum = -2 เมอ i = 0, j = 2, k = 1: theSum = -2+11 =9 เมอ i = 0, j = 2, k = 2: theSum = 9 – 6 = 3 maxSum ยงคงเปน 9 ในการ loop หา theSum ครงตอไป j จะกลายเปน 3 และตอไปก 4 (ขอขาม เพราะวธการเหมอนเดม) เมอ i เปลยนเปน 1 การ run กจะเหมอนเมอ i = 0 เพยงแตเรมจาก array element index ท 1 แทนทจะเปน 0 เมอ i = 1, j = 1, k = 1: theSum = 11 maxSum เปลยนเปน 11 ในการ loop หา theSum ครงตอไป j ไดกลายเปน 2 คาท k เปนไดจะม 2 คา คอ 1 กบ 2

-2 11 -6 4

-2 11 -6 4

-2 11 -6 4

Page 15: 1 บทที่ โครงสร างข อมูลกับโปรแกรมvishnu/datastructure/aj...2 โครงสร างข อม ลก บโปรแกรม

Data Structure การคานวณความเรวของโปรแกรม 15

เมอ i = 1, j = 2, k = 1:

theSum = 11 เมอ i = 1, j = 2, k = 2: theSum = 11 – 6 = 5 maxSum ยงคงเปน 11 ในการ loop หา theSum ครงตอไป j จะกลายเปน 3 คา k ทเปนไดกจะมไดตงแต 1 ถง 3 เมอ i = 1, j = 3, k = 1:

theSum = 11

เมอ i = 1, j = 3, k = 2: theSum = 11 – 6 = 5 เมอ i = 1, j = 3, k = 3: theSum = 5 + 4 = 9 maxSum ยงคงเปน 11 ไมทาใหดตอแลวนะ จากตวอยางจะเหนไดวาวธนเปนการลองทกกรณ และวธนกมจดออนทเหนไดชดเจนมาก นนคอในการ loop หา theSum แตละครง โปรแกรมตองเรมเกบคาใหมตงแตตน แทนทจะบวกตอจากคาทหาไดในการ loop ครงกอน อยางเชน ถาบวกจากตาแหนง 0 ถง2 ไปแลว ตอนทบวกจากตาแหนงท 0 ถง 3 กลบตองเรมบวกใหมหมด แทนทจะใชผลจากการบวกจากตาแหนง 0 ถง2 ได วธท 2 เรามาดตวโปรแกรมกนกอน ในรปขางลาง ถาดจาก Big O เราจะเหนวาม for loop อยสองลป ซงแตละลปมจานวนการ run ขนตรงกบขนาดของขอมลเขา ดงนน โปรแกรมนจงมคา Big O เปน O(N2) ซงนอยกวาวธแรก ดงนน โปรแกรมนเรวกวาแนนอน ถาเลอกระหวางวธทหนงกบวธน เรากควรจะเลอกวธน

-2 11 -6 4

-2 11 -6 4

Page 16: 1 บทที่ โครงสร างข อมูลกับโปรแกรมvishnu/datastructure/aj...2 โครงสร างข อม ลก บโปรแกรม

16 โครงสรางขอมลกบโปรแกรม วศวกรรมคอมพวเตอร จฬาฯ

-2 11 -6 4

1: int maxSubSum02 (int [] a) 2: int maxSum = 0; 3: for (int i = 0; i < a.length; i++) 4: int theSum = 0; 5: for (int j = i; j < a.length; j++) 6: theSum += a[j]; 7: if (theSum > maxSum) 8: maxSum = theSum; 9: 10: 11: 12: return maxSum; 13:

วธนเรวกวาวธแรกยงไง จากตวโปรแกรม เราจะเหนไดวา โปรแกรมนทาการเกบคา theSum ไปเรอย ๆ ตามขนาดของ array แตจะตางจากวธแรก คอ จะมการเกบสะสมคา theSum ไวใชในการคานวณครงตอไป โดยม i เปนตวกาหนดตาแหนงทจะเรมบวก ตอจากนน กจะเรมบวกจากตาแหนงท i นนๆ โดยใช j เปนตวทาการลป ดงนนลปในสดของโปรแกรมนจะทาหนาทเหมอนลปสองลปดานในของวธแรก และการลปน กจะเปนการ update คา maxSum ไปในตวเลย นคอเหตผลททาใหประหยดเวลาไดมาก รป 1.7 เปนการแสดงการทางานของโปรแกรมนเมอ i มคาเปน 0 จะเหนไดวามการสะสมคา theSum ไวใชใน iteration ตอไป เมอ i=0, j=0: theSum = -2 maxSum = 0 เมอ i=0, j=1: theSum = -2 + 11 = 9 maxSum กลายเปน 9 เมอ i=0, j=2: theSum = 9 + (-6) = 3 maxSum ยงคงเปน 9 เมอ i=0, j=3: theSum = 3 + 4 maxSum ยงคงเปน 9 เมอ i=0, j=4: คา j เกนกวาลมต ทาอะไรไมได

รป 1.7 ขนตอนการหา max sub sum วธทสอง

Page 17: 1 บทที่ โครงสร างข อมูลกับโปรแกรมvishnu/datastructure/aj...2 โครงสร างข อม ลก บโปรแกรม

Data Structure การคานวณความเรวของโปรแกรม 17

เมอ i มคาเปน 1 กระบวนการคดยงคงเหมอนเดม เพราะฉะนน ถาขนาดของอารเรยคอ N เราจะมจดเรมตนนบอย N จด โดยในแตละจด มการบวกสะสมคาอยางมากทสด N ครง ซงนกคอทมาของ O(N2) นนเอง วธท 3 ตอไปมาดวธทสามกน วธทสามนใชความรจากความสมพนธเวยนเกด [หนงสออ. สมชาย] มาเปนหลกในการเขยนโปรแกรม หลกการทใช คอ การแบงแยกและเอาชนะ (divide and conquer) นนคอ แบงปญหาออกเปนสวนเลก ๆ สองสวนเทา ๆ กน แลวกแบงไปเรอย ๆ จนถงปญหาพนฐาน (ซงแกไดงาย) หลงจากนนกรวมคาตอบสวนตาง ๆ เขาดวยกน สาหรบในการแกปญหา maximum subsequence sum นน ตว sequence ทเปนคาตอบอาจจะอยใน

- ครงซายของการแบงปญหา หรอ - ครงขวาของการแบงปญหา หรอ - อยทงสองขาง (ตองมตวสดทายจากครงซายและตวแรกจากครงขวา)

อยางในตวอยางขางลางน ซงเปน array ทมสมาชก 8 ตว 1 -2 7 -6 2 8 -5 4

• ครงซาย คา maxSubSum = 7 • ครงขวา คา maxSubSum = 10 • maxSubSum ของครงซายทมตวสดทาย (-6) คอ 1 • maxSubSum ของครงขวาทมตวแรก (2) คอ 10

เพราะฉะนน maxSubSum ของชวงทอยทงครงซายและขวา = 10 + 1 = 11 เพราะฉะนนคา maxSubSum ของตวอยางนคอ max ของ 7, 10 และ 11 นนกคอ 11 นนเอง ดงนนเราสามารถใชการแบงขางซายขวาชวยในการหาคาตอบได ตวโปรแกรมเปนดงรป 1.8 ในการหาคา Big O ของโปรแกรมในรป 1.8 น เราสามารถหาไดจากการประมาณ unit running time จากตวโปรแกรมเอง ถาใหเวลาในการ run maxSumDivideConquer สาหรบ array ขนาด n

Page 18: 1 บทที่ โครงสร างข อมูลกับโปรแกรมvishnu/datastructure/aj...2 โครงสร างข อม ลก บโปรแกรม

18 โครงสรางขอมลกบโปรแกรม วศวกรรมคอมพวเตอร จฬาฯ

เปน T(n) จะเหนไดวาการเรยก maxSumDivideConquer เพอหาคา maxsumleft และ maxsumright จะมเวลาในการ run = T(n/2) สวนลปทหา maxlefthalfSum กบ maxrighthalfSum แตละลปจะ run ไปได n/2 ครง เพราะตรวจดแคครงหนงของ input สวนอน ๆ ของโปรแกรมนจะ run ดวยเวลาคงท ฉะนนสามารถตดพวกนนทงไปได จะไดวา T(n) = 2T(n/2) + 2O(n/2) T(n) = 2T(n/2) + O(n) เพราะวา O(n) <= c*n ตามนยาม เราสามารถแทน O(n) ดวย c*n ไดในการประมาณคาเวลา เพราะฉะนน คาประมาณคอ T(n) = 2T(n/2) + cn

cn

nT

nnT

cnnTnT

+=

+=

2

)2

()(

)2

(2)(

เพราะฉะนน

(1)

Page 19: 1 บทที่ โครงสร างข อมูลกับโปรแกรมvishnu/datastructure/aj...2 โครงสร างข อม ลก บโปรแกรม

Data Structure การคานวณความเรวของโปรแกรม 19

cTT

cn

nT

n

nT

cn

nT

n

nT

+=

+=

+=

1)1(

2)2(

.................8

)8

(

4

)4

(

4

)4

(

2

)2

(

เมอเอา (1) + (2) + (3) +…..+ (x) จะได

T(n)/n = T(1)/1 + c * log (n) T(n) = n* T(1) + c*nlog(n)

เพราะวา T(1) เปนคาคงท ดงนนเราจงสามารถตอบไดทนทวา T(n) ม Big O เปน O(n log(n) ซงคา Big O นนอยกวาคา Big O ของวธท 2 วธนจงนาจะดกวา (แตอยาลมวาการใช recursion ตองเปลองหนวยความจาในการสราง stack) วธท 4 คอการเอาวธท 2 มาปรบปรงใหเรวขน โดยอาศยขอสงเกตทวา • ตวแรกของ maximum subsequence sum จะเปนลบไมได อยางเชน

3 -5 1 4 7 -4 คา -5 จะเปนตวแรกของ sequence ของคาตอบไมได แคเราใหตวแรกเปนสมาชกของ array ตวตอไปแทน (ในทนคอเลข 1) เรากจะไดคารวมมากขนแลว นนคอ ถามจานวนบวกอยบาง ยงไงถาเราเรมคด sequence จากจานวนบวก เรากจะได คามากกวาเมอเรมดวยจานวนลบแนๆ (อยาลมวาเราใชสมมตฐานวา maximum subsequence sum มคานอยทสดคอ 0 ดงนนแมทกจานวนจะเปนลบ เรากยงสามารถตอบไดวาคา maximum subsequence sum นนเปน 0)

(2)

(3)

(x)

Page 20: 1 บทที่ โครงสร างข อมูลกับโปรแกรมvishnu/datastructure/aj...2 โครงสร างข อม ลก บโปรแกรม

20 โครงสรางขอมลกบโปรแกรม วศวกรรมคอมพวเตอร จฬาฯ

1: int maxSumDivideConquer (int [] array, int leftindex, int rightindex

2: // ตองถอวาขนาดของอารเรยหารสองลงตวพอดจะไดแบงไดเทากน ไมเชนนนยาก 3: if (leftindex == rightindex) // Base Case 4: if (array[leftindex] > 0 ) 5: return array[leftindex]; 6: else

7: return 0; // maxSubSum มคาตาสดคอ 0 เทานน 8: 9: 10: int centerindex = (leftindex + rightindex)/2; 11: int maxsumleft = maxSumDivideConquer(array, leftindex, centerindex); 12: int maxsumright = maxSumDivideConquer ( array, centerindex + 1, right); 13: int maxlefthalfSum = 0, lefthalfSum = 0;

14: // เกบผลรวมทมากทสดนบจากตวสดทายของครงซายลงไปถงตวแรก 15: for (int i = center; i >= leftindex; i--) 16: lefthalfSum = lefthalfSum + array[i]; 17: if (lefthalfSum > maxlefthalfSum) 18: maxlefthalfSum = lefthalfSum; 19: 20: 21: int maxrighthalfSum = 0, righthalfSum = 0; 22: // เกบผลรวมทมากทสด นบจากตวแรกของครงขวาไปถงตวสดทาย 23: for (int i = centerindex + 1; i <= rightindex; i++) 24: righthalfSum = righthalfSum + array [i]; 25: if (righthalfSum > maxrighthalfSum) 26: maxrighthalfSum = righthalfSum; 27: 28:

29: // จากนนหา max ของทง 3 กรณ คอ ของครงซาย, ของครงขวา, และของทอยทง 2 ครง 30: return max3 (maxsumleft, maxsumright, maxlefthalfSum + maxrighthalfSum) 31:

รป 1.8 โคดการหา maximum subsequence sum ดวย divide/ conquer

Page 21: 1 บทที่ โครงสร างข อมูลกับโปรแกรมvishnu/datastructure/aj...2 โครงสร างข อม ลก บโปรแกรม

Data Structure การคานวณความเรวของโปรแกรม 21

• subsequence ทมผลรวมเปนลบ ไมสามารถเปนสวนเรมตนของ maximum subsequence sum ไดดวยเหตผลเชนเดยวกน

ถาใหเราอยระหวางการทาลป ลปหนง โดยท i เปน index ของตวแรกของ subsequence และ j เปน index ของตวสดทายของ subsequence (ซงตวสดทายนทาให subsequence มคาเปนลบ) และ p เปน index ใด ๆ ระหวาง i+1 กบ j ดงรป

array a . . . . . i p j

ขนตอไปของลปกนาจะเปนการเลอน j ออกไป ซง • ถา a[j] เปนลบ เรากไมได maximum subsequence sum ทดขน คาของ maximum

subsequence sum กจะยงคงไมเปลยน • ถา a[j] เปนบวก เรากจะไดคา a[i]+…+a[j] ทมากขนกวา a[i]+…+a[j ตวเกา] แต

เพราะ a[i]+…+a[j ตวเกา] เปนลบ คาผลรวมจงไมมทางสคาของ maximum subsequence sum ทเกบสะสมมาตอนทผลรวมยงเปนบวกได หรอแมแตจะสคา a[j ตวใหม] เพยวๆกไมได ดงนนจงสรปไดวา ถาม subsequence เปนลบแลวละก เราไมตองทาการเลอน j ใหเสยเวลา เราควรไปเลอน i เลย

แตควรจะเลอน i ไปแคหนงชองเทานนหรอ จากสมมตฐานของขอน เรารวา a[j] เทานนททาให a[i]+…+a[j] มคาเปนลบ เพราะฉะนน การเลอน i เพมไปหนงตาแหนง กมแตทาใหคาผลรวมจาก a[i] ถง a[p] (โดย p เปนคาทอยระหวาง i ถง j) ลดลง นนคอ ถาเลอน j จาก i ตวน ยงไงกไมมทางเพม max sub sum ได เพราะฉะนนถาจะให sequence มคามากขนไดอก มทางเดยวคอเราตองเรมคดจากตาแหนงท j+1 นนคอเลอน i ไปท j+1 เลย การทาแบบนทาใหการตรวจสอบเรวขนมาก เรามาดตวโปรแกรมกนจากรป 1.9 จากตวโปรแกรมจะเหนวามการตรวจสอบหนงรอบ โดยเรยงตรวจสอบทกสมาชก แตวาจะ reset คา theSum (สะสมมาจากตาแหนง i ตามขอสงเกตของเรา) ทสะสมไวใหเปน 0 เมอเจอตวททาให sequence เปนลบ(ตวนอยทตาแหนง j) ดงนน theSum ตอไปจะถกสรางจากการรวมเลขตาแหนงท j+1 เปนตนไป ซงเปนไปตามขอสงเกต

Page 22: 1 บทที่ โครงสร างข อมูลกับโปรแกรมvishnu/datastructure/aj...2 โครงสร างข อม ลก บโปรแกรม

22 โครงสรางขอมลกบโปรแกรม วศวกรรมคอมพวเตอร จฬาฯ

ของวธท 4 น และจะเหนไดชดเจนวา Big O ลดลงมาเหลอแค O(n) เทานน เพราะมลปเพยงลปเดยว

1: int maxsubsumOptimum (int[] array) 2: int maxSum = 0, theSum = 0; 3: for (int j = 0; j < a.length; j++) 4: theSum = theSum + array [j]; 5: if ( theSum > maxSum) 6: maxSum = theSum; 7: else if (theSum < 0) // ถาเจอ a[j] ททาใหทง 8: //sequence เปนลบ 9:

10: theSum = 0; // นคอจะมาเรมคดใหมจากตาแหนง j+1 11: 12: 13: return maxSum; 14:

รป 1.9 โคดของวธทสในการหา maximum subsequence sum

การม log ใน Big O จากตวอยางวธท 3 ของการแกปญหา maximum subsequence sum จะเหนวาม log เขามาเกยวของ เรามหลกงาย ๆ ในการดวาโปรแกรมม Big O เปน log คอถาเราสามารถใชเวลาคงท (O(1)) ในการแบงปญหาปญหาหนงออกเปนสวน ๆ เทา ๆ กน (อยางในตวอยาง maximum subsequence sum เราแบงปญหาเปนสองสวนเทา ๆ กน) ปญหานนจะม Big O เปน O(log n)ในการคดปญหาประเภทนเรามกสมมตใหมการอานขอมลเขาเรยบรอยแลว มฉะนนแคการอานขอมลเขากเปน O(n) แลว

ตวอยางท 1-5 มสมาชก อารเรย a[0] ถง a[n-1] ซงเรยกจากนอยไปหามากอยในอารเรย a เรยบรอยแลว เราตองการจะหา x วาอยในชองของ index ไหน (ถาไมอยเลยใหแสดงผลเปน -1)

Page 23: 1 บทที่ โครงสร างข อมูลกับโปรแกรมvishnu/datastructure/aj...2 โครงสร างข อม ลก บโปรแกรม

Data Structure การม log ใน Big O 23

ถาใชการไลหาจากสมาชกอารเรยตวแรก (Big O คอ O(n)) จะเสยเวลาได ในเมอเรารวาอารเรยนเรยงสมาชกไวแลว กควรใชความรนใหเปนประโยชน โดยดสมาชกตวกลางของอารเรย ถามนนอยกวา x แสดงวา เหลอครงขวาของ array ใหหาอยางเดยว ถามนมากกวา x กจะเหลอครงซายใหหาอยางเดยว ทาอยางนจะหาไดเรวขนมาก วธนเรยกวา Binary search มาดตวโปรแกรมกน 1: int binarySearch (int[] a, int x) 2: int left = 0, right = a.length – 1; 3: while (left <=right) 4: int mid = (left + right)/2; 5: if (a[mid] < x ) 6: left = mid + 1; 7: else if (a[mid] > x) 8: right = mid – 1; 9: else 10: return mid; 11: 12:

13: return -1; // ถงตรงนแสดงวาไมเจอเลย 14:

จะเหนไดวาในแตละครงทลป ขนาดของอารเรยทเราตองตรวจสอบจะลดไปครงหนงทกครง ฉะนนคา Big O คอ O(log(n)) การหาขอมลดวยวธนใชไดดกบตารางทไมคอยมการเปลยนแปลง (ไมงนตองจดเรยงขอมลบอยเกนไป)

ตวอยางท 1-6 ลองดโปรแกรมทหาตวหารรวมมากของ n กบ m 1: long gcd (long m , long n) 2: while (n!=0) 3: long rem = m%n; 4: m = n; 5: n = rem; 6: 7: return m; 8:

Page 24: 1 บทที่ โครงสร างข อมูลกับโปรแกรมvishnu/datastructure/aj...2 โครงสร างข อม ลก บโปรแกรม

24 โครงสรางขอมลกบโปรแกรม วศวกรรมคอมพวเตอร จฬาฯ

นคอการหาเศษไปเรอย ๆ จนเศษเปน 0 คาเศษทเกดกอน 0 จะเปนคาตอบ (รป 1.10 แสดงขนตอนการหา gcd (2564, 1988)) จากโปรแกรม คาทกาหนดวาจะมการวนลปหรอไม กคอคา n ซงมาจาก rem (เศษ) อกท เพราะฉะนน การลดลงของเศษจะบอกวา Big O เปนเทาไร แตถาเราดจากรป 1.10 จะเหนวา ในการเขาลปครงหนงไปการเขาลปถดไป คาเศษลดลงอยางไมเปนสดสวนเลย (ชวงแรกจะลดลงมาก จาก 576 เปน 260 และ 56 แตชวงหลงจะไมคอยลด จาก 56 ไป 36 และ 20) ในการหาคา Big O ของตวอยางนเราตองใชประโยชนจากทฤษฎตอไปน

นยามท 1-4 ถา M > N แลว M mod N < M/2

เราสามารถพสจนนยามนไดไมยาก • ถา N <= M/2: เนองจากเศษตองนอยกวา N เพราะฉะนน เศษกมคานอยกวา M/2

โดยปรยาย • ถา N > M/2: M หาร N จะได 1 กบเศษ M-N นนคอ 1 กบเศษ M – (> M/2)

เพราะฉะนน เศษจะนอยกวา M/2 โดยปรยาย จากนยามน เราดรป 1.10 อกท จะเหนวา เศษของลป ท 1 ถกนามาใชเปน m เรมตน(กอนหาเศษ)ของลปท 3 (และเศษของลปท x จะถกนามาใชเปน m เรมตนของลปท (x+2)) เพราะฉะนน เศษจากลปท (x+2) จะตองมคานอยกวาครงหนงของเศษจากลปท x นแสดงวาเมอลปผานไปสองครง ขนาดของ เศษลดลงเกนหรอเทากบครงหนงแน ๆ นทาใหเราประมาณจานวนครงของการลป ได คอ 2 log n ครง ซงหมายความวา Big O คอ O (log n)

Page 25: 1 บทที่ โครงสร างข อมูลกับโปรแกรมvishnu/datastructure/aj...2 โครงสร างข อม ลก บโปรแกรม

Data Structure การม log ใน Big O 25

1st loop rem = 2564 mod 1988 = 576

m = 1988 n = 576

2nd loop rem = 1988 mod 576 = 260 m = 576 n = 260

3rd loop rem = 576 mod 260 = 56 m = 260

n = 56 4th loop rem = 260 mod 56 = 36

m = 56 n = 36

5th loop rem = 56 mod 36 = 20 m = 36 n = 20

6th loop rem = 36 mod 20 = 16 m = 20 n = 16

7th loop rem = 20 mod 16 = 4 m = 16

n = 4 8th loop rem = 16 mod 4 = 0

m = 4 n = 0

ไม loop ตอ : return m = 4 เปนตวหารรวมมาก

รป 1.10 ขนตอนการหาตวหารรวมมากของ 2564 กบ 1988

< (576/2)

Page 26: 1 บทที่ โครงสร างข อมูลกับโปรแกรมvishnu/datastructure/aj...2 โครงสร างข อม ลก บโปรแกรม

26 โครงสรางขอมลกบโปรแกรม วศวกรรมคอมพวเตอร จฬาฯ

ตวอยางท 1-7 การยกกาลงเลข อนนเกยวกบ log n ยงไง? ตามปกต ถาใหหา xn เรากคงจะเอา x มาคณกน n-1 ครง แตถาใหดด เราสามารถแกปญหานในรปแบบของการแบงแยกและเอาชนะได ดงน • ถา n เปนเลขค กแบงเปน xn/2 สองตวแลวเอาผลลพธมาคณกน (xn/2 *xn/2) = xn

• ถา n เปนเลขค กแบงเปน x(n-1)/2 สองตวกบ x หนงตวแลวเอาผลลพธมาคณกนหมด (x(n-1)/2 * x(n-1)/2 *x) = xn

จะสงเกตไดวา ปญหาถกแบงเปน 2 ครง (ประมาณ) เทากน โดยใชการคณอยางมากแค 2 ครง นแสดงวาตองใชการคณอยางมากแค 2 log n ครง (คา Big O คอ O (log n))

ตวโปรแกรมเปนดงน 1: long power (long x, int n) 2: if (n==0) 3: return 1; 4: if (isEven (n)) 5: return power (x*x, n/2); 6: else 7: return power (x*x, n/2)*x; 8:

สาหรบเรองของ log นมนยามทสาคญคอ

นยามท 1-5 logk n = O(n) เมอ k เปนคาคงท (นยามนบอกเราวา logarithm function มอตราการเพมตามาก)

นยามท 1-6 ฟงกชน f(n) = loga n มคา big O เปน O(logb n) (a และ b เปนจานวนบวกทไมใช 1) (สรปคอ log function ม growth rate เทากน)

พสจนนยาม 1-6:

Page 27: 1 บทที่ โครงสร างข อมูลกับโปรแกรมvishnu/datastructure/aj...2 โครงสร างข อม ลก บโปรแกรม

Data Structure นยามอน ๆ นอกเหนอจาก Big O 27

ให xna =log และ ynb =log

bnanbyax

nbyaxnbna

ba

yx

ln*logln*loglnln

lnlnln,

==

==∴==∴

cnabnn bba *)(log

lnln*loglog ==

)(loglog nOn ba =∴ รป 1.11 แสดง runtime ของ big O ตางๆ จากนอยไปมาก

runtime c log n logk n n n log n n2

n3

2n

รป 1.11 runtime ของ big O

นยามอน ๆ นอกเหนอจาก Big O นยามท 1-7 Big Omega ( Ω )

T(N) = Ω (g(N)) ถามคาคงท C และ N0 ซง T(N) >= C g(N) โดย N>=N0

Page 28: 1 บทที่ โครงสร างข อมูลกับโปรแกรมvishnu/datastructure/aj...2 โครงสร างข อม ลก บโปรแกรม

28 โครงสรางขอมลกบโปรแกรม วศวกรรมคอมพวเตอร จฬาฯ

จากนยาม ถา f(N) = Ω (N2) แลวละก f(N) = Ω (N) = Ω (N1/2) แตเราควรเลอกอนทคาใกลความจรงทสด

นยามท 1-8 Big Theta ( Θ )

T(N) = Θ (h(N)) กตอเมอ T(N) = O(h(N)) และ T(N) = Ω (h(N)) (คอม c1, c2, N0 ท c1*h(N) <= T(N) <= c2*h(N) สาหรบ N >= N0

นยามท 1-9 small O

T(N) = o(p(N)) ถา T(N) = O(p(N)) แต T(N) ≠ Θ (p(N))

• T(N) = O(f(N)) มความหมายเหมอนกบ f(N) = Ω (T(N)) เราสามารถเรยกไดวา f(N)

เปน “upper bound” ของ T(N) และ T(N) กถอไดวาเปน lower bound ของ f(N) • f(N) = N2 และ g(N) = 2N2 มคา Big O และ Big Ωเทากน นนคอ f(N) = Θ (g(N)) • f(N) = N2 ม Big O ไดหลายคา (เชน O(N3), O(N4)) แตคาทดทสดคอ O(N2) เรา

สามารถใชสมการ f(N) = Θ (N2) เปนการบอกวา คา Big O -คอ N2 นเปน Big O ทดทสด

จากขอสงเกตนทาใหเราไดอกหนงนยามคอ

นยามท 1-10 ถา T(N) คอ Polynomial degree k แลว

T(N) = Θ (Nk)

Page 29: 1 บทที่ โครงสร างข อมูลกับโปรแกรมvishnu/datastructure/aj...2 โครงสร างข อม ลก บโปรแกรม

Data Structure Best case Worst case และ Average case 29

จากนยามน ถา T(N) = 5N4 + 4N3 + N เราจะไดวา T(N) = Θ (N4)

Best case Worst case และ Average case

เวลาในการ run แบบ worst case คอ เวลาเมอการ run ตองใชจานวนขนตอนมากทสด สวน best case คอ เวลาในการ run ทนอยทสดทเปนไปได สองอยางนคงไมกอใหเกดปญหาอะไร แตวาแลว average case (เวลาเฉลย) ละจะหาอยางไร ถาเราคดแบบงาย ๆ กจะสามารถหาไดจากการ

1. ดวามก input (ขอมลเขา) เขาโปรแกรม 2. สาหรบแตละ input ดวาโปรแกรมใชกขนตอน (unit time) ในการ run 3. คาเฉลย (average case running time) = ผลรวมของจานวน unit time จากทก input /

จานวน input แตการหาคาเฉลยอยางงายน ตงอยบนสมมตฐานวา input แตละแบบมอตราการเกดขนเทากน ถาจะใหไมตองมสมมตฐานน เราตองเอาคาความนาจะเปนในการเกดของ input แบบตาง ๆ เขามาคดดวยนนคอ

Average case running time = Σi ความนาจะเปนของ inputi * คา unit time เมอใช inputi

โดย ความนาจะเปนมคาตงแต 0 ถง 1 และความนาจะเปนทงหมดบวกกนตองได 1 แตวธนกยงตงอยบนสมมตฐานทวา คา ความนาจะเปนทงหมดตองหาได

ตวอยางท 1-8 ถาเราตองการหา x ในอารเรยขนาด n

Page 30: 1 บทที่ โครงสร างข อมูลกับโปรแกรมvishnu/datastructure/aj...2 โครงสร างข อม ลก บโปรแกรม

30 โครงสรางขอมลกบโปรแกรม วศวกรรมคอมพวเตอร จฬาฯ

Best case เกดขนเมอเจอ x ในชองแรกของอารเรยเลย สวน Worst case เกดขนเมอ x อยชองสดทายในอารเรย (หรออาจไมอยเลย) Average case อาจเปนไดหลายอยาง ถาเราสมมตวา x อาจอยในชองไหนของอารเรยกได (คอแตละชองมโอกาสเทากน)

- โอกาสท x จะอยในชองแรก คอ 1/n - โอกาสท x จะอยในชองท i ใดๆ คอ 1/n

เพราะฉะนน Average Case running time = 1/n * (จานวนขนตอนทใชในการหาเมอ x อยชองท 1) + 1/n * (จานวนขนตอนทใชในการหาเมอ x อยชองท 2) + ... + 1/n * (จานวนขนตอนทใชในการหาเมอ x อยชองท n หรออาจไมอยเลย) = (1 + 2 +… + n) / n = (n+1)/2 สรปไดวาจะไดเวลาของ average case เปน (n+1)/2 ซงม big O เปน O(n) ซงในทนเปนคา big O ทเทากบคา big O ของ worst case แตถาคาความนาจะเปนเปลยนไป เชน

• ใหความนาจะเปนทจะเจอ x ในชองแรก = 41

• ความนาจะเปนทจะเจอ x ในชองท 2 = 81

เพราะฉะนน ความนาจะเปนทจะเจอ x ในชองหนงนอกจากชองแรกและชองท 2

)2(85

)2/()81

411(

−=

−−−=

n

n

คาเฉลยของ running time จะกลายเปน

)2(85*)...43(

21

*)2(8

5...4*)2(8

53*)2(8

52*811*

41

−++++=

−++

−+

−++=

nn

nnnn

แบบฝกหด

1. ให f(n) = 7n*log2n และ g(n) = n2 จงหาคา n0 (ซง <= n) ซงทาให f(n) <g(n) 2. จงพสจนวา ถา ))(()(1 NfONT = และ ))(()(2 NgONT = แลว

)))((),((max()()( 21 NgONfONTNT =+

Page 31: 1 บทที่ โครงสร างข อมูลกับโปรแกรมvishnu/datastructure/aj...2 โครงสร างข อม ลก บโปรแกรม

Data Structure Best case Worst case และ Average case 31

3. จงพสจนวา T(N) = O(f(N)) กตอเมอ f(N) = Ω (T(N)) 4. จงแสดงวา 3(n+1) เปน O(3n) 5. จงแสดงวา n = O(n log n) 6. จงพสจนวา logk n = o(n) เมอ k เปนคาคงท 7. ถา f(n) = 3n เมอ n เปนจานวนค และ f(n)=n2 เมอ n เปนจานวนค จงหาคา big O ของ f(n) 8. ถามตวเลขอย n ตว จงเขยนโปรแกรมเพอหาคาทมากทสดและนอยทสดโดยใชการ

เปรยบเทยบไมเกน 3n/2 ครง 9. สมมตวามโปรแกรมอยสองโปรแกรม โปรแกรมทหนงม worst case running time = 230 n

log2 n สวนโปรแกรมทสองม worst case running time = n2 จงหาวาเมอ n เปนเทาไร โปรแกรมทสองจงจะม worst case running time มากกวาโปรแกรมแรก

10. ใหเรามสมการ in

ii xaxp ∑

=

=0

)( เราสามารถนามาเขยนใหมเปน

)...)))(...((()( 13210 nn xaaxaxaxaxaxp ++++++= − ซงวธการนเรยกวา วธการของ Horner จงเขยนโปรแกรมหา p(x) รวมทงบอกคา big O ดวย

11. จงเขยนโปรแกรมเพอคณเลขสองจานวน โดยใหใชเครองหมายบวกเทานน โปรแกรมนมคา big O เปนเทาไร

12. จงพสจนวา ∑=

=−n

i

ni1

2)12(

13. จงแสดงวา ⎡ ⎤ )log(log1

2 nnin

i

Θ=∑=

14. สมมตวาหองสมด”โคตรโหด” ปรบเราเมอคนหนงสอสายวนแรกเปนจานวนเงน 2 บาท ถาเราไมคน คาปรบจะยกกาลงสองในวนตอไปและตอไปเรอยๆ ถามวาในวนท n คาปรบจะเปนเทาไร และจะใชเวลากวนคาปรบจงจะเทากบ x บาท

15. จงดดแปลงโปรแกรมทหา maximum subsequence sum ใหเกบคา index ของ maximum subsequence sum ไวดวยเพอพรอมพมพออกมาทกเวลา

16. จงเขยนโปรแกรมเพอหา minimum subsequence sum โปรแกรมนมคา big O เปนเทาไร 17. จงเขยนโปรแกรมเพอหา maximum subsequence product โปรแกรมนมคา big O เปน

เทาไร

Page 32: 1 บทที่ โครงสร างข อมูลกับโปรแกรมvishnu/datastructure/aj...2 โครงสร างข อม ลก บโปรแกรม

32 โครงสรางขอมลกบโปรแกรม วศวกรรมคอมพวเตอร จฬาฯ

18. จงเขยนโปรแกรมเพอหาวาจานวนเตมบวก n เปนจานวนเฉพาะหรอไม โปรแกรมนมคา big O เปนเทาไร

19. ถาใน 0.5 วนาท โปรแกรมหนงสามารถจดการ input ไดหนงรอยหาสบตว จงหาวาในหานาทโปรแกรมนจะสามารถจดการกบ input ไดกตว เมอโปรแกรมนเปน O(n log n) และ O(n2) ตามลาดบ

20. จงหา big O จากโคดชดตอไปน 1: sum=0; 2: for(i=0;i<n;i++) 3: for(j=0;j<n*n;j++) 4: sum++;

1: sum=0; 2: for(i=0;i<n;i++) 3: for(j=0;j<i;j++) 4: sum++;

1: sum=0; 2: for(i=0;i<n;i++) 3: for(j=0;j<i*i;j++) 4: for(k=0;k<j;k++) 5: sum++;

1: sum=0; 2: for(i=1;i<n;i++) 3: for(j=1;j<i*i;j++) 4: if(j%i = =0) 5: for(k=0;k<j;k++) 6: sum++;