วันอังคารที่ 26 เมษายน พ.ศ. 2559

บทที่ 5

   บทที่ 5

                                              คิว (Queues)

      คิว(Queue)เป็นโครงสร้างข้อมูลแบบเชิงเส้นหรือลิเนียร์ลิสตซึ่งการเพิ่มข้อมูลจะกระทำทีปลายข้างหนึ่งซึ่งเรียกว่าสวนท้ายหรือเรียร์ (rear)และการนำข้อมูลออกจะ กระทำที่ปลายอีกข้างหนึ่งซึ่งเรียกวา ส่วนหน้า หรือฟรอนต์(front)ลักษณะการทำงานของคิวเป็นลักษณะของการเข้าก่อน ออกก่อนหรือที่เรียกว่า FIFO (First In First Out)

การทำงานของคิว

การใส่สมาชิกตัวใหม่ลงในคิวเรียกว่า Enqueue ซึ่งมีรูปแบบคือenqueue (queue, newElement) หมายถึง การใส่ข้อมูลnewElement ลงไปที่ส่วนเรียร์
                       
การนำข้อมูลที่อยู่ตอนต้นของคิวมาแสดงจะ เรียกว่า Queue Frontแต่จะไม่ทำการเอาข้อมูลออกจากคิวการนำข้อมูลที่อยู่ตอนท้ายของคิวมาแสดงจะ เรียกว่าQueue Rear แต่จะไม่ทำการเพิ่มข้อมูลเข้าไปในคิว
                              















    การแทนที่ข้อมูลของคิวการแทนที่ข้อมูลของคิวสามารถทาได 2 วิธี คือ
1. การแทนที่ข้อมูลของคิวแบบลิงค์ลิสค์
2. การแทนที่ข้อมูลของคิวแบบอะเรย์

การแทนที่ข้อมูลของคิวแบบลิงค์ลิสต

   การแทนที่ข้อมูลของสแตกแบบลิงค์ลิสต จะประกอบไปด้วย 2 ส่วน คือ
1. Head Node จะประกอบไปด้วย 3 ส่วนคือ พอยเตอร์จำนวน 2 ตัว คือ Front และ rear กับจำนวนสมาชิกในคิว
2. Data Node จะประกอบไปด้วย ข้อมูล (Data) และพอยเตอร์ที่ชี้ไปยังข้อมูลตัวถัดไปการดำเนินการเกี่ยวกับคิวการดำเนินการเกี่ยวกับคิว ได้แก่
1. Create Queue
2. Enqueue
3. Dequeue
4. Queue Front
5. Queue Rear
6. Empty Queue
7. Full Queue

Algorithm CreateQueue
Pre Nothing
Post Head has been allocated and initialized
Return Head’s address if successful, null if overflow
1. if (memory available)

allocate (newPrt)
2 newPtr->front = null pointer
3 newPtr->rear = null pointer
4 newPtr->count = 0
5 return newPtr
2. Else1 return null pointer
End CreateQueue



Algorithm EnQueue
Queue has been create
Post Item data have been inserted
Return Boolean; True: if successful, False ifoverflow
1. if (queue full)
1 return false


1 allocate(newPtr)
2 newPtr->data = item
3 newPtr->next = null pointer
4 if (queue->count zero)
1 queue->front = newPtr
5 else1 queue->rear->next = newPtr
6 queue->rear = newPtr
7 queue->count = queue->count+1
8 return true
End EnQueue

Algorithm DeQueue
Queue has been create
Data at front of queue returned to userthrough item and front element deleted and recycled
Return Boolean; True: if successful, False ifunderflow
1. if (queue->count is 0)
1 return false

1 item = queue->front->data
2 deleteLoc = queue->front
3 if (queue->count 1)
1 queue->rear = null pointer
4 queue->front = queue->front->next
5 queue->count = queue->count-1
6 recycle(deleteLoc)
7 return true
End Dequeue

4.Queue Front เป็นการนำข้อมูลที่อยู่ส่วนต้นของคิวมา
Algorithm QueueFront
Queue is a pointer to an initialized queue
Post Data pass back to caller
Return Boolean; True: successful, False ifunderflow


5. Queue Rear เป็นการนำข้อมูลที่อยู่ส่วนท้ายของคิวมาแสดง
Algorithm QueueRearPre
Queue is a pointer to an initialized queue
Post Data pass back to caller
Return Boolean; True: successful, False if underflow

6. Empty Queue เป็นการตรวจสอบว่าคิวว่างหรือไม่
Algorithm EmptyQueue
Queue is a pointer to a queuehead node
Return Boolean; True: if empty, False if queuehas data
1. Return (queue->count equal 0)
End EmptyQueue

7. Full Queue เป็นการตรวจสอบว่าคิวเต็มหรือไม่
Algorithm FullQueue
Pre Queue is a pointer to a queue head node
Return Boolean; True: if full, False if room for anothernode
1. allocate (tempPtr)
2. if (allocation successful)
1 release (tempPtr)
2 return false
3. else
1 return true
End FullQueue

8. Queue Count เป็นการนับจำนวนสมาชิกที่อยู่ในคิว
Algorithm QueueCount
Queue is a pointer to the queuehead node
Return Queue count
1. Return queue->count
End QueueCount

9. Destroy Queue เป็นการลบข้อมูลทั้งหมดที่อยู่ในคิวAlgorithm DestroyQueue
Queue is valid queue
All data have been deleted and recycled
Return null pointer
1. pWalker = queue->front
2. Loop(pWalker not null)
1 deletePtr = pWalker
2 pWalker = pWalker->next
3 recycle (deletePtr)
4 recycle (queue)
5 return null pointer1.
End DestroyCount

การแทนที่ข้อมูลของคิวแบบอะเรย์

  การนำข้อมูลเข้าสู่คิว จะไม่สามารถนำเข้าในขณะที่คิวเต็ม หรือไม่มีที่ว่าง ถ้าพยายาม นำเข้าจะทำให้เกิดความผิดพลาดที่เรียกว่า overflow การนำข้อมูลออกจากคิว จะไม่สามารถนำอะไรออกจากคิวที่ว่างเปล่าได้ถ้าพยายามจะทำให้เกิดความผิดพลาดที่เรียกว่า underflow ในการใส่สมาชิกลงในคิวจะต้องตรวจสอบ ก่อนว่าคิวเต็ม หรือไม่

  จากตัวอย่าง จะเห็นได้ว่าอาจจะมีปัญหาในการนำเข้าข้อมูลในกรณีที่คิวเต็มแต่สภาพความเป็นจริงแล้ว front ไม้ได้อยู่ในช่องแรก ของคิว จะไม่สามารถนำที่ว่างในส่วนหน้ามาใช้ได้อีก
วิธีการแก้ปัญา ดั้งกล่าว จะใช้คิวที่เป็น แบบคิววงกลม(Circular Queue)ซึ่งคิวช่องสุดท้ายนั้นต่อกับคิวช่องแรกสุด



   จากตัวอย่าง จะเห็นได้ว่าอาจจะมีปัญหาในการนำเข้าข้อมูลในกรณีที่คิวเต็มแต่สภาพความเป็นจริงแล้ว front ไม้ได้อยู่ในช่องแรก ของคิว จะไม่สามารถนำที่ว่างในส่วนหน้ามาใช้ได้อีกวิธีการแก้ปัญา ดั้งกล่าว จะใช้คิวที่เป็น แบบคิววงกลม(Circular Queue)ซึ่งคิวช่องสุดท้ายนั้นต่อกับคิวช่องแรกสุด

วันจันทร์ที่ 11 เมษายน พ.ศ. 2559

บทที่ 4

บทที่ 4

                         สแตก(stack)

     สแตก  เป็นโครงสร้างข้อมูลที่เก็บข้อมูลต่อเนื่องกัน  ซึ่งมีลักษณะคล้ายกันกับการวางจานข้าวหรือหนังสือซ้อนกันเป็นชั้นๆ  โดยมีตัวดำเนินการคอยจัดการกับข้อมูล  ได้แก่  การนำข้อมูลเข้า(Push)  และการนำข้อมูลออก (Pop)  โดยจะกระทำกับข้อมูลที่อยู่ตำแหน่งบนสุดในสแตกเท่านั้น  จึงทำให้หลักการของโครงสร้างข้อมูลดังกล่าวมีลักษณะเป็น "เข้าก่อนออกทีหลัง  Last In First Out /LIFO) ซึ่งหมายถึง  ข้อมูลที่นำเข้าเป็นลำดับสุดท้ายจะถูกนำออกจากสแตกเป็๋นลำดับแรก

1. ฟังก์ชัน Push ทำหน้าที่เพิ่มข้อมูลเข้าไปในชั้นบนสุดของแสต็กปัญหาของการ  
Push ก็คือต้องมีความมั่นใจว่าภายในสแต้กนั้นมีพื้นที่ว่างพอที่จะบรรจุข้อมูลใหม่ลงไปได้ถ้าหาก 
สแต็กหรือมีพื้นที่ว่างไม่เพียงพอ จะทำให้เกิดสถานะโอเวอร์โฟลว์ (Overflow State) ส่งผลให้ 
ไม่สามารถใส่ข้อมูลใหม่เข้าไปในสแต็กได้อีก ซึ่งโดยทั่วไปเราจะใช้ฟังก์ชัน fullStack ในการ 
ตรวจสอบว่าสแต็กเต็มหรือไม่ โดยพิจารณาจากรูปที่ 1 ที่แสดงถึงฟังก์ชัน Push ด้วยการใส่ 
ข้อมูลลงในสแต็ก 
รูปที่ 1 การPush ข้อมูลลงในสแต็ก
                2. ฟังก์ชัน Pop  เป็นฟังก์ชันคืนค่าข้อมูลที่อยู่บนสุดของสแต็กส่งคืนให้กับผู้ใช้ พร้อม 
ทั้งลบข้อมูลรายการนั้นออกไปด้วย ส่งผลให้ข้อมูลรายการถัดไปกลีบมาอยู่ในสถานะบนสุดอีกครั้ง 
และเมื่อรายการสุดท้ายในสแต็กได้ถูกนำออกไปทั้งหมด สแต็กดังกล่าวก็จะถูกกำหนดให้อยู่ใน 
สถานะว่าง (EmptyState) แต่หากในขณะนั้นมีการเรียกใช้ฟังก์ชัน Pop บนสแต็กว่างเปล่าจะ 
ทำให้เกิดสถานะอันเดอร์โฟลว์(Underflow State) ดังนั้นเมื่อต้องการ Pop ข้อมูลออกจาก 
สแต็ก จึงจำเป็นต้องตรวจสอบก่อนว่าสแต็กนั้นว่างหรือไม่ ซึ่งโดยทั่วไปเราจะใช้ฟังก์ชัน empty 
Stack ในการตรวจสอบว่าสแต็กว่างหรือไม่ โดยพิจารณาจากรูปที่ 2 ที่แสดงถึงฟังก์ชัน Pop  
ด้วยการนำข้อมูลออกจากสแต็ก
รูปที่ 2  การ Pop ข้อมูลออกจากสแต็ก
              3. ฟังก์ชัน Stack Top ฟังก์ชันนี้จะมีความคล้ายคลึงกับฟังก์ชัน Pop ที่คืนค่าข้อมูล 
ด้วยการคัดลอกข้อมูลบนสุดของสแต็กส่งคืนให้กับผู้ใช้ แต่จะแตกต่างตรงที่ฟังก์ชัน Stack Top  
นั้น จะคืนค่าข้อมูลไปยังผู้ใช้งานเท่านั้น โดยไม่มีการลบข้อมูลออกจากสแต็กแต่อย่างใด กล่าวคือ 
หน้าที่ของฟังก์ชัน StackTop นั้นก็คือการอ่านข้อมูลบนสแต็กที่อยู่ลำดับบนสุดของสแต็กนั่นเอง  
โดยพิจารณาจากรูปที่ 3 ที่แสดงถึงฟังก์ชันStack Topด้วยการอ่านข้อมูลจากสแต็กที่อยู่ใน 
ลำดับสุดส่งคืนกลับไปยังผู้ใช้เพื่อนำไปใช้งานต่อไป 
รูปที่ 3 การอ่านข้อมูลด้วย Stack Top

การสร้างสแต็กด้วยอาร์เรย์ 


                   การสร้างสแต็กด้วยโครงสร้างข้อมูลแบบอาร์เรย์นั้น เป็นการจัดสรรพื้นที่หน่วยความ

จำแบบสแตติก (Static)  ซึ่งต้องมีการกำหนดขนาดของสแต็กเพื่อใช้งานล่วงหน้าว่าต้องการขนาด

เท่าไรจากนั้นก็ทำการจัดสรรเนื้อที่ภายในหน่วยความจำแบบคงที่ตายตัวและด้วยโครงสร้างแบบ

อาร์เรย์ที่นำมาแทนที่ข้อมูลของสแต็ก จึงต้องจัดเก็บข้อมูลที่เป็นชนิดเดียวกัน จากรูปที่ 4

แสดงถึงการสร้างสแต็กด้วยอาร์เรย์

      
                                 รูปที่ 4  การสร้างสแต็กด้วยอาร์เรย์

อย่างไรก็ตาม การเลือกโครงสร้างข้อมูลแบบอาร์เรย์มาสร้างสแต็กนั้น จะมีข้อเสียอยู่หลายประการ

ด้วยกัน คือ
  • การสร้างสแต็กด้วยอาร์เรย์ต้องมีการจัดสรรพื้นที่หน่วยความจำที่แน่นอนไว้ล่วงหน้า
  • กรณีการเพิ่มข้อมูลลงในสแต็กมากเกินกว่าที่กำหนดไว้จะส่งผลให้สแต็กเต็มได้ 
  • แต่ก็สามารถแก้ไขปัญหาได้ด้วยการจัดสรรเนื้อที่ภายในหน่วยความจำจำนวนมากๆ เข้าไว้
    ซึ่งก็จะทวีความสิ้นเปลืองยิ่งขึ้น
  • สำหรับกรณีมีข้อมูลจำนวนน้อยหรือไม่มีข้อมูลในสแต็กเลย นั่นหมายความว่าต้องเสียพื้นที่
    หน่วยความจำไปโดยปริยาย
การสร้างสแต็กด้วยลิงก์ลิสต์

            การสร้างสแต็กด้วยโครงสร้างข้อมูลแบบลิงก์ลิสต์จัดเป็นอีกวิธีหนึ่งที่มีประสิทธิภาพสูงซึ่ง

ลิงก์ลิสต์จะจัดสรรหน่วยความจำแบบไดนามิก (Dynamic) ดังนั้นจึงไม่ต้องกำหนดขนาดคงที่อย่าง

เช่นอาร์เรย์ กล่าวคือหน่วยความจำจะถูกจัดสรรเมื่อมีการใช้งานจริงเท่านั้น อีกทั้งยังสามารถจัดเก็บ

ข้อมูลต่างชนิดกันได้ นอกจากนี้แล้ว การสร้างสแต็กด้วยลิงก์ลิสต์ สแต็กจะไม่มีวันเต็มต่อเมื่อยังมี

เนื้อที่เพียงพอต่อการจัดสรรได้อยู่

               ส่วนประกอบสำคัญของลิงก์ลิสต์ก็คือ โครงสร้างสองส่วนที่มีความแตกต่างกันคือ ส่วนหัว

(Head) และส่วนข้อมูล (Data Node) โดยโครงสร้างส่วนหัวจะประกอบไปด้วย Metadataที่เป็น

ข้อมูลเพื่อใช้อธิบายข้อมูลอีกทีหนึ่ง และพอยน์เตอร์ที่อยู่ส่วนบนสุดของสแต็ก สำหรับส่วนข้อมูลจะ

ประกอบด้วยข้อมูลพอยน์เตอร์ที่ใช้เชื่อมโยงไปยังโหนดถัดไปในสแต็ก พิจารณาจากรูปที่ 6 ที่

แสดงถึงการสร้างสแต็กด้วยด้วยลิงก์ลิสต์ โดยรูปที่ 5 นั้นคือแนวความคิดของสแต็ก และเป็นรูป

แบบของการสร้างสแต็กด้วยลิงก์ลิสต์ในเชิงกายภาพ

      
                                     รูปที่ 5 การสร้างสแต็กด้วยลิงก์ลิสต์

บทที่ 3

บทที่ 3

ลิงลิสต์ (Linked  List)

ลิงลิสต์ (Linked  List)

         ลิงค์ลิสต์ (Linked  List) เป็นโครงสร้างข้อมูลที่ถูกประยุกต์ใช้ในการคำนวณและประมวลผลต่างๆมากมาย  การเก็บข้อมูลลิงค์ลิสต์จะเป็นแบบลำดับเช่นเดียวกันกับสแตคและคิว  เพียงแต่งลำดับในข้อมูลในลิงค์ลิสต์อาจจะตรงหรือไม่ตรงกับลำดับของข้อมุลที่เก็บไว้บนพื้นที่เก็บข้อมูลก็ได้

        ข้อมูล (Data)

        ในส่วนของข้อมูลจะมีการจัดเก็บสารสนเทศที่สามารถนำไปใช้ในการประมวลผลตามที่ต้อง

การต่อไป

         ลิงค์ (Link)

         ในส่วนของลิสต์นั้น จะใช้สำหรับเชื่อมโยงไปยังข้อมูลโดยเริ่มต้นจากเฮดพอยน์เตอร์ที่ชี้ไป 

ยังตำแหน่งโหนดแรกของลิสต์ จากนั้นลิงก์ในแต่ละโหนดก็จะเชื่อมโยงไปยังโหนดตัวถัดไปเรื่อยๆ

ส่วนชื่อของลิสต์จะเป็นชื่อเดียวกันกับชื่อตัวแปรพอยน์เตอร์โดยลิงก์ลิสต์อย่างง่ายที่จะกล่าวถึงต่อ

ไปนี้คือ ซิงเกิลลิงก์ลิสต์ (Single-Linked List) ซึ่งจะมีเพียงลิงก์เดียวที่ใช้เชื่อมโยงไปยังโหนด

ตัวถัดไป

           โครงสร้างข้อมูลแบบลิงก์ลิสต์ (Linked List Data Structure)

            สำหรับโครงสร้างข้อมูลลิงก์ลิสต์ ประกอบด้วย

 โครงสร้างโหนดส่วนหัว (Head Node Structure)

            ภายในโหนดส่วนหัวจะมีเพียงหนึ่งพอยน์เตอร์ที่จะชี้ไปยังลิสต์ คือ เฮดพอยน์ เตอร์ ภายใน  โครงสร้างส่วนนี้จะมี Metadata ที่เอาไว้อธิบายข้อมูลภายในลิสต์ ภายในนี้คือฟิลด์ Count เพื่อ เอาไว้บอกว่าในลิสต์นี้มีจำนวนสมาชิกทั้งหมดเท่าไร ซึ่งสามารถเพิ่มหรือลดลงได้ หากมีการแข้ ไขข้อมูลในลิสต์

โครงสร้างโหนดข้อมูล (Data  Node Structure) 

             โครงสร้างโหนดข้อมูลประกอบด้วยส่วนข้อมูลและลิงก์ สำหรับข้อมูล  (Data  type) ของ  ลิสต์นั้นจะขึ้นอยู่กับการนำไปประยุกต์ใช้ แต่ปกติแล้ว ชนิด ข้อมูลจะเป็นไปในลักษณะที่แสดงไว้ที่  ด้านล่างและที่สำคัญ ชนิดข้อมูลจะต้องได้รับ การปรับปรุงรายละเอียดอยู่เสมอหลังจากถูกสร้างขึ้น

ความจริงแล้วมีโครงสร้างข้อมูลอยู่หลายชนิดที่สามารถนำมาสร้างลิสต์ แต่หัวข้อต่อ 
ไปนี้จะขอ  กล่าวถึงการสร้างลิสต์ด้วยลิงก์ลิสต์เป็นสำคัญ โดยสามารถสรุปคุณสมบัติ 
ของลิงก์ลิสต์ได้ดังนี้ 
1.ลิงก์ลิสต์จะใช้เฮดพอยน์เตอร์ (pHead) เป็นตัวชี้ไปยังโหนดแรกของลิสต์ ในขณะ ที่พอยน์เตอร์หรือลิงก์ของแต่ละโหนดก็จะเชื่อมโยงลิงก์ไปยังโหนดตัวถัดไป โดย โหนดตัวสุดท้ายที่ไม่ มีลิงก์ให้เชื่อมต่อจะถูกกำหนดค่าให้เป็น null ซึ่งในที่นี้ใช้ สัญลักษณ์   S  แทน 
2. โหนดข้อมูลจะประกอบด้วย Data และ Link โดยที่

- Data คือข้อมูลหรือสารสนเทศที่สามารถนำไปใช้ประโยชน์ 
- Link คือตัวชี้หรือพอยน์เตอร์ที่ใช้สำหรับเชื่อมโยงไปยังโหนดถัดไป

3. ไม่มีความสัมพันธ์ทางกายภาพระหว่างโหนด

4. ข้อมูลที่จัดเก็บภายในหน่วยความจำไม่จำเป็นต้องอยู่ติดกัน

5. กรณีที่พอยน์เตอร์ไม่มีตัวชี้หรือไม่มีสมาชิก เฮดพอยน์เตอร์จะถูกกำหนดค่าเป็น null ซึ่งหมาย  ถึงลิสต์ว่านั่นเองลิงก์ลิสต์จัดเป็นโครงสร้างข้อมูลที่ดีโครงสร้างหนึ่ง เพราะว่าเป็นโครงสร้างที่  ง่ายต่อการเพิ่มและลบข้อมูลไม่ว่าจะกระทำที่ส่วนหน้า ส่วน หลัง หรือส่วนกลางของข้อมูล

                     การสร้างลิสต์ (Create List)

                ฟังก์ชัน Create List เป็นการกำหนดโครงสร้างโหนดส่วนหัวและกำหนดค่าเริ่มต้น ให้   กับ metadata  สำหรับลิสต์โดยในที่นี้จะมี   metadata   อยู่  2  ตัวด้วยกัน  แต่ก็อาจขยาย เพิ่มเติมได้

         การแทรกโหนด (Insert Node)  

                เป็นฟังก์ชันที่ใช้สำหรับแทรกโหนดเพิ่มเข้าไปในลิสต์ ณ ขณะนี้ต้องการเพียงว่า โหนด ก่อนหน้า (Predecessor) ของโหนดใหม่ที่จะแทรกนั้นคือโหนดใดเมื่อได้รับการแจ้งว่าโหนด ก่อนหน้าคือโหนดใดแล้ว ก็จะทำการแทรกข้อมูลเพิ่มตามขั้นตอนต่อไปนี้

                  1.จัดสรรหน่วยความจำสำหรับโหนดใหม่พร้อมกับข้อมูล
 
                  2.กำหนดตัวชี้ให้กับลิงก์ฟิลด์ของโหนดใหม่ 
                  3.นำตัวชี้ที่อยู่ก่อนหน้าโหนดใหม่ชี้มายังโหนดใหม่ 
                 จาก 3 ขั้นตอนของการแทรกโหนดเข้าไปยังลิสต์ข้างต้น เป็นเพียงการนำเสนอขั้น 
ตอน ในรูปแบบอย่างง่ายเพื่อให้เกิดความเข้าใจในเบื้องต้นเท่านั้น แต่ความเป็นจริงยังมีรายละเอียด

         อีกหลายอย่าง

                 ในการแทรกโหนดเข้าไปในลิสต์นั้น ขั้นตอนแรกจำเป็นต้องรู้ตำแหน่งที่อยู่ของโหนด ก่อนหน้าโหนดใหม่ที่ต้องการจะแทรกเสียก่อน ซึ่งโหนดนี้จะระบุตัวชี้ที่เป็นไปได้ทั้ง 2 สถานะด้วย กันคือ อาจเป็นแอดเดรสของโหนดถัดไป หรือเป็นค่า null ก็ได้ การที่จำเป็นต้องรู้ตำแหน่งโหนด ก่อนหน้าก็เพราะว่าโหนดนี้จะมีลิงก์ที่ใช้สำหรับเชื่อมโยงไปยังโหนดถัดไป ซึ่งลิงก์ดังกล่าวนี้จะนำ มาแทนตำแหน่งลิงก์ของโหนดใหม่เพื่อชี้ไปยังโหนดข้างหลัง (Successor) ที่อยู่ถัดจากโหนด ใหม่นั่นเอง แต่กรณีดังกล่าวเป็นการประยุกต์ใช้กับการแทรกระหว่างโหนดภายในลิสต์ แต่ถ้าเป็น กรณีลิงก์ของโหนดก่อนหน้ามีค่าเป็นnull นั่นหมายความว่าเป็นการแทรกโหนดที่ท้ายลิสต์ในการ แทรกโหนดเพิ่มเข้าไปในลิสต์สามารถกระทำได้ 4 รูปแบบด้วยกันคือ 

              1. การแทรกโหนดในลิสต์ว่าง (Insert into Empty List) 

                   กรณีนี้เป็นการแทรกโหนดเพิ่มเข้าไปในลิสต์ในขณะที่ลิสต์ว่างเปล่าหรือไม่มีข้อมูล ใดๆ อยู่นั่นหมายถึงเป็นการแทรกสมาชิกตัวแรกเข้าไป ซึ่งขณะนั้นเฮดพอยน์เตอร์จะมีค่าเป็น  null เนื่องจากเป็นลิสต์ว่าง หลังจากนั้นมีลิสต์ใหม่ที่ต้องการแทรกเพิ่มเข้ามา (pNew) 
(a) Before add
                  
                                                                       (b) After add

รูป แสดงการแทรกโหนดเมื่อลิสต์ภายในว่าง

           2 การแทรกโหนดที่ตำแหน่งแรก (Insert at Beginning) 

               เป็นการแทรกโหนดเข้าไปไว้ในตำแหน่งโหนดแรก ซึ่งทำให้โหนดที่เคยอยู่ลำดับแรก เดิมต้องมาต่อท้ายโหนดใหม่ที่แทรกเข้าไป ขั้นตอนแรกของการแทรกข้อมูลที่โหนดแรกของลิสต์  จะต้องทราบถึงตัวชี้ของตัว Predecessor ก่อน ซึ่งหากไม่มี หรือมีค่าเป็น nullก็หมายความว่า เป็นการแทรกโหนดแรกในลิสต์ว่างเปล่า
                      การแทรกโหนดที่ลำดับแรกจะมีวิธีการคือ ให้นำตัวชี้ของโหนดใหม่ชี้ไปยังโหนด      แรกของ ลิสต์หลังจากนั้นก็ทำการกำหนดเฮดพอยน์เตอร์ชี้ไปยังโหนดใหม่ ซึ่งเราจะรู้            ตำแหน่งแอดเดรสของโหนดใหม่อยู่แล้วหลังจากที่ได้สร้างขึ้นมา

                                                                     (a) Before add
                   
                                                           (b) After add

                     รูป  แสดงการแทรกโหนดไว้ที่ตำแหน่งแรกของลิสต์

        3 การแทรกโหนดที่กึ่งกลางของลิสต์ (Insert in Middle) 

            การเพิ่มโหนดในส่วนกลางของลิสต์หรือการแทรกระหว่างโหนด ในขั้นตอนแรก ต้องรู้ตำ แหน่งโหนดก่อนหน้าเสียก่อน ซึ่งก็คือตัว Predecessor (pPre) ความสำคัญของโหนด  Predecessor ก็คือจะมีลิงก์ที่ใช้เชื่อมโยงไปยังโหนดถัดไป 
            ในการแทรกโหนดระหว่างสองโหนด ตัวชี้หรือลิงก์ฟิลด์ของโหนดใหม่จะชี้ไปยังโหนด  Successor ในขณะที่ตัวชี้ pPre ก็จะชี้ไปยังโหนดใหม่ 

                                                   (a) Before add
                   
                                                       (b) After add 
รูป  แสดงแทรกโหนดที่กึ่งกลางของลิสต์

          4 การแทรกโหนดที่ท้ายลิสต์ (Insert at End) 

              เมื่อมีการเพิ่มโหนดที่ส่วนท้ายของลิสต์ เราต้องการเพียงแค่ตัวชี้ของ Predecessor  เพื่อชี้ไปยังโหนดใหม่เท่านั้น ซึ่งในที่นี้จะไม่มีโหนด Successor เนื่องจากเป็นการแทรกที่ท้าย ลิสต์ดังนั้นลิงก์ฟิลด์ของโหนดใหม่จึงถูกกำหนดให้เป็นค่า null

              อย่างไรก็ตาม ก็ยังมีตรรกะพิเศษในอีกรูปแบบหนึ่งเพื่อใช้กับอัลกอริทึมการแทรกโหนด
 ที่ท้ายลิสต์ ซึ่งจัดเป็นข้อดีข้อหนึ่งของโครงสร้างลิงก์ลิสต์ โดยเราทราบอยู่แล้วว่าโหนดสุดท้ายของ ลิสต์จะมีตัวชี้ที่เชื่อมโยงไปที่ null นั่นหมายถึงโหนดสุดท้ายที่ไม่มีโหนดตัวถัดไปแล้วนั่นเองแต่ถ้า หากเรามีความต้องการใช้พอยน์เตอร์มากกว่าที่จะใช้ค่าคงที่ของ null เป็นตัวกำหนด

a) Before add

            
(b) After add

รูป  การแทรกโหนดไว้ที่ส่วนท้ายของลิสต์ 

                 จากรายละเอียดการแทรกโหนดเข้าไปในลิสต์ในรูปแบบต่างๆไม่ว่าจะเป็นการแทรก โหนดในขณะที่ลิสต์ว่าง การแทรกโหนดที่ตำแหน่งแรกของลิสต์ กึ่งกลางหรือท้ายลิสต์ก็ตามและ ต่อ ไปนี้ขอกล่าวถึงอัลกอลิทึมที่ใช้สำหรับการแทรกโหนดเข้าไปในลิสต์ โดยจะมีพอยน์เตอร์ชี้ไป ยัง ลิสต์ตัว Predecessor และข้อมูลที่ต้องการแทรก ซึ่งจะต้องมีการจัดสรรหน่วยความจำสำหรับ โหนดใหม่ และทำการปรับเปลี่ยนพอยน์เตอร์เชื่อมโยงที่เหมาะสมต่อไป เมื่ออัลกอริทึมนี้ทำงานจน สัมฤทธิ์ผล จะรีเทิร์นค่าตรรกะเป็นจริงเมื่อแทรกโหนดใหม่ ซึ่งก็คือข้อผิดพลาดในสถานะ Overflow นั่นเอง


                  การลบโหนด (Delete Node) 

                  อัลกอริทึมการลบโหนดออกจากลิสต์นอกจากจะนำโหนดที่ถูกลบส่งคืนแก่หน่วยความ จำระบบเพื่อจะได้นำไปใช้งานอื่นต่อไปแล้ว ยังต้องมีการปรับเปลี่ยนตัวชี้ใหม่ด้วย สำหรับขั้นตอน แรกของการลบโหนด จะต้องค้นหาตำแหน่งของโหนดที่ต้องลบ (pLoc) ภายในลิสต์ให้พบก่อน เมื่อพบตำแหน่งโหนดที่ต้องการลบภายในลิสต์แล้ว จะทำให้ทราบตำแหน่งแอดเดรสของ Predecessor(pPre) ซึ่งก็คือโหนดที่อยู่ก่อนหน้าโหนดที่ต้องการลบนั่นเอง หลังจากนั้นก็จะ กำหนดลิงก์ฟิลด์ของโหนด Predecessorชี้ไปยังโหนด Successor ซึ่งเป็นโหนดที่อยู่ด้านหลัง โหนดที่ถูกลบ จากนั้นก็จะนำพื้นที่หน่วยความจำที่เก็บโหนดที่ถูกลบไปนั้นส่งคืนแก่ระบบเพื่อนำ ไป ใช้งานอื่นต่อไป

                 1.การลบโหนดที่ตำแหน่งแรก  (Delete First Node)


                 
 เมื่อรู้ตำแหน่งแรกแล้ว (pLoc) ต่อมาก็ให้ทำการรีเซตเฮดพอยน์เตอร์เพื่อชี้ไปยัง โหนดSuccessor ที่อยู่ถัดไปจากโหนดแรกที่ต้องการลบ จากนั้นก็จะนำโหนดที่ถูกลบส่งคืนแก่ ระบบ และเนื่องจากในที่เป็นการลบโหนดแรกออกจากลิสต์ ตัวโหนด Predecessor (pPre) ที่อยู่ ก่อนหน้านั้นจึงไม่มีดังนั้นโหนด pPre จึงถูกกำหนดค่าให้เป็น null ซึ่งก็หมายถึงเป็นการลบโหนด ที่ตำแหน่งแรกนั่นเอง

               2 การลบโหนดโดยทั่วไป  (General Delete Case) 

                การลบโหนดออกจากลิสต์ในกรณีทั่วไป ซึ่งประกอบด้วยการลบโหนดที่อยู่กึ่งกลางภาย ในลิสต์ และการลบโหนดที่ท้ายลิสต์ ทั้งสองกรณีต่างก็สามารถใช้ตรรกะเดียวกันในการใช้งานใน การลบโหนดลบโหนดออกจากลิสต์ ไม่ว่าจะเป็นโหนดที่อยู่กึ่งกลางลิสต์หรือที่ท้ายลิสต์ก็ตามขั้น ตอน แรกจำเป็นต้องรู้ตำแหน่งโหนดที่ลบเสียก่อน จากนั้นก็กำหนดตัวชี้ของโหนด Predecessor ให้ชี้ไปยังโหนดSuccessor ที่อยู่ถัดจากโหนดในตำแหน่ง pLoc หรือโหนดที่ต้องการลบนั่นเอง โดยแสดงขั้นตอนการกระทำได้ดังรูป

                                          (a) Before delete
      
                                               (b) After delete
รูป การลบโหนดออกจากลิสต์โดยทั่วไป
                      ส่วนกรณีการลบโหนดที่ท้ายลิสต์ออกเมื่อโหนดท้ายลิสต์ได้ถูกลบออกไปแล้ว ค่าของ null pointer จะถูกย้ายไปเก็บไว้ในตำแหน่งฟิลด์ของโหนด Predecessorดังนั้น โหนดที่เคยอยู่ก่อนหน้าก็จะกลายเป็นโหนดในลำดับสุดท้าย ส่วนโหนดท้ายลิสต์ที่ถูกลบไป ก็จะส่งคืนกลับไปยังระบบ

                      ารค้นหาข้อมูลภายในลิสต์ (Search List)

                เป็นฟังก์ชันที่ใช้สำหรับค้นหาข้อมูลภายในลิสต์ซึ่งตามปกติแล้วการค้นหาข้อมูลภายใน ลิสต์สามารถค้นพบได้จากอัลกอริทึมที่หลากหลายเพื่อใช้งานในรูปแบบต่างๆ ไม่ว่าจะเป็น 

                การแทรกโหนด  ที่จำเป็นต้องรู้ตำแหน่งตัว Predecessorหรือโหนดก่อนหน้าของ โหนดที่ต้องการจะแทรกก่อน

                การลบโหนดออกจากลิสต์  ขั้นแรกต้องค้นหาโหนดที่ต้องการลบให้พบก่อน แล้วจึง ค่อย กำหนดให้โหนด Predecessor ชี้ไปยังตำแหน่งโหนด Successor จากนั้นจึงปลดโหนดที่ ลบไปนั้นคืนแก่ระบบ


                การดึงข้อมูลจากลิสต์ ขั้นแรกจำเป็นต้องค้นหาข้อมูลภายในลิสต์ให้พบก่อน จึงสามารถ ดึงข้อมูลนั้นออกมาใช้งานได้ เรามีความจำเป็นต้องค้นหาข้อมูลในรูปแบบ Sequential Search กับกรณีการค้นหาข้อมูลในลิสต์ที่สร้างด้วยลิงก์ลิสต์ เป็นเพราะว่าโหนดต่าง ๆ ที่อยู่ ภายใน ลิสต์นั้นไม่ได้มีความสัมพันธ์กันในทางกายภาพเลย ซึ่งแตกต่างจากลิงก์ลิสต์ที่สร้างด้วย อาร์เรย์ ที่สามารถค้นหาข้อมูลภายในอาร์เรย์ได้ด้วยวิธี Binary Search ซึ่งมีประสิทธิภาพเหนือ กว่า สำหรับการค้นหาข้อมูลแบบ Sequential Search ภายในลิงก์ลิสต์ สามารถเรียกอีกชื่อหนึ่ง ว่า Ordered List Search


                 การดึงข้อมูลจากโหนดออกมาใช้งาน (Retrieve Node) วิธีการดึงข้อมูลออกจาก โหนดเพื่อนำออกมาใช้งานนั้น จะเริ่มต้นด้วยการค้นหาโหนดจากตำแหน่งข้อมูลภายในลิสต์ ถ้า หากพบข้อมูลที่ต้องการ ก็จะทำการเคลื่อนย้ายข้อมูลไปยังพื้นที่เอาต์พุตในส่วนของโมดูลที่เรียกใช้ งาน และจะรีเทิร์นค่าตรรกะเป็นจริงกลับไป แต่ถ้าไม่พบก็จะรีเทิร์นค่าตรรกะเป็นเท็จกลับไป สำหรับ ซูโดโค้ดการดึงข้อมูลจากโหนดภายในลิสต์ออกมาใช้งาน


                  ลิสต์ว่าง (Empty List) เป็นฟังก์ชันที่ใช้ตรวจสอบว่าภายในลิสต์ว่างหรือไม่ ซึ่งเป็น โมดูลแบบง่ายที่รีเทิร์นค่าตรรกะ ณ ขณะนั้นกลับไป เช่น รีเทิร์นค่าตรรกะเป็นจริงกลับไปเมื่อลิสต์ ว่างหรือในทางตรงกันข้ามก็จะรีเทิร์นค่าตรรกะเท็จกลับไป เป็นต้น

                 ลิสต์เต็ม 
(Full List) เป็นฟังก์ชันที่ใช้ตรวจสอบว่าภายในลิสต์นั้นเต็มหรือไม่ ซึ่งก็จัด เป็นโมดูลแบบง่ายเช่นกันด้วยการรีเทิร์นค่าตรรกะในขณะนั้นกลับไป อย่างไรก็ตาม ฟังก์ชันนี้อาจ ไม่จำเป็นต้องใช้ก็ได้โดยเฉพาะในภาษา C เนื่องจากลิงก์ลิสต์ใช้หน่วยความจำแบบไดนามิก

               จำนวนสมาชิกในลิสต์  (List  Count) ฟังก์ชัน List  Count ภายในโมดูลจะมีเพียง ประโยคคำสั่งเดียวเท่านั้น แต่ก็เป็นฟังก์ชันที่มีความสำคัญทีเดียว เพราะว่าจะแจ้งจำนวนสมาชิกหรือจำนวนอิลิเมนต์ที่มีอยู่ในขณะนั้นให้กับโมดูลที่เรียก แทนที่จะต้องท่องเข้าไปในลิสต์เพื่อนับ สมาชิกแต่ละอิลิเมนต์แทน

วันอังคารที่ 8 มีนาคม พ.ศ. 2559

บทที่ 2

บทที่ 2

อาร์เรย์  (Array )

โครงสร้างข้อมูลแบบอาร์เรย์  (Array )

          อาร์เรย์  (Array ) หรือแถวลำดับคือการรวมกลุ่มของตัวแปรที่สามารถใช้ตัวแปรที่สามารถ
ใช้ตัวแปรที่สามารถใช้ตัวแปรชื่อเดียวแทนข้อมูลสมาชิกได้หลาย ๆ ตัวในคราวเดียวกันด้วยการใช้
เลขดรรชนี(index) หรือซับสคริปต์ (Subscript) เป็นตัวอ้างอิงตำแหน่งสมาชิกบนแถวลำดับนั้นๆ
ในความเป็นจริงแล้วโครงสร้างข้อมูลแบบอาร์เรย์นั้นจัดเป็นโครงสร้างข้อมูลพื้นฐานที่เข้าใจง่ายที่
สุดเมื่อเทียบกับบรรดาโครงสร้างข้อมูลชนิดอื่นๆภาษาคอมพิวเตอร์ระดับสูงทุกภาษาสามารถนิยาม
ข้อมูลแบบอาร์เรย์ได้ทั้งสิ้น

คุณสมบัติของอาร์เรย์  (Array )

        1. อาร์เรย์เป็นตัวแทนกลุ่มของข้อมูลที่มีความสัมพันธ์กัน
        2. สมาชิกในอาร์เรย์จะมีคุณสมบัติเหมือน ๆกันกล่าวคือต้องมีชนิดข้อมูลเหมือนกันทั้งหมด
        3. ขนาดของอาร์เรย์จะมีขนาดคงที่ และจะเก็บมากกว่า 50 ช่องไม่ได้
        4.อาร์เรย์เป็นโครงสร้างข้อมูลที่ผู้ใช้สามารถอ้างอิงเพื่อเข้าถึงข้อมูลที่ต้องการได้ทันที

การอ้างอิงตำแหน่งสมาชิกในอาร์เรย์

        อาร์เรย์ หรือแถวลำดับ คือการรวมกลุ่มของตัวแปรชื่อเดียวแทนข้อมูลสมาชิกหลายตัวโดยใช้เลขดัชนี(Index) หรือ ซับสคริปต์ (Subscript) เป็นตัวอ้างตำแหน่งสมาชิกบนแถวลำดับนั้นโดยเลขดรรชนีจะอยู่ภายในเครื่องหมาย ( ) หรือ [ ] ก็ได้ ทั้งนี้ขึ้นอยู่กับภาษาคอมพิวเตอร์แต่
ละภาษาตัวอย่างที่เช่น 
Month [1]   แทนเดือนที่ 1     คือเดือนมกราคม
Month [2]   แทนเดือนที่ 2     คือเดือนกุมภาพันธ์
:
Month [12] แทนเดือนที่12    คือเดือนธันวาคม
  
อย่างไรก็ตาม ในภาษาคอมพิวเตอร์อย่างภาษา C หรือ JAVA หมายเลขลำดับของอาร์เรย์จะเริ่มต้นด้วยหมายเลข0 ในขณะที่ภาษา FORTRAN จะเริ่มต้นด้วยหมายเลข 1 ดังนั้นหากมีการประกาศตัวแปรอาร์เรย์ด้วยภาษา C หรือ JAVA ก็อาจทำให้การใช้งานเพื่ออ้างอิงลำดับสมาชิกในอาร์เรย์เกิดความสับสนได้ จึงจำเป็นต้องใช้อย่างระมัดระวัง

 ขอบเขตของอาร์เรย์ (Bounds)

        เลขดรรชนีในอาร์เรย์ประกอบด้วยช่วงขอบเขตของค่า ซึ่งประกอบด้วยขอบเขตล่างสุด 
(Lower Bound)และขอบเขตบนสุด (Upper Bound) แต่อย่างไรก็ตาม ในภาษาคอมพิว
เตอร์บางภาษาจะกำหนดขอบเขตค่าดังกล่าวได้เพียงขอบเขตบนสุดเท่านั้นโดยขอบเขตล่าง
สุดจะถูกกำหนดคงที่เตรียมไว้อยู่แล้ว เช่น ภาษาC, C++, C# และ JAVAจะถูกกำหนดขอบ
เขตล่างสุดเท่ากับ 0 ในขณะที่ภาษาFORTRANจะถูกกำหนดขอบเขตล่างสุดเท่ากับ 1

        ตัวอย่าง  การกำหนดตัวแปรอาร์เรย์ในภาษา FORTRAN ซึ่งขอบเขตล่างสุดของภาษา
FORTRAN

จะเท่ากับ 1 (L = 1)

INTEGER a (5)
         การประกาศดังกล่าวก็คือ กำหนดอาร์เรย์ชื่อ a เป็นชนิดข้อมูลแบบจำนวนเต็มโดยกำหนด
ขนาด 5ช่องซึ่งเป็นไปดังรูป


  รูปที่ 2.1รายละเอียดของอาร์เรย์ a

        สำหรับการคำนวณหาจำนวนสมาชิกของอาร์เรย์หนึ่งมิติ สามารถคำนวณได้จากสูตรดังนี้
จำนวนสมาชิก = U – L + 1
โดยที่      U = ขอบเขตบนสุด (Upper Bound)
               L = ขอบเขตล่างสุด (Lower Bound)
สำหรับการคำนวณหาจำนวนสมาชิกของอาร์เรย์ a ก็จะเป็นไปตามสูตรดังนี้
จำนวนสมาชิก = U – L + 1
                      = 5 –  1 + 1
                      = 5
สำหรับในกรณีเดียวกัน แต่หากกำหนดตัวแปรอาร์เรย์ด้วยภาษา C ซึ่งขอบเขตล่างสุดของภาษา C
จะเท่ากับ 0 (L = 0)
Int b[5];

รูปที่ 2.2  รายละเอียดของอาร์เรย์  b

        สำหรับการคำนวณหาจำนวนสมาชิกของอาร์เรย์ a ก็จะเป็นไปตามสูตรดังนี้
จำนวนสมาชิก = U – L + 1

                      = 4 –  0 + 1

                      = 5
ในกรณีที่ อาร์เรย์มีมากกว่า 1 มิติ

     U1    ขอบเขตบนสุด (Upper Bounds) ของแถว
     L1    ขอบเขตล่างสุด (Lower Bounds) ของแถว
     U2    ขอบเขตบนสุด (Upper Bounds) ของคอลัมน์
     L2    ขอบเขตล่างสุด (Lower Bounds) ของคอลัมน์

จำนวนสมาชิก = (U1 – L1 + 1)  x  (U2 – L2 + 1)

การจัดเก็บอาร์เรย์ในหน่วยความจำ


     สมาชิกทุกตัวในอาร์เรย์ต้องเป็นข้อมูลชิดเดียวกันการเข้าถึงข้อมูลในอาร์เรย์แต่ละตำแหน่งใช้เวลาในการเข้าถึงข้อมูลเท่าๆกัน

การจัดเก็บข้อมูลใน อาร์เรย์ มี 3 แบบคือ


              อาร์เรย์ 1 มิติ (One-Dimension Array)

   คือ อะเรย์ที่มีเพียง แถวนอน แต่มี แถวตั้งหลายแถว ซึ่งในการระบุตำแหน่งหรือตัวชี้(index) จะมีแต่ระบุแต่ตำแหน่งของแถวตั้งเท่านั้น โดยนับเริ่มจาก 0
               Array Name   คือ ชื่อของอาร์เรย์               L   คือขอบเขตล่างสุด (Lower Bound)                            U   คือขอบเขตบนสุด (Upper Bound)                          LOC ( a [ i ] )  =  B + w ( i – L )               LOC ( a [ i ] )   = ตำแหน่งแอดเดรสที่เก็บ a[i] ในหน่วยความจำ                B    = แอสเดรสเริ่มต้นของ a                 w    = จำนวนช่องของหน่วยความจำที่จัดเก็บข้อมูลต่อหนึ่งสมาชิก                 ตัวอย่างเช่น ขนาดหน่วยความจำที่ใช้เก็บข้อมูลสมาชิก 1 ตัวของแต่ละช่องเท่ากับ 4 ไบต์ (32 บิต) ดังนั้น กำหนดให้                  กำหนดให้ : แอดเดรสเริ่มต้น (Base Address) = 1000                                                              W      = 1                อยากทราบว่าอาร์เรย์ a[10] ถูกจัดเก็บไว้ในหน่วยความจำแอดเดรสใด ก็สามารถคำนวณได้จากสูตรดังต่อไปนี้                LOC (a[i]     = B + w(i – L)                LOC (a[10] = 1000 + 1(10 – 0)                                    = 1010                 ดังนั้นตำแหน่งอาร์เรย์ a[10] จะถูกเก็บไว้ในหน่วยความจำแอดเดรสที่ 1010 นั่นเอง
 รูปที่1  แสดงอาร์เรย์  number ที่จัดเก็บอยู่ภายในหน่วยความจำคอมพิวเตอร์


                  อาร์เรย์สองมิติ (Two  Dimension  Array) 
                  
                   อาร์เรย์สองมิติจะมีรูปแบบตารางที่ประกอบด้วยแถว (Row) และคอลัมม์ (Column) การอ้าองอิงอาร์เรย์สองมิติจึงต้องระบุบแนวแถวและคอลัมม์  สำหรับรูปแบบทั่วไปของโครงสร้างข้อมูลอาร์เรย์สองมิติ  คือ

                                                   ArrayName [L1 : U1 , L2 : U2]       
            
                    โดยที่  ArrayName  คือชื่อของอาร์เรย์

                    L1   คือขอบเขตล่างสุด  (Lower Bound)  ของแถว

                   U1  คือขอบเขตบนสุด  (Upper Bound)   ของแถว

                   L2   คือขอบเขตล่างสุด  (Lower Bound)  ของคอลัมน์

                  U2  คือขอบเขตบนสุด  (Upper Bound)   ของคอลัมน์

                 โดยสมมติว่าได้มีการกำหนดให้ K[4,3] หรือ K[0:3,0:2] ด้วยภาษา C ดังนี้

                  int K[4] [3];

                ซึ่งแสดงได้ดังรูป

                        
                 รูปที่ 2  รูปแสดงอาร์เรย์สองมิติชื่อ K ที่มีขนาดมิติ 4 x 3

          อย่างไรก็ตาม การจัดเก็บอาร์เรย์สองมิติในหน่วยความจำยังสามารถจัดเก็บได้ 2 วิธี 
ด้วยกันคือ
  1. การจัดเก็บด้วยการเรียงแถวเป็นหลัก (Row Major Order)
  2. การจัดเก็บด้วยการเรียงคอลัมน์เป็นหลัก (Column Major Order)
                ในกรณีการจัดเก็บอาร์เรย์สองมิติในหน่วยความจำด้วยการเรียงแถวเป็นหลัก การจัด เรียงจะเริ่มต้นตั้งแต่แถวแรกและเรียงลำดับต่อไปในแต่ละคอลัมน์จนครบ จากนั้นก็ขึ้นแถวใหม่ ไปเรื่อยๆ จนกระทั่งแถวสุดท้าย

       
                  รูปที่ 3 ข้อมูลของอาร์เรย์สองมิติชื่อ K ที่จัดเก็บอยู่ในหน่วยความจำหลักในรูปแบบเรียงแถวเป็น                              หลัก (Row Major Order)

                อาร์เรย์สามมิติ(Three Dimension Array) 


               หากพิจารณาให้ดี จะเห็นว่าอาร์เรย์ สามมิตินั้นก็คือการนำอาร์เรย์สองมิติมาเรียงซ้อนกันหลายๆ ชั้น (Page) ทำให้อาร์เรย์สามมิติ  นอกจากจะมีแถวและคอลัมน์แล้วก็จะมีความลึกเพิ่มขึ้นอีก ซึ่งความลึกนี้เองเกิดขึ้นจากการนำ อาร์เรย์สองมิติมาเรียงซ้อนกัน  สำหรับรูปแบบทั่วไปของโครงสร้างข้อมูลอาร์เรย์สามมิติ คือ 

               ArrayName [L1 : U1 , L2 : U2 , L3 : U3]    
                                               
              โดยที่  ArrayName  คือชื่อของอาร์เรย์

              L1     คือขอบเขตล่างสุด  (Lower Bound)  ของชั้น

             U1      คือขอบเขตบนสุด  (Upper Bound)   ของชั้น

             L2      คือขอบเขตล่างสุด  (Lower Bound)  ของแถว

             U2     คือขอบเขตบนสุด  (Upper Bound)   ของแถว

             L3      คือขอบเขตล่างสุด  (Lower Bound)  ของคอลัมน์

             U3     คือขอบเขตบนสุด  (Upper Bound)   ของคอลัมน์

           โดยสมมติว่าได้มีการกำหนดให้ S[3,4,5] หรือ S[0:2, 0:3, 0:4] ด้วยภาษา C ดังนี้

           Int S [3] [4] [5] ;

          ในการอ้างสมาชิกแต่ละตัวบนแถวลำดับสามมิติสามารถกำหนดให้เป็นไปดังนี้คือ

          S [0, 0, 0], S [0, 0 1], S [i, j, k], … , S [2, 3, 4]

          การจัดเก็บอาร์เรย์สามมิติในหน่วยความจำ จะเป็นในลักษณะเช่นเดียวกันกับที่ผ่านมา 

คือเรียงลำดับเป็นแนวเดียว อีกทั้งยังสามารถจัดเก็บด้วยการเรียงแถวเป็นหลัก หรือคอลัมน์เป็นหลัก 

เช่นเดียวกับอาร์เรย์สองมิติที่ผ่านมา และต่อไปนี้คือสูตรการคำนวณหาแอดเดรสของอาร์เรย์สามมิติ

แบบแถวเป็นหลัก
    
            LOC (S[i, j, k] ) = B + [w X R X C (i-L1) ]  + [w X C (j-L2) ]  + [w(k- L3) ]

            และจากรูป คืออาร์เรย์สามมิติชื่อ S ที่จัดเก็บภายในหน่วยความจำในรูปแบบแถวเป็น

หลักในที่นี้ต้องการทราบตำแหน่งแอดเดรสที่เก็บข้อมูลอาร์เรย์ S ชั้นที่ 0 แถวที่ 3 คอลัมน์ 4

จากรูปแบบของอาร์เรย์สามมิติ         S[L1 : U1 , L2 : U2 , L3 :U3]

ได้มีการประกาศอาร์เรย์ด้วยภาษา C ดังนี้  S [3] [4] [5]

ผลที่ได้ อาร์เรย์ K จะมีขอบเขตระหว่าง     K [0:2, 0:3, 0:4]

LOC (S[i, j, k] )    = B + [w X R X C (i-L1) ]+ [w X C (j-L2) ]+ [w(k- L3) ]

LOC (S[0, 3, 4] ) = 500 + [4 X 4 X 5 (0-0) ]+ [4 X 5 (3-0) ]+ [4(4- 0) ]

                             = 500 + 0 + 60 +16

                             = 576




ดังนั้นอาร์เรย์ S ชั้นที่ 0 แถวที่ 3 คอลัมน์ 4 จะจัดเก็บอยู่ในตำแหน่งแอดเดรสที่ 576

 รูปที่ 4 อาร์เรย์ S ชั้นที่ 0 แถวที่ 3 คอลัมน์ 4 จะจัดเก็บอยู่ในตำแหน่งแอดเดรสที่ 576