Lúng túng khi truy cập vào các Node trong linked list

Em thường hay cảm thấy khó khăn và bối rối trong việc xác định temp->next, temp->next->next
là phần nào, là địa chỉ hay cả cái node hay khi gọi câu lệnh temp->next = newNode trong hàm removeDuplicates thì temp->next là phần nào ạ. Mong mọi người chỉ cho em để em có thể hiểu cặn kẻ một tí ạ. Em xin cảm ơn mọi người.

#include "pch.h"
#include <iostream>
#include <string>
#include <stack>
using namespace std; 
class SinglyLinkedListNode {
public:
	int data;
	SinglyLinkedListNode *next;

	SinglyLinkedListNode(int node_data) {
		this->data = node_data;
		this->next = nullptr;
	}
};

class SinglyLinkedList {
public:
	SinglyLinkedListNode *head;
	SinglyLinkedListNode *tail;

	SinglyLinkedList() {
		this->head = nullptr;
		this->tail = nullptr;
	}

	void insert_node(int node_data) {
		SinglyLinkedListNode* node = new SinglyLinkedListNode(node_data);

		if (!this->head) {
			this->head = node;
		}
		else {
			this->tail->next = node;
		}

		this->tail = node;
	}
};

void print_singly_linked_list(SinglyLinkedListNode* node, string sep) {
	while (node) {
		cout << node->data;
		node = node->next;
		if (node) {
			cout << sep;
		}
	}
}
void removeDuplicates(SinglyLinkedListNode * head)
{
	SinglyLinkedListNode *temp = head;
	SinglyLinkedListNode *newNode = new SinglyLinkedListNode();
	if (temp == NULL) return;
	while (temp->next)
	{
		if (temp->data == temp->next->data)
		{
			newNode = temp->next->next;
			free(temp->next);
			temp->next = newNode;
		}
		else temp = temp->next;
	}
}



int main()
{
	SinglyLinkedList *llist = new SinglyLinkedList();
	llist->insert_node(1);
	llist->insert_node(1);
	llist->insert_node(5);
	llist->insert_node(5);
	llist->insert_node(8);
	removeDuplicates(llist->head);
	print_singly_linked_list(llist->head, " ");
	return 0;
}

Thực ra có địa chỉ là có node :slight_smile: nên ko cần phân biệt gì.


Hàm tên Remove sao lại có new node gì đây? :smiley:

SinglyLinkedListNode *newNode = new SinglyLinkedListNode();
2 Likes

Hello b,

Đầu tiên bạn cần nắm được khái niệm: “con trỏ là một biến dùng để lưu địa chỉ”

Như vậy với mọi biến con trỏ khi bạn dùng thì chắc chắc nó là địa chỉ.

Toán tử new sẽ tạo ra một đối tượng trên heap (là vùng nhớ không bị tự động thu hồi trong C++), và trả về địa chỉ vùng nhớ của đối tượng được tạo đó.

Như vậy nếu dùng: Node* p = new Node(); thì con trỏ p chứa địa chỉ của một đối tượng Node.
Khi đó, nếu muốn dùng đối tượng này (tham chiếu tới vùng nhớ đối tựong) thì ta phải dùng *p
VD: muốn lấy data của Node thì dùng (*p).data

Trong đó C++ lại hỗ trợ toán tử ->, toán tử này tương đương với (*).
Tức là (*p).data tương đương với p->data

Như vậy với câu hỏi của bạn, bạn chỉ cần xem:
Khi temp là một con trỏ kiểu Node và kiểu Node có một data member kiểu con trỏ Node là next thì:
temp->next sẽ lấy giá trị của next nằm trong đối tượng mà temp trỏ tới, next có thể chưa một địa chỉ của đối tượng khác hoặc không chưa địa chỉ nào cả.
Bạn cứ suy luận như vậy là ra.

Như trong câu hỏi của bạn thì:
Đoạn SinglyLinkedListNode *newNode = new SinglyLinkedListNode(); thì new SinglyLinkedListNode(); không cần thiết vì không dùng làm gì cả.

newNode = temp->next->next;
free(temp->next); // Đoạn này nên dùng: delete temp->next
temp->next = newNode;

Khi temp là địa chỉ của Object thứ 1 thì temp->next là địa chỉ Object thứ 2, và temp->next->next là địa chỉ của object thứ 3.

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