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.

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:

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!

Đăng ký kênh youtube để ủng hộ Cafedev nha các bạn, Thanks you!