Thắc mắc về con trỏ trỏ tới con trỏ trong C

// A complete working C program to demonstrate deletion in singly
// linked list
#include <stdio.h>
#include <stdlib.h>

// A linked list node
struct Node
{
    int data;
    struct Node *next;
};
struct Node* head = NULL;

/* Given a reference (pointer to pointer) to the head of a list
and an int, inserts a new node on the front of the list. */
void push(struct Node** head_ref, int new_data)
{
    struct Node* new_node = (struct Node*) malloc(sizeof(struct Node));
    new_node->data = new_data;
    new_node->next = (*head_ref);
    (*head_ref) = new_node;
}

/* Given a reference (pointer to pointer) to the head of a list
and a key, deletes the first occurrence of key in linked list */
void deleteNode(struct Node **head_ref, int key)
{
    // Store head node
    struct Node *temp = *head_ref, *prev;

    // If head node itself holds the key to be deleted
    if (temp != NULL && temp->data == key)
    {
            *head_ref = temp->next; // Changed head
            free(temp);			 // free old head
            return;
    }
    // Search for the key to be deleted, keep track of the
    // previous node as we need to change 'prev->next'
    while (temp != NULL && temp->data != key)
    {
            prev = temp;
            temp = temp->next;
    }
    // If key was not present in linked list
    if (temp == NULL) return;

    // Unlink the node from linked list
    prev->next = temp->next;

    free(temp); // Free memory
}

// This function prints contents of linked list starting from
// the given node
void printList(struct Node *node)
{
    while (node != NULL)
    {
            printf(" %d ", node->data);
            node = node->next;
    }
}

/* Drier program to test above functions*/
int main()
{
    /* Start with the empty list */
    push(&head, 7);
    push(&head, 1);
    push(&head, 3);
    push(&head, 2);

    puts("Created Linked List: ");
    printList(head);
    deleteNode(&head, 1);
    puts("\nLinked List after Deletion of 1: ");
    printList(head);
    return 0;
}

E muốn hỏi ở hàm deleteNode.
Ban đầu temp đc trỏ tới head_ref và sau đó prev trỏ tới temp => prev trỏ tới head_ref.
Khi temp = temp->next vaf prev = temp thì con trỏ prev sẽ trỏ đến địa chỉ của temp->next và head_ref không thay đổi. Nhưng khi prev->next = temp->next thì head_ref lại được thay đổi.
Vậy lý do tại sao prev = temp thì head_ref giữ nguyên còn prev->next = temp->next thì lại thay đổi ạ.
E xin cám ơn.

Bạn vẽ 1 cái link list ra giấy, rồi cắt 3 mảnh giấy nhỏ đại diện cho temp , head_refprev , sau đó thử chạy chương trình với 3 mảnh giấy đó xem :smiley:
Nhớ ghi thông tin bằng bút chì lên mấy mảng giấy nhé cho dễ thay đổi.

3 Likes

hàm deleteNode xóa node nào giữ data == key;

temp duyệt từ đầu tới cuối list, và sau khi so sánh data == key, nếu false và chưa tới cuối( NULL ) nó sẽ gửi cái địa chỉ cho prev rồi đi tìm tiếp trong đau khổ.
Khi data == key ngay tại head thì update lại head rồi kết thúc hàm.
Khi temp tới cuối node NULL nó sẽ kết thúc hàm.
Khi ‘temp’ gặp node nào có data == key nó sẽ lấy node kế tiếp đè bẹp node này thể hiện qua:
prev->next = temp->next;
prev là node trước => prev->next là node này;
temp là node này => temp->next là node kế tiếp;

Theo như tui phân tích ở trên thì head chỉ thay đổi khi data cần delete nằm ở node đầu.
P/s: Thực sự thì code bạn lấy ở đâu ko thụt thò gì hết tui lười đọc quá, ráng coi được phần deleteNode. Bạn nên bỏ công chỉnh lai rồi hãy post.

5 Likes

chết, e xin lỗi, e sửa lại rồi ạ.

Sau 1 hồi đọc thì em vẫn chưa hiểu ý anh lắm. Em mạo muội đoán rằng prev = tempprev->next = temp->next mà anh nói tới là cái này:
image
Thế nhưng lại sau 1 hồi phân tích thì em chưa thấy việc thay prev = temp bằng prev->next = temp->next thì nó thay đổi head_ref ở chỗ nào.
Em có vẽ 1 cái ảnh mô tả quá trình hoạt động của cái hàm delete nhưng chưa thấy sự thay đổi của head_ref ở chỗ nào. (vẽ bằng paint nên hơi xấu)
Ở trường hợp prev = temp thì em có vẽ được nhưng đến prev->next = temp->next thì fail do không biết thằng prev trỏ vào thằng nào.


Không biết là em hiểu có đúng theo thắc mắc của anh không. Nếu có thì em nghĩ là trong trường hợp node cần xóa không ở đầu thì head_ref không thay đổi được. Nếu có sai gì thì anh mô tả lại cho mọi người dễ hiểu hơn và vào giúp nhé. :smiley:

Nếu chủ thớt tự code thì ko có lấy ở đâu cả. Nếu không tự code thì em có tìm được 1 nguồn. Không biết đúng nguồn không nhưng có thụt thò mà nhỉ. :smile:
(Không có ý soi mói rồi này nọ nhưng tại code đẹp với lại cmt rất kĩ nên đi tìm thôi)


P/s: Em nghĩ nếu chủ thớt lấy code mạng nên tự code lại thì vẫn hơn. Đọc code người khác có thể hiểu nhưng việc code lại sau đó không hiểu chỗ nào thì lên đây hỏi vẫn đem lại hiệu quả cao nhất. :smiley:

6 Likes

Code là trên GeeksforGeeks thôi ạ, còn việc không thụt thò là do e khi post e đã quên không edit lại. Tại e đọc và debug mãi ko hiểu nên mạo muội lên đây hỏi cho hiểu trước khi code lại ạ.
Hiện giờ e đã thông, mong mod hay admin đi qua khoá topic dùm e ạ.
E xin cám ơn mọi người đã chỉ bảo ạ

Mình không phải mod hay admin nhưng thể theo nguyện vọng của bạn chủ thớt :relieved:

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?