Chào ace, bài này chúng ta sẽ tìm hiểu về Tìm độ dài của linked list (sử dụng vòng lặp và đệ quy) trong series tự học về cấu trúc dữ liệu và giải thuật, sau đây cafedev sẽ giới thiệu và chia sẻ chi tiết(khái niệm, độ phức tạp, ứng dụng của nó, code ví dụ…) về nó thông qua các phần sau.
Trong bài học này, chúng ta sẽ viết một hàm để đếm số lượng node có trong một linked list cho trước.
Ví dụ, đối với linked list có dạng 1 -> 3 -> 1 -> 2 -> 1 thì hàm này sẽ trả về 5.
Nội dung chính
1. Thuật toán sử dụng vòng lặp
1. Khởi tạo biến đếm count bằng 0
2. Khởi tạo một con trỏ node, khai báo và khởi tạo một con trỏ current = head
3. Khi con trỏ current vẫn còn chưa NULL thì thực hiện những việc sau:
a) current = current -> next
b) count++; // sau dòng này, vòng lặp tiếp tục chạy lần lặp tiếp theo
4. return count
Sau đây sẽ là đoạn code cài đặt cái thuật toán tìm độ dài của linked list sử dụng vòng lặp đã nêu ở trên, được viết bằng nhiều ngôn ngữ lập trình:
CODE VÍ DỤ ĐƯỢC VIẾT BẰNG C++ C Java Python C#
C
// Iterative C program to find length or count of nodes in a linked list
#include<stdio.h>
#include<stdlib.h>
/* Link list node */
struct Node
{
int data;
struct Node* next;
};
/* Given a reference (pointer to pointer) to the head
of a list and an int, push a new node on the front
of the list. */
void push(struct Node** head_ref, int new_data)
{
/* allocate node */
struct Node* new_node =
(struct Node*) malloc(sizeof(struct 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;
}
/* Counts no. of nodes in linked list */
int getCount(struct Node* head)
{
int count = 0; // Initialize count
struct Node* current = head; // Initialize current
while (current != NULL)
{
count++;
current = current->next;
}
return count;
}
/* Driver program to test count function*/
int main()
{
/* Start with the empty list */
struct Node* head = NULL;
/* Use push() to construct below list
1->2->1->3->1 */
push(&head, 1);
push(&head, 3);
push(&head, 1);
push(&head, 2);
push(&head, 1);
/* Check the count function */
printf("count of nodes is %d", getCount(head));
return 0;
}
C++
// Iterative C++ program to find length
// or count of nodes in a linked list
#include <bits/stdc++.h>
using namespace std;
/* Link list node */
class Node
{
public:
int data;
Node* next;
};
/* Given a reference (pointer to pointer) to the head
of a list and an int, push a new node on the front
of the list. */
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;
}
/* Counts no. of nodes in linked list */
int getCount(Node* head)
{
int count = 0; // Initialize count
Node* current = head; // Initialize current
while (current != NULL)
{
count++;
current = current->next;
}
return count;
}
/* Driver program to test count function*/
int main()
{
/* Start with the empty list */
Node* head = NULL;
/* Use push() to construct below list
1->2->1->3->1 */
push(&head, 1);
push(&head, 3);
push(&head, 1);
push(&head, 2);
push(&head, 1);
/* Check the count function */
cout<<"count of nodes is "<< getCount(head);
return 0;
}
Java
// Java program to count number of nodes in a linked list
/* Linked list Node*/
class Node
{
int data;
Node next;
Node(int d) { data = d; next = null; }
}
// Linked List class
class LinkedList
{
Node head; // head of list
/* Inserts a new Node at front of the list. */
public void push(int new_data)
{
/* 1 & 2: Allocate the Node &
Put in the data*/
Node new_node = new Node(new_data);
/* 3. Make next of new Node as head */
new_node.next = head;
/* 4. Move the head to point to new Node */
head = new_node;
}
/* Returns count of nodes in linked list */
public int getCount()
{
Node temp = head;
int count = 0;
while (temp != null)
{
count++;
temp = temp.next;
}
return count;
}
/* Driver program to test above functions. Ideally
this function should be in a separate user class.
It is kept here to keep code compact */
public static void main(String[] args)
{
/* Start with the empty list */
LinkedList llist = new LinkedList();
llist.push(1);
llist.push(3);
llist.push(1);
llist.push(2);
llist.push(1);
System.out.println("Count of nodes is " +
llist.getCount());
}
}
Python
# A complete working Python program to find length of a
# Linked List iteratively
# Node class
class Node:
# Function to initialise the node object
def __init__(self, data):
self.data = data # Assign data
self.next = None # Initialize next as null
# Linked List class contains a Node object
class LinkedList:
# Function to initialize head
def __init__(self):
self.head = None
# This function is in LinkedList class. It inserts
# a new node at the beginning of Linked List.
def push(self, new_data):
# 1 & 2: Allocate the Node &
# Put in the data
new_node = Node(new_data)
# 3. Make next of new Node as head
new_node.next = self.head
# 4. Move the head to point to new Node
self.head = new_node
# This function counts number of nodes in Linked List
# iteratively, given 'node' as starting node.
def getCount(self):
temp = self.head # Initialise temp
count = 0 # Initialise count
# Loop while end of linked list is not reached
while (temp):
count += 1
temp = temp.next
return count
# Code execution starts here
if __name__=='__main__':
llist = LinkedList()
llist.push(1)
llist.push(3)
llist.push(1)
llist.push(2)
llist.push(1)
print ("Count of nodes is :",llist.getCount())
C#
// C# program to count number
// of nodes in a linked list
using System;
/* Linked list Node*/
public class Node
{
public int data;
public Node next;
public Node(int d)
{
data = d; next = null;
}
}
// Linked List class
public class LinkedList
{
Node head; // head of list
/* Inserts a new Node at front of the list. */
public void push(int new_data)
{
/* 1 & 2: Allocate the Node &
Put in the data*/
Node new_node = new Node(new_data);
/* 3. Make next of new Node as head */
new_node.next = head;
/* 4. Move the head to point to new Node */
head = new_node;
}
/* Returns count of nodes in linked list */
public int getCount()
{
Node temp = head;
int count = 0;
while (temp != null)
{
count++;
temp = temp.next;
}
return count;
}
/* Driver program to test above functions. Ideally
this function should be in a separate user class.
It is kept here to keep code compact */
public static void Main()
{
/* Start with the empty list */
LinkedList llist = new LinkedList();
llist.push(1);
llist.push(3);
llist.push(1);
llist.push(2);
llist.push(1);
Console.WriteLine("Count of nodes is " +
llist.getCount());
}
}
Kết quả in ra là:
count of nodes is 5
2. Thuật toán sử dụng đệ quy
Ở bên trong hàm int getCount(head) ta sẽ làm:
1. Nếu head là NULL, return 0 luôn.
2. Nếu không thì return 1 + getCount(head->next) để tiếp tục gọi đến hàm đệ quy để chạy thuật toán
Sau đây sẽ là đoạn code cài đặt cái thuật toán tìm độ dài của linked list sử dụng đệ quy đã nêu ở trên, được viết bằng nhiều ngôn ngữ lập trình:
CODE VÍ DỤ ĐƯỢC VIẾT BẰNG C++/C Java Python C#
C/C++
// Recursive C program to find length or count of nodes in a linked list
#include<stdio.h>
#include<stdlib.h>
/* Link list node */
struct Node
{
int data;
struct Node* next;
};
/* Given a reference (pointer to pointer) to the head
of a list and an int, push a new node on the front
of the list. */
void push(struct Node** head_ref, int new_data)
{
/* allocate node */
struct Node* new_node =
(struct Node*) malloc(sizeof(struct 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;
}
/* Counts the no. of occurrences of a node
(search_for) in a linked list (head)*/
int getCount(struct Node* head)
{
// Base case
if (head == NULL)
return 0;
// count is 1 + count of remaining list
return 1 + getCount(head->next);
}
/* Driver program to test count function*/
int main()
{
/* Start with the empty list */
struct Node* head = NULL;
/* Use push() to construct below list
1->2->1->3->1 */
push(&head, 1);
push(&head, 3);
push(&head, 1);
push(&head, 2);
push(&head, 1);
/* Check the count function */
printf("count of nodes is %d", getCount(head));
return 0;
}
Java
// Recursive Java program to count number of nodes in
// a linked list
/* Linked list Node*/
class Node
{
int data;
Node next;
Node(int d) { data = d; next = null; }
}
// Linked List class
class LinkedList
{
Node head; // head of list
/* Inserts a new Node at front of the list. */
public void push(int new_data)
{
/* 1 & 2: Allocate the Node &
Put in the data*/
Node new_node = new Node(new_data);
/* 3. Make next of new Node as head */
new_node.next = head;
/* 4. Move the head to point to new Node */
head = new_node;
}
/* Returns count of nodes in linked list */
public int getCountRec(Node node)
{
// Base case
if (node == null)
return 0;
// Count is this node plus rest of the list
return 1 + getCountRec(node.next);
}
/* Wrapper over getCountRec() */
public int getCount()
{
return getCountRec(head);
}
/* Driver program to test above functions. Ideally
this function should be in a separate user class.
It is kept here to keep code compact */
public static void main(String[] args)
{
/* Start with the empty list */
LinkedList llist = new LinkedList();
llist.push(1);
llist.push(3);
llist.push(1);
llist.push(2);
llist.push(1);
System.out.println("Count of nodes is " +
llist.getCount());
}
}
Python
# A complete working Python program to find length of a
# Linked List recursively
# Node class
class Node:
# Function to initialise the node object
def __init__(self, data):
self.data = data # Assign data
self.next = None # Initialize next as null
# Linked List class contains a Node object
class LinkedList:
# Function to initialize head
def __init__(self):
self.head = None
# This function is in LinkedList class. It inserts
# a new node at the beginning of Linked List.
def push(self, new_data):
# 1 & 2: Allocate the Node &
# Put in the data
new_node = Node(new_data)
# 3. Make next of new Node as head
new_node.next = self.head
# 4. Move the head to point to new Node
self.head = new_node
# This function counts number of nodes in Linked List
# recursively, given 'node' as starting node.
def getCountRec(self, node):
if (not node): # Base case
return 0
else:
return 1 + self.getCountRec(node.next)
# A wrapper over getCountRec()
def getCount(self):
return self.getCountRec(self.head)
# Code execution starts here
if __name__=='__main__':
llist = LinkedList()
llist.push(1)
llist.push(3)
llist.push(1)
llist.push(2)
llist.push(1)
print 'Count of nodes is :',llist.getCount()
C#
// Recursive C# program to count number of nodes in
// a linked list
using System;
/* Linked list Node*/
public class Node
{
public int data;
public Node next;
public Node(int d)
{
data = d; next = null;
}
}
// Linked List class
public class LinkedList
{
Node head; // head of list
/* Inserts a new Node at front of the list. */
public void push(int new_data)
{
/* 1 & 2: Allocate the Node &
Put in the data*/
Node new_node = new Node(new_data);
/* 3. Make next of new Node as head */
new_node.next = head;
/* 4. Move the head to point to new Node */
head = new_node;
}
/* Returns count of nodes in linked list */
public int getCountRec(Node node)
{
// Base case
if (node == null)
return 0;
// Count is this node plus rest of the list
return 1 + getCountRec(node.next);
}
/* Wrapper over getCountRec() */
public int getCount()
{
return getCountRec(head);
}
/* Driver program to test above functions. Ideally
this function should be in a separate user class.
It is kept here to keep code compact */
public static void Main(String[] args)
{
/* Start with the empty list */
LinkedList llist = new LinkedList();
llist.push(1);
llist.push(3);
llist.push(1);
llist.push(2);
llist.push(1);
Console.WriteLine("Count of nodes is " +
llist.getCount());
}
}
Kết quả in ra là:
count of nodes is 5
Nguồn và Tài liệu tiếng anh tham khảo:
Tài liệu từ cafedev:
- Full series tự học Cấu trúc dữ liệu và giải thuật từ cơ bản tới nâng cao tại đây nha.
- Ebook về Cấu trúc dữ liệu và giải thuật tại đây.
- Các series tự học lập trình khác
Nếu bạn thấy hay và hữu ích, bạn có thể tham gia các kênh sau của cafedev để nhận được nhiều hơn nữa:
Chào thân ái và quyết thắng!