STARTING
CONTROL STATEMENT
FUNCTION
ARRAY & POINTER
OOP
STL
ITERATORS
OTHER FEATURES
CÁC CHỦ ĐỀ
BÀI MỚI NHẤT
MỚI CẬP NHẬT

[STL] So sánh giữa Vector và List trong C++

Khi làm việc với dữ liệu, mình thường cần sử dụng các cấu trúc dữ liệu để lưu trữ và quản lý dữ liệu. Trong STL (Standard Template Library) của C++, std::vectorstd::list là hai cấu trúc dữ liệu phổ biến. Mặc dù cả hai đều cung cấp khả năng lưu trữ dữ liệu, nhưng chúng có những đặc điểm khác nhau về cách thức lưu trữ và hiệu suất. Bài viết này sẽ so sánh giữa std::vectorstd::list trong STL của C++, cung cấp giải thích cho mỗi điểm khác biệt và cung cấp ví dụ minh họa.

test php

banquyen png
Bài viết này được đăng tại freetuts.net, không được copy dưới mọi hình thức.

lam the nao de su dung vector list va map STL png

Vector trong C++

Ưu điểm:

  • Truy cập ngẫu nhiên nhanh chóng: std::vector được triển khai như một mảng liên tục các phần tử, cho phép truy cập ngẫu nhiên vào bất kỳ phần tử nào với thời gian hằng số O(1).
  • Thêm và xóa phần tử ở cuối vector hiệu quả: Thao tác thêm và xóa phần tử ở cuối vector chỉ mất thời gian hằng số O(1).

Nhược điểm:

  • Thêm và xóa phần tử ở vị trí khác không phải cuối vector có thể chậm: Khi thêm hoặc xóa phần tử ở đầu hoặc ở giữa vector, toàn bộ vector phải được sao chép lại, có thể tốn nhiều thời gian O(n).

Ví dụ:

Bài viết này được đăng tại [free tuts .net]

#include <iostream>
#include <vector>

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};

    // Truy cập ngẫu nhiên
    std::cout << "Element at index 2: " << vec[2] << std::endl;
    //freetuts.net

    // Thêm phần tử vào cuối vector
    vec.push_back(6);

    // Xóa phần tử cuối cùng của vector
    vec.pop_back();

    return 0;
}

List trong C++

Ưu điểm:

  • Thêm và xóa phần tử ở bất kỳ vị trí nào hiệu quả: std::list được triển khai dưới dạng danh sách liên kết, cho phép thêm và xóa phần tử ở bất kỳ vị trí nào với thời gian hằng số O(1).
  • Không cần phải di chuyển dữ liệu khi thêm hoặc xóa: Do danh sách liên kết không cần phải di chuyển các phần tử khác khi thêm hoặc xóa, giúp tăng hiệu suất.

Nhược điểm:

  • Truy cập ngẫu nhiên chậm: Việc truy cập phần tử trong std::list yêu cầu phải đi qua từng nút, do đó có độ phức tạp thời gian tuyến tính O(n).

Ví dụ:

#include <iostream>
#include <list>
//freetuts.net

int main() {
    std::list<int> mylist = {1, 2, 3, 4, 5};

    // Thêm phần tử vào đầu danh sách
    mylist.push_front(0);

    // Xóa phần tử ở vị trí thứ 3
    auto it = std::next(mylist.begin(), 2);
    mylist.erase(it);

    return 0;
}

So sánh giữa Vector và List trong C++

Độ phức tạp thời gian và không gian

  • Vector: Thời gian truy cập ngẫu nhiên là O(1), nhưng thêm và xóa phần tử ở vị trí bất kỳ có độ phức tạp là O(n) do cần di chuyển các phần tử. Chiếm không gian liên tục trong bộ nhớ.
  • List: Thời gian truy cập ngẫu nhiên là O(n) do phải đi qua từ đầu đến vị trí cần truy cập. Thêm và xóa phần tử ở bất kỳ vị trí nào có độ phức tạp là O(1) vì không cần di chuyển các phần tử. Chiếm không gian không liên tục trong bộ nhớ vì cần lưu trữ con trỏ.

Tốc độ truy cập và tìm kiếm:

  • Vector có tốc độ truy cập ngẫu nhiên nhanh hơn so với List do dữ liệu được lưu trữ liên tục trong bộ nhớ.
  • Trong trường hợp tìm kiếm, cả Vector và List đều có độ phức tạp O(n) vì phải đi qua từ đầu đến cuối dữ liệu.

Thêm và xóa phần tử:

  • Vector không linh hoạt trong việc thêm và xóa phần tử ở vị trí bất kỳ do độ phức tạp thời gian là O(n).
  • List linh hoạt trong việc thêm và xóa phần tử ở bất kỳ vị trí nào với độ phức tạp thời gian là O(1).

Sử dụng phù hợp của Vector và List

Sử dụng Vector khi:

  • Cần truy cập ngẫu nhiên đến các phần tử.
  • Dữ liệu có kích thước không thay đổi và ít thao tác thêm/xóa.
  • Yêu cầu không gian liên tục trong bộ nhớ.

Sử dụng List khi:

  • Cần thực hiện các thao tác thêm/xóa phần tử thường xuyên ở bất kỳ vị trí nào.
  • Cần tiết kiệm thời gian cho các thao tác thêm/xóa phần tử.
  • Dữ liệu có thể mở rộng và thay đổi kích thước linh hoạt.

Ví dụ:

#include <iostream>
#include <vector>
#include <list>

int main() {
    // Sử dụng Vector
    std::vector<int> vec = {1, 2, 3};
    vec.push_back(4); // Thêm phần tử vào cuối Vector
    vec.erase(vec.begin() + 1); // Xóa phần tử ở vị trí thứ 2 trong Vector
     // bài viết được đăng tại freetuts.net

    // Sử dụng List
    std::list<int> li = {1, 2, 3};
    li.push_back(4); // Thêm phần tử vào cuối List
    li.erase(++li.begin()); // Xóa phần tử ở vị trí thứ 2 trong List

    return 0;
}

Trong ví dụ trên, ta có thể thấy cách sử dụng Vector và List để thêm và xóa phần tử, và sự khác biệt về độ phức tạp thời gian của từng cấu trúc dữ liệu.

Ví dụ thực hành Vector trong C++

Ví dụ về sử dụng Vector trong C++:

#include <iostream>
#include <vector>

int main() {
    // Khai báo và khởi tạo Vector
    std::vector<int> vec = {1, 2, 3, 4, 5};

    // Thêm một phần tử vào cuối Vector
    vec.push_back(6);

    // Truy cập và hiển thị các phần tử trong Vector
    std::cout << "Vector: ";
    for (int i : vec) {
        std::cout << i << " ";
    }
    std::cout << std::endl;
     //Bài viết được đăng tại freetuts.net

    // Xóa phần tử ở vị trí thứ 3 trong Vector
    vec.erase(vec.begin() + 2);

    // Hiển thị Vector sau khi xóa phần tử
    std::cout << "Vector sau khi xoa: ";
    for (int i : vec) {
        std::cout << i << " ";
    }
    std::cout << std::endl;

    return 0;
}

Kết quả:

Screenshot 202024 03 26 20003312 png

Ví dụ về sử dụng List trong C++:

#include <iostream>
#include <list>

int main() {
    // Khai báo và khởi tạo List
    std::list<int> li = {1, 2, 3, 4, 5};

    // Thêm một phần tử vào cuối List
    li.push_back(6);

    // Truy cập và hiển thị các phần tử trong List
    std::cout << "List: ";
    for (int i : li) {
        std::cout << i << " ";
    }
    std::cout << std::endl;
    //Bài viết được đăng tại freetuts.net

    // Xóa phần tử ở vị trí thứ 3 trong List
    auto it = std::next(li.begin(), 2);
    li.erase(it);

    // Hiển thị List sau khi xóa phần tử
    std::cout << "List sau khi xoa: ";
    for (int i : li) {
        std::cout << i << " ";
    }
    std::cout << std::endl;

    return 0;
}

Kết quả:

Screenshot 202024 03 26 20003338 png

Trong các ví dụ trên, ta đã sử dụng Vector và List để thực hiện các thao tác thêm và xóa phần tử. Vector được sử dụng cho các trường hợp cần truy cập ngẫu nhiên và không cần thêm/xóa phần tử nhiều, trong khi List được sử dụng khi cần thêm/xóa phần tử thường xuyên ở bất kỳ vị trí nào.

Kết bài

Trong bài viết này, mình đã tìm hiểu về hai cấu trúc dữ liệu phổ biến trong STL của C++, đó là Vector và List. Chúng ta đã đi vào chi tiết về định nghĩa, tính chất, ưu điểm và nhược điểm của mỗi loại cấu trúc dữ liệu, cũng như so sánh giữa chúng dựa trên các yếu tố như độ phức tạp thời gian, tốc độ truy cập, thêm và xóa phần tử.

Thông qua các ví dụ minh họa, mình đã thấy cách sử dụng Vector và List trong các tình huống khác nhau, từ đó đưa ra quyết định về việc lựa chọn cấu trúc dữ liệu phù hợp cho mỗi bài toán cụ thể.

Tùy thuộc vào yêu cầu và đặc điểm của từng vấn đề, mình có thể lựa chọn sử dụng Vector hoặc List để tối ưu hiệu suất và tiện ích của chương trình. Hi vọng bài viết này đã cung cấp cho bạn cái nhìn tổng quan và chi tiết về sự khác biệt giữa hai cấu trúc dữ liệu quan trọng này trong STL của C++.

Cùng chuyên mục:

Các hàm xử lý ngày tháng (datetime.h) trong C/C++

Các hàm xử lý ngày tháng (datetime.h) trong C/C++

Các hàm xử lý số thực (float.h) trong C/C++

Các hàm xử lý số thực (float.h) trong C/C++

Các hàm xử lý số nguyên lớn (bigint.h) trong C/C++

Các hàm xử lý số nguyên lớn (bigint.h) trong C/C++

Các hàm xử lý thời gian (time.h) trong C

Các hàm xử lý thời gian (time.h) trong C

Các hàm xử lý chuỗi (string.h) trong C/C++

Các hàm xử lý chuỗi (string.h) trong C/C++

Thread Pools và Parallel Algorithms trong C++

Thread Pools và Parallel Algorithms trong C++

Tạo và quản lý các Multithreading trong C++

Tạo và quản lý các Multithreading trong C++

Xử lý ngoại lệ khi làm việc với Memory Allocation trong C++

Xử lý ngoại lệ khi làm việc với Memory Allocation trong C++

Try, Catch, và Throw của Exception Handling trong C++

Try, Catch, và Throw của Exception Handling trong C++

Cách sử dụng Lambda Expressions trong C++

Cách sử dụng Lambda Expressions trong C++

Sử dụng weak_ptr trong C++

Sử dụng weak_ptr trong C++

Sử dụng shared_ptr trong C++

Sử dụng shared_ptr trong C++

Sử dụng unique_ptr trong C++

Sử dụng unique_ptr trong C++

Tổng quan về Smart Pointers trong C++

Tổng quan về Smart Pointers trong C++

Sử dụng Iterators trong STL của C++

Sử dụng Iterators trong STL của C++

[Iterator] Sử dụng Vector trong C++

[Iterator] Sử dụng Vector trong C++

[Iterator] Sử dụng trong List trong C++

[Iterator] Sử dụng trong List trong C++

[STL] Sử dụng Vector trong C++

[STL] Sử dụng Vector trong C++

Tổng quan về Iterators trong C++

Tổng quan về Iterators trong C++

[STL] Các hàm thường dùng của lớp Vector trong C++

[STL] Các hàm thường dùng của lớp Vector trong C++

Top