รายการ (Lis t) [3] ผู้สอน อาจารย์ ยืนยง กันทะเนตร สาขาวิชาเทคโนโลยีคอมพิวเตอร์เคลื่อนที่ คณะเทคโนโลยีสารสนเทศและการสื่อสาร Website : ict.up.ac.th/yeunyong
หัวข้อวันนี้ Insert & Delete หลักในการเขียนฟังก์ชัน insertFirst() deleteFirst() insertLast() deleteLast() 2
หลักในการเขียนฟังก์ชัน Insert & Delete แยกออกเป็นกรณีต่างๆ ให้ได้ เงื่อนไขของแต่ละกรณี วาดรูปแสดงการทำงานของแต่ละกรณี คำสั่งภาษาโปรแกรม รวมแต่ละกรณีเข้าด้วยกัน การเช็คเงื่อนไขอาจเปลี่ยนแปลง เล็กน้อย บางกรณีอาจรวมกัน ( บางส่วน ) ได้ เพื่อให้โปรแกรมกระชับ หรือ ทำงาน ได้ไว้ขึ้น 3
void insertFirst (node **ptr_head, int input); parameter ชื่อของตัวแปรลิสต์ที่จะใส่ข้อมูล ข้อมูลที่จะใส่ return value ไม่มี body of function มีกี่กรณี ? แต่ละกรณีจะแทรกอย่างไร ? 4
insertFirst : Singly- linked list void insertFirst ( node **ptr_head, int input ) { node *n ; n = new node ; n->data = input ; if ( *ptr_head == NULL ) { // กรณียังไม่มีข้อมูล n->next = NULL ; *ptr_head = n ; } else { // ต้องเปลี่ยน pointer 2 ตัว n->next = *ptr_head ; // next ของโหนด ใหม่ *ptr_head = n ; // head } } *** คำสั่งใน if และ else สามารถยุบรวมกันได้ 5
insertFirst : Singly- circularly-linked list void insertFirst ( node **ptr_head, int input ) { node *n, *t ; n = new node ; n->data = input ; if ( *ptr_head == NULL ) { // กรณียังไม่มีข้อมูล n->next = n ; *ptr_head = n ; } else { // ต้องเปลี่ยน pointer 3 ตัว t = *ptr_head ; // ใช้ t ท่องไปยังโหนดสุดท้าย while ( t->next != *ptr_head ) t = t->next ; t->next = n ; // next ของโหนดสุดท้าย n->next = *ptr_head ; // next ของโหนดใหม่ *ptr_head = n ; // head } } 6
insertFirst : Doubly-linked list void insertFirst ( node **ptr_head, int input ) { node *n ; n = new node ; n->data = input ; if ( *ptr_head == NULL ) { // กรณียังไม่มีข้อมูล n->next = NULL ; n->back = NULL ; *ptr_head = n ; } else { // ต้องเปลี่ยน pointer 4 ตัว n->next = *ptr_head ; // next ของโหนด ใหม่ n->back = NULL ; // back ของโหนดใหม่ *ptr_head->back = n ; // back ของโหนด แรก *ptr_head = n ; // head } } 7
insertFirst : Doubly- circularly-linked list void insertFirst ( node **ptr_head, int input ) { node *n, *t ; n = new node ; n->data = input ; if ( *ptr_head == NULL ) { // กรณียังไม่มีข้อมูล n->next = n ; n->back = n ; *ptr_head = n ; } else { // ต้องเปลี่ยน pointer 5 ตัว n->next = *ptr_head ; // next ของ โหนดใหม่ n->back = *ptr_head->back ;// back ของ โหนดใหม่ *ptr_head->back->next = n ;// next ของ โหนดสุดท้าย *ptr_head->back = n ;// back ของโหนดแรก *ptr_head = n ; // head } } 8
void deleteFirst ( node **ptr_head ) ; parameter ชื่อของตัวแปรลิสต์ที่จะดึงข้อมูลออก return value ไม่มี body of function มีกี่กรณี ? แต่ละกรณีจะลบอย่างไร ? มีความคล้ายคลึงกันกับ insertFirst() ? 9
deleteFirst : Singly-linked list void deleteFirst ( node **ptr_head ) { node *d ; d = *ptr_head ; if ( *ptr_head->next == NULL ) { // กรณี เหลือข้อมูลตัวเดียว *ptr_head = NULL ; } else { // ต้องเปลี่ยน pointer 1 ตัว *ptr_head = *ptr_head->next ; // head } delete d ; } *** คำสั่งใน if และ else สามารถยุบรวมกันได้ 10
deleteFirst : Singly- circularly-linked list void deleteFirst ( node **ptr_head ) { node *d, *t ; d = *ptr_head ; if ( *ptr_head->next == *ptr_head ) { // กรณีเหลือ ข้อมูลตัวเดียว *ptr_head = NULL ; } else { // ต้องเปลี่ยน pointer 2 ตัว t = *ptr_head ; // ใช้ t ท่องไปยังโหนดสุดท้าย while ( t->next != *ptr_head ) t = t->next ; t->next = *ptr_head->next ; // next ของโหนด สุดท้าย *ptr_head = *ptr_head->next ; // head } delete d ; } 11
deleteFirst : Doubly- linked list void deleteFirst ( node **ptr_head ) { node *d ; d = *ptr_head ; if ( *ptr_head->next == NULL ) { // กรณี เหลือข้อมูลตัวเดียว *ptr_head = NULL ; } else { // ต้องเปลี่ยน pointer 2 ตัว *ptr_head->next->back = NULL ; // back ของโหนดที่ 2 *ptr_head = *ptr_head->next ; // head } delete d ; } 12
deleteFirst : Doubly- circularly-linked list void deleteFirst ( node **ptr_head ) { node *d ; d = *ptr_head ; if ( *ptr_head->next == NULL ) { // กรณีเหลือข้อมูลตัว เดียว *ptr_head = NULL ; } else { // ต้องเปลี่ยน pointer 3 ตัว // next ของโหนดสุดท้าย *ptr_head->back->next = *ptr_head->next ; // back ของโหนดที่ 2 *ptr_head->next->back = *ptr_head->back ; // head *ptr_head = *ptr_head->next ; } delete d ; } 13
void insertLast (node **ptr_head, int input); parameter ชื่อของตัวแปรลิสต์ที่จะใส่ข้อมูล ข้อมูลที่จะใส่ return value ไม่มี body of function มีกี่กรณี ? แต่ละกรณีจะแทรกอย่างไร ? 14
insertLast : Singly- linked list void insertLast ( node **ptr_head, int input ) { node *n, *t ; n = new node ; n->data = input ; if ( *ptr_head == NULL ) { // กรณียังไม่มีข้อมูล n->next = NULL ; *ptr_head = n ; } else { // ต้องเปลี่ยน pointer 2 ตัว t = *ptr_head ; // ใช้ t ท่องไปยังโหนดสุดท้าย while ( t->next != NULL ) t = t->next ; n->next = NULL ; // next ของโหนดใหม่ t->next = n ; // next ของโหนดสุดท้าย } } 15
insertLast : Singly-circularly- linked list void insertLast ( node **ptr_head, int input ) { node *n, *t ; n = new node ; n->data = input ; if ( *ptr_head == NULL ) { // กรณียังไม่มีข้อมูล n->next = n ; *ptr_head = n ; } else { // ต้องเปลี่ยน pointer 2 ตัว t = *ptr_head ; // ใช้ t ท่องไปยังโหนดสุดท้าย while ( t->next != *ptr_head ) t = t->next ; n->next = *ptr_head ; // next ของโหนด ใหม่ t->next = n ; // next ของโหนดสุดท้าย } } 16
insertLast : Doubly- linked list void insertLast ( node **ptr_head, int input ) { node *n, *t ; n = new node ; n->data = input ; if ( *ptr_head == NULL ) { // กรณียังไม่มีข้อมูล n->next = NULL ; n->back = NULL ; *ptr_head = n ; } else { // ต้องเปลี่ยน pointer 3 ตัว t = *ptr_head ; // ใช้ t ท่องไปยังโหนดสุดท้าย while ( t->next != NULL ) t = t->next ; n->next = NULL ; // next ของโหนดใหม่ n->back = t ; // back ของโหนดใหม่ t->next = n ; // next ของโหนดสุดท้าย } } 17
insertLast : Doubly- circularly-linked list void insertLast ( node **ptr_head, int input ) { node *n, *t ; n = new node ; n->data = input ; if ( *ptr_head == NULL ) { // กรณียังไม่มีข้อมูล n->next = n ; n->back = n ; *ptr_head = n ; } else { // ต้องเปลี่ยน pointer 4 ตัว และไม่ต้องท่อง !!! n->next = *ptr_head ; // next ของโหนดใหม่ n->back = *ptr_head->back ;// back ของโหนด ใหม่ *ptr_head->back->next = n ;// next ของโหนด สุดท้าย *ptr_head->back = n ;// back ของโหนดแรก } } 18
void deleteLast ( node **ptr_head ) ; parameter ชื่อของตัวแปรลิสต์ที่จะดึงข้อมูลออก return value ไม่มี body of function มีกี่กรณี ? แต่ละกรณีจะลบอย่างไร ? 19
deleteLast : Singly-linked list void deleteLast ( node **ptr_head) { node *d, *p ; if ( *ptr_head->next == NULL ) { // กรณีเหลือข้อมูล ตัวเดียว d = *ptr_head ; * ptr_head = NULL ; } else { d = *ptr_head ; while (d->next != NULL){ p = d ; // p ท่องตาม delnode(t) d = d->next ; } p->next = NULL ; // ตัดโหนดสุดท้ายทิ้ง } delete d ; } 20
deleteLast : Singly- circularly-linked list void deleteLast ( node **ptr_head) { node *d, *p ; if ( *ptr_head->next == *ptr_head ) {// เหลือข้อมูลตัว เดียว d = *ptr_head ; *ptr_head = NULL ; } else { // ต้องเปลี่ยน pointer แค่ 1 ตัว !!! d = *ptr_head ; while (d->next != *ptr_head ){ p = d ; d = de->next ; } p->next = *ptr_head ; } delete d ; } 21
deleteLast : Doubly- linked list void deleteLast ( node **ptr_head) { node *d ; // มี back ชี้กลับโหนดก่อนหน้าแล้ว ตัด p ทิ้งได้ if ( *ptr_head->next == NULL ) { // กรณีเหลือข้อมูลตัว เดียว d = *ptr_head ; *ptr_head = NULL ; } else { // ก็ยังเปลี่ยน pointer แค่ 1 ตัว !!! d = *ptr_head ; while (d->next != NULL){ d = d->next ; } d->back->next = NULL ; // next ของโหนดก่อนหน้า } delete d ; } 22
deleteLast : Doubly- circularly-linked list void deleteLast ( node **ptr_head) { node *d ; if ( *ptr_head->next == *ptr_head ) { // เหลือข้อมูลตัว เดียว d = *ptr_head ; *ptr_head = NULL ; } else { // เปลี่ยน pointer 2 ตัว !!! และไม่ต้องท่อง !!! d = *ptr_head->back ; d->back->next = *ptr_head ; // next ของโหนดก่อน หน้า *ptr_head->back = d->back ; } delete d ; } 23