Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C++

การกลับกันของโหนด K ตัวสลับกันใน Singly Linked List ด้วย C++

ในบทช่วยสอนนี้ เราได้รับ linked list A ความยาว N และจำนวนเต็ม K เราต้องกลับลำดับคู่โหนดสลับกัน โดยขนาดของแต่ละคู่คือ K ยังกำหนดว่า N หาร K ลงตัว อาร์กิวเมนต์แรกคือหัวข้อ (head pointer) ของ linked list A และอาร์กิวเมนต์ที่สองคือจำนวนเต็ม K เช่น

ข้อมูลนำเข้า

5 -> 6 -> 2 -> 8 -> 5 -> 2 -> 4 -> 8 -> 9 -> 6 -> null K=2

ข้อมูลส่งออก

6 -> 5 -> 2 -> 8 -> 2 -> 5 -> 4 -> 8 -> 6 -> 9 -> null
1 -> 2 -> 5 -> 8 -> 9 -> 6 -> 4 -> 5 -> 8 -> null K=3

ข้อมูลส่งออก

5 -> 2 -> 1 -> 8 -> 9 -> 6 -> 8 -> 5 -> 4 -> null

แนวทางการหาคำตอบ

วิธี Iterative (วนซ้ำ)

  • ท่อง 2K โหนดต่อการวนซ้ำ (หรือลูป) และบันทึกหัวและหางของแต่ละคู่ K โหนดในอินพุตที่กำหนด (Linked list) โดยใช้ join และ tail pointer
  • จากนั้น กลับลำดับ K โหนดของ linked list และเชื่อมโหนดหางของรายการที่กลับแล้ว กับโหนดหัวของ linked list เริ่มต้น ที่ถูกชี้โดย join pointer
  • จากนั้นเราจะเปลี่ยน current pointer ไปยัง K โหนดถัดไป
  • หางของรายการปัจจุบันทำหน้าที่เป็นโหนดสุดท้าย (ซึ่งถูกชี้โดย new tail) และ join pointer จะชี้ไปหัวของรายการใหม่ (ที่กลับแล้ว) และพวกมันถูกรวมเข้าด้วยกัน เราจะวนซ้ำขั้นตอนเหล่านี้จนกว่าทุกโหนดจะทำตามขั้นตอนเดียวกัน

ตัวอย่างโค้ด (Iterative)

#include <bits/stdc++.h> using namespace std; class Node {    public:    int data;    Node* next; }; Node* kAltReverse(struct Node* head, int k){    Node* prev = NULL;    Node* curr = head;    Node* temp = NULL;    Node* tail = NULL;    Node* newHead = NULL;    Node* join = NULL;    int t = 0;    while (curr) {       t = k;       join = curr;       prev = NULL;       while (curr && t--) {          temp = curr->next;          curr->next = prev;          prev = curr;          curr = temp;       }       if (!newHead)          newHead = prev;       if (tail)          tail->next = prev;       tail = join;       tail->next = curr;       t = k;       while (curr && t--) {          prev = curr;          curr = curr->next;       }       tail = prev;    }    return newHead; } void push(Node** head_ref, int new_data){    Node* new_node = new Node();    new_node->data = new_data;    new_node->next = (*head_ref);    (*head_ref) = new_node; } void printList(Node* node){    int count = 0;    while (node != NULL) {       cout << node->data << " ";       node = node->next;       count++;    } } int main(void){    Node* head = NULL;    int i;    for (i = 6; i <27; i+=3)       push(&head, i);    int k = 3;    cout << "Given linked list \n";    printList(head);    head = kAltReverse(head, k);    cout << "\n Modified Linked list \n";    printList(head);    return (0); }

ข้อมูลส่งออก

Given linked list 24 21 18 15 12 9 6 Modified Linked list 18 21 24 15 12 9 6

วิธี Recursive (เรียกซ้ำ)

  • ท่อง K โหนดจากจุดเริ่มต้น และตั้งค่า temp เป็นโหนดที่ k+1
  • กลับลำดับ K โหนดที่ท่องทั้งหมด
  • ตั้งค่า next pointer ของโหนดสุดท้ายของคู่ K โหนดนั้นเป็น temp
  • ข้ามการวนซ้ำครั้งถัดไป ซึ่งคู่ K โหนดเหล่านั้นต้องข้าม
  • เรียกซ้ำตามขั้นตอนเหล่านี้สำหรับการกลับ K โหนดถัดไป จนถึงโหนดสุดท้าย

Pseudo Code

reverseAltK(head, k)    curr = head    prev = null    next = null    count = 0    WHILE count < k AND curr       next = curr.next       curr.next = prev       prev = curr       curr = next       count = count + 1 IF head    head.next = curr count = 0 WHILE count < k-1 AND curr    curr = curr.next    count = count + 1 IF curr    curr.next = reverseKGroupAltRecursive(curr.next, k) return prev

ตัวอย่างโค้ด (Recursive)

#include <bits/stdc++.h> using namespace std; /* Link list node */ class node{    public:    int data;    node* next; }; /* Helper function for kAltReverse() */ node * _kAltReverse(node *node, int k, bool b); /* Alternatively reverses the given linked list in groups of given size k. */ node *kAltReverse(node *head, int k){    return _kAltReverse(head, k, true); } /* Helper function for kAltReverse(). It reverses k nodes of the list only if the third parameter b is passed as true, otherwise moves the pointer k nodes ahead and recursively calls iteself */ node * _kAltReverse(node *Node, int k, bool b){    if(Node == NULL)       return NULL;    int count = 1;    node *prev = NULL;    node *current = Node;    node *next;    /* The loop serves two purposes       1) If b is true,       then it reverses the k nodes       2) If b is false,       then it moves the current pointer */    while(current != NULL && count <= k){       next = current->next;       /* Reverse the nodes only if b is true*/          if(b == true)             current->next = prev;       prev = current;       current = next;       count++;    }    /* 3) If b is true, then node is the kth node.    So attach rest of the list after node.    4) After attaching, return the new head */    if(b == true){       Node->next = _kAltReverse(current, k, !b);       return prev;    }    /* If b is not true, then attach    rest of the list after prev.    So attach rest of the list after prev */    else{       prev->next = _kAltReverse(current, k, !b);       return Node;    } } /* UTILITY FUNCTIONS */ /* Function to push a node */ void push(node** head_ref, int new_data){    /* allocate node */    node* new_node = new node();    /* put in the data */    new_node->data = new_data;    /* link the old list off the new node */    new_node->next = (*head_ref);    /* move the head to point to the new node */    (*head_ref) = new_node; } /* Function to print linked list */ void printList(node *node){    int count = 0;    while(node != NULL){       cout << node->data << " ";       node = node->next;       count++;    } } // Driver Code int main(void){    /* Start with the empty list */    node* head = NULL;    int i;    // create a list 1->2->3->4->5...... ->20    for(i = 20; i > 0; i--)       push(&head, i);    cout << "Given linked list \n";    printList(head);    head = kAltReverse(head, 3);    cout << "\nModified Linked list \n";    printList(head);    return(0); }

ข้อมูลส่งออก

Given linked list 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 Modified Linked list 3 2 1 4 5 6 9 8 7 10 11 12 15 14 13 16 17 18 20 19

สรุป

บทช่วยสอนนี้สอนวิธีกลับโหนด K ตัวสลับกันใน Singly Linked List และ pseudo-code การนำไปใช้ใน C++ สามารถเขียนใน Java, Python และภาษาอื่นๆ ได้ ในแนวทางนี้ เราใช้การเรียกซ้ำเพื่อกลับ K โหนดสลับกันและข้ามโหนดที่เหลือ หวังว่าบทช่วยสอนนี้จะมีประโยชน์