hocvietcode.com
  • Trang chủ
  • Học lập trình
    • Lập trình C/C++
    • Lập trình HTML
    • Lập trình Javascript
      • Javascript cơ bản
      • ReactJS framework
      • AngularJS framework
      • Typescript cơ bản
      • Angular
    • Lập trình Mobile
      • Lập Trình Dart Cơ Bản
        • Dart Flutter Framework
    • Cơ sở dữ liệu
      • MySQL – MariaDB
      • Micrsoft SQL Server
      • Extensible Markup Language (XML)
      • JSON
    • Lập trình PHP
      • Lập trình PHP cơ bản
      • Laravel Framework
    • Lập trình Java
      • Java Cơ bản
    • Cấu trúc dữ liệu và giải thuật
    • Lập Trình C# Cơ Bản
    • Machine Learning
  • WORDPRESS
    • WordPress cơ bản
    • WordPress nâng cao
    • Chia sẻ WordPress
  • Kiến thức hệ thống
    • Microsoft Azure
    • Docker
    • Linux
  • Chia sẻ IT
    • Tin học văn phòng
      • Microsoft Word
      • Microsoft Excel
    • Marketing
      • Google Adwords
      • Facebook Ads
      • Kiến thức khác
    • Chia sẻ phần mềm
    • Review công nghệ
    • Công cụ – tiện ích
      • Kiểm tra bàn phím online
      • Kiểm tra webcam online
Đăng nhập
  • Đăng nhập / Đăng ký

Please enter key search to display results.

Home
  • Cấu trúc dữ liệu
  • Cấu trúc dữ liệu và giải thuật
Cấu trúc dữ liệu Mảng (Array)

Cấu trúc dữ liệu Mảng (Array)

  • 16-12-2024
  • Toanngo92
  • 1 Comment

Mục lục

  • Khái niệm Cấu trúc dữ liệu Mảng
    • 1. Định nghĩa
    • 2. Đặc điểm của mảng
    • 3. Cách hoạt động
    • 4. Ưu điểm
    • 5. Nhược điểm
    • 6. Ứng dụng
    • Ví dụ minh họa
  • Phân tích tiệm cận các thao tác với mảng
    • 1. Giả thuyết cơ sở
    • 2. Tìm kiếm phần tử trong mảng
  • Khái niệm Logarit
    • Định nghĩa
    • Các loại logarit thông dụng
    • 3. Thêm phần tử vào mảng
    • 4. Xóa phần tử khỏi mảng
    • 5. Tổng kết thời gian tiệm cận
    • 6. Nhận xét
  • 1. Bản chất của truy cập phần tử qua chỉ số
  • 2. Thời gian thực thi và tiệm cận
  • 3. Tổng kết

Khái niệm Cấu trúc dữ liệu Mảng

1. Định nghĩa

Mảng (Array) là một cấu trúc dữ liệu lưu trữ một tập hợp các phần tử có cùng kiểu dữ liệu, được tổ chức theo thứ tự và nằm liền kề nhau trong bộ nhớ. Mỗi phần tử của mảng được xác định bởi chỉ số (index).

2. Đặc điểm của mảng

  • Kích thước cố định: Số lượng phần tử của mảng được xác định tại thời điểm khai báo và không thể thay đổi trong suốt quá trình thực thi chương trình.
  • Các phần tử có cùng kiểu dữ liệu: Ví dụ, mảng có thể lưu toàn bộ số nguyên, số thực hoặc chuỗi, nhưng không thể lưu lẫn lộn các kiểu dữ liệu.
  • Lưu trữ liên tiếp trong bộ nhớ: Các phần tử của mảng được sắp xếp liền kề, giúp truy cập nhanh thông qua chỉ số.
  • Truy cập trực tiếp (Direct Access): Có thể truy cập phần tử bất kỳ bằng chỉ số mà không cần duyệt qua các phần tử khác.

3. Cách hoạt động

  • Khai báo mảng: Cần xác định kiểu dữ liệu, tên mảng và kích thước của mảng.
    • Ví dụ (C/C++): int arr[5]; // Mảng lưu 5 số nguyên
  • Truy cập phần tử: Sử dụng chỉ số để đọc hoặc ghi giá trị.
    • Ví dụ: arr[0] = 10; // Gán giá trị 10 vào phần tử đầu tiên cout << arr[0]; // In giá trị phần tử đầu tiên (10)

4. Ưu điểm

  • Truy cập nhanh: Nhờ lưu trữ liên tiếp và chỉ số cố định, việc truy cập phần tử diễn ra với thời gian O(1).
  • Dễ sử dụng: Cấu trúc đơn giản, dễ hiểu.

5. Nhược điểm

  • Kích thước cố định: Không thể thay đổi số lượng phần tử sau khi khai báo.
  • Lãng phí bộ nhớ: Nếu khai báo kích thước lớn hơn nhu cầu thực tế, bộ nhớ không được sử dụng hiệu quả.
  • Khó thêm/xóa phần tử: Việc thêm hoặc xóa phần tử đòi hỏi dịch chuyển các phần tử khác trong mảng.

6. Ứng dụng

Mảng thường được sử dụng để:

  • Lưu trữ danh sách dữ liệu cố định như điểm số, tên học sinh.
  • Làm nền tảng cho các cấu trúc dữ liệu phức tạp hơn như danh sách liên kết, hàng đợi, ngăn xếp, bảng băm.

Ví dụ minh họa

Giả sử cần lưu điểm của 5 học sinh:

#include <iostream>
using namespace std;

int main() {
    int scores[5] = {90, 85, 78, 92, 88}; // Mảng lưu 5 điểm số

    // Truy cập và in từng phần tử
    for (int i = 0; i < 5; i++) {
        cout << "Điểm học sinh " << i + 1 << ": " << scores[i] << endl;
    }
    return 0;
}

Kết quả:

Điểm học sinh 1: 90
Điểm học sinh 2: 85
Điểm học sinh 3: 78
Điểm học sinh 4: 92
Điểm học sinh 5: 88

Phân tích tiệm cận các thao tác với mảng

1. Giả thuyết cơ sở

  • Mảng có kích thước nn.
  • Các phần tử được đánh số từ 0 đến n-1.
  • Truy cập và thao tác với mảng dựa trên chỉ số (index).

2. Tìm kiếm phần tử trong mảng

  • Tìm kiếm tuyến tính (Linear Search):
    • Cần duyệt từng phần tử từ đầu đến cuối mảng để kiểm tra điều kiện khớp.
    • Thời gian thực thi:
      • Trường hợp tốt nhất: O(1) (phần tử cần tìm nằm ở vị trí đầu tiên).
      • Trường hợp xấu nhất: O(n) (phần tử cần tìm nằm ở vị trí cuối cùng hoặc không tồn tại).
      • Trường hợp trung bình: O(n), vì trung bình phải duyệt qua n/2 phần tử.
  • Tìm kiếm nhị phân (Binary Search) (áp dụng cho mảng đã sắp xếp):
    • Mỗi lần chia đôi mảng, kiểm tra giá trị giữa để quyết định hướng tìm kiếm.
    • Thời gian thực thi:
      • Trường hợp tốt nhất: O(1) (phần tử ở giữa ngay từ đầu).
      • Trường hợp xấu nhất: O(log⁡n), do mảng bị chia đôi lặp đi lặp lại.
      • Trường hợp trung bình: O(log⁡n).

Giải thích lý do thuật toán O(log n) khi chia 2 lần:

Khái niệm Logarit

Logarit là một khái niệm toán học dùng để giải quyết các bài toán liên quan đến lũy thừa. Cụ thể, logarit là phép toán ngược của phép nâng lũy thừa.

Định nghĩa

Cho hai số thực a > 0 và b > 0 sao cho a!= 0, logarit cơ số a của b là số thực x sao cho:

a ^ x  = b

Ta có

log(a)b = x

Ví dụ:

log(2) 8 = 3
log(10) 100 = 10

Các loại logarit thông dụng

  1. Logarit thập phân (logarit cơ số 10):
    Ký hiệu: log(b) (thường bỏ cơ số nếu là 10).
    Ví dụ: log(100) =2.
  2. Logarit tự nhiên (logarit cơ số e):
    Ký hiệu: lb(b) với e xấp xỉ = 2.718
    Ví dụ: ln(e) = 1

Trong phân tích tiệm cận, chia đôi nhiều lần thường dẫn đến độ phức tạp O(log n) vì số lần thực hiện chia đôi phụ thuộc vào logarit cơ số 2 của kích thước bài toán. Điều này xuất phát từ cách logarit mô tả sự giảm dần theo lũy thừa.

Nếu bắt đầu với kích thước n, số lần chia đôi cần thiết để đạt kích thước 1 là số k sao cho:

Do đó, số bước chia đôi tỷ lệ với log(2)n.

Theo tính chất của logarit, Logarit cơ số khác nhau có thể chuyển đổi lẫn nhau thông qua công thức đổi cơ số:

Ví dụ:

Như vậy, log⁡(2)n, log(⁡10)n, hay ln⁡(n) (logarit tự nhiên) chỉ khác nhau bởi một hằng số nhân.

rong ký hiệu O lớn (Big-O), chúng ta chỉ quan tâm đến tốc độ tăng trưởng (growth rate) của hàm khi nnn tiến tới vô hạn. Các hằng số nhân không ảnh hưởng đến bậc độ phức tạp, vì chúng không làm thay đổi bản chất của hàm khi nnn lớn.

  • Vì log(2)n, log(10)​n, hay ln⁡(n) chỉ khác nhau bởi hằng số, chúng đều thuộc cùng một lớp độ phức tạp O(log n).

3. Thêm phần tử vào mảng

  • Mảng có kích thước cố định:
    • Nếu mảng đã đầy, không thể thêm phần tử.
    • Nếu còn chỗ, cần xác định vị trí thêm phần tử:
      • Cuối mảng: Không cần dịch chuyển phần tử, thời gian O(1).
      • Giữa hoặc đầu mảng: Phải dịch chuyển tất cả các phần tử sau vị trí thêm, thời gian O(n)O(n) trong trường hợp xấu nhất.
  • Mảng có kích thước động (sử dụng cấp phát bộ nhớ động):
    • Khi mảng đầy, phải tạo một mảng mới lớn hơn, sao chép dữ liệu cũ sang mảng mới:
      • Thời gian sao chép: O(n).
      • Sau đó, thêm phần tử vào mảng mới: O(1).
      • Tổng thời gian: O(n) khi mảng đầy, O(1) khi chưa đầy.

4. Xóa phần tử khỏi mảng

  • Mảng có kích thước cố định:
    • Sau khi xóa, các phần tử phía sau vị trí xóa phải được dịch chuyển lên để lấp khoảng trống.
    • Thời gian thực thi:
      • Trường hợp tốt nhất: O(1) (xóa phần tử cuối, không cần dịch chuyển).
      • Trường hợp xấu nhất: O(n) (xóa phần tử đầu, tất cả các phần tử phải dịch chuyển).
  • Mảng động:
    • Nếu không yêu cầu giữ thứ tự, có thể thay phần tử cần xóa bằng phần tử cuối cùng và giảm kích thước mảng, thời gian O(1).
    • Nếu cần giữ thứ tự, phải dịch chuyển phần tử như mảng cố định, thời gian O(n).

5. Tổng kết thời gian tiệm cận

Thao tácTốt nhấtTrung bìnhXấu nhất
Tìm kiếm tuyến tínhO(1)O(n)O(n)
Tìm kiếm nhị phânO(1)O(log⁡n)O(log⁡n)
Thêm (cuối)O(1)O(1)O(1)
Thêm (giữa hoặc đầu)O(1)O(n)O(n)
Xóa (cuối)O(1)O(1)O(1)
Xóa (giữa hoặc đầu)O(1)O(n)O(n)

6. Nhận xét

  • Mảng cung cấp thời gian truy cập O(1), nhưng các thao tác thêm và xóa (ở giữa hoặc đầu) có thời gian xấu nhất là O(n).
  • Tối ưu hoá thao tác thêm/xóa thường cần các cấu trúc khác như danh sách liên kết hoặc vector động (trong C++).

1. Bản chất của truy cập phần tử qua chỉ số

Khi mảng được tạo ra, các phần tử của nó được lưu trữ liên tiếp trong bộ nhớ. Địa chỉ bộ nhớ của phần tử thứ i trong mảng được tính bằng công thức:

i * Base Address + i * (Kích thước phần tử)
  • Địa chỉ cơ sở: Là địa chỉ của phần tử đầu tiên (A[0]).
  • Kích thước phần tử: Phụ thuộc vào kiểu dữ liệu (ví dụ: int thường chiếm 4 byte).
  • Do mảng được lưu trữ liên tiếp, máy tính chỉ cần một phép tính toán học đơn giản để xác định địa chỉ của phần tử và truy xuất giá trị.

2. Thời gian thực thi và tiệm cận

Truy cập phần tử qua chỉ số là một thao tác hằng thời gian.

Thời gian thực thi: O(1) (thời gian không phụ thuộc vào kích thước của mảng nn).

Phân tích toán học:

Máy tính thực hiện các bước:

  1. Lấy địa chỉ cơ sở (A[0]).
  2. Tính địa chỉ phần tử i: i * Base Address + i * (Kích thước phần tử)
  3. Đọc giá trị tại địa chỉ vừa tính.
  4. Tất cả các bước trên đều thực hiện trong thời gian cố định, không phụ thuộc vào n.

3. Tổng kết

Thao tácThời gian tốt nhấtThời gian trung bìnhThời gian xấu nhất
Truy cập phần tửO(1)O(1)O(1)
  • Lý do thời gian là O(1):
    • Mảng lưu trữ liên tiếp, chỉ cần một phép tính toán đơn giản để xác định địa chỉ, không cần duyệt qua bất kỳ phần tử nào khác.
  • Kết luận: Truy cập phần tử bằng chỉ số trong mảng là một trong những thao tác hiệu quả nhất về mặt thời gian.

Bài viết liên quan:

Cấu trúc dữ liệu danh sách liên kết (LinkedList)
Giới thiệu về thuật toán
Định lý thợ (Master Theorem)
Giải thuật Qui hoạch động (Dynamic Programming) 
Giải thuật chia để trị (Divide and Conquer)
Phân tích tiệm cận trong CTDL và giải thuật
Giải thuật tham lam (Greedy Algorithm)
Đệ quy trong lập trình
Thuật toán tìm kiếm nhảy – Jump Search
Thuật toán tìm kiếm nhị phân – binary search
Thuật toán tìm kiếm tuần tự – linear search
Sắp xếp trộn – Merge Sort

1 Comments

  1. Pingback: Cấu trúc dữ liệu Mảng (Array) – Blog nghiên cứu về lập trình, viết mã

THÊM BÌNH LUẬN Cancel reply

Dịch vụ thiết kế Wesbite

NỘI DUNG MỚI CẬP NHẬT

2. PHÂN TÍCH VÀ ĐẶC TẢ HỆ THỐNG

3. THIẾT KẾ HỆ THỐNG

1. TỔNG QUAN KIẾN THỨC THỰC HÀNH TRIỂN KHAI DỰ ÁN CÔNG NGHỆ THÔNG TIN

Hướng dẫn tự cài đặt n8n comunity trên CyberPanel, trỏ tên miền

Mẫu prompt tạo mô tả chi tiết bối cảnh

Giới thiệu

hocvietcode.com là website chia sẻ và cập nhật tin tức công nghệ, chia sẻ kiến thức, kỹ năng. Chúng tôi rất cảm ơn và mong muốn nhận được nhiều phản hồi để có thể phục vụ quý bạn đọc tốt hơn !

Liên hệ quảng cáo: [email protected]

Kết nối với HỌC VIẾT CODE

© hocvietcode.com - Tech888 Co .Ltd since 2019

Đăng nhập

Trở thành một phần của cộng đồng của chúng tôi!
Registration complete. Please check your email.
Đăng nhập bằng google
Đăng kýBạn quên mật khẩu?

Create an account

Welcome! Register for an account
The user name or email address is not correct.
Registration confirmation will be emailed to you.
Log in Lost your password?

Reset password

Recover your password
Password reset email has been sent.
The email could not be sent. Possible reason: your host may have disabled the mail function.
A password will be e-mailed to you.
Log in Register
×