Đáng ngạc nhiên, điều này hóa ra là quan trọng ngay cả khi quicksort không phải đối mặt với phân vùng hoang dã không cân bằng, và ngay cả khi introsort thực sự đang được sử dụng.
Sự cố phát sinh (trong C++) khi giá trị trong vùng chứa đang được sắp xếp thực sự lớn.Bằng cách này, tôi không có nghĩa là họ chỉ vào những vật thể thực sự to lớn, nhưng họ thực sự rất lớn. Trong trường hợp đó, một số (có thể nhiều) trình biên dịch sẽ làm cho khung stack đệ quy khá lớn, quá, bởi vì nó cần ít nhất một giá trị tạm thời để làm một trao đổi. Hoán đổi được gọi là bên trong phân vùng, mà không phải là đệ quy, vì vậy bạn sẽ nghĩ rằng trình điều khiển đệ quy quicksort sẽ không yêu cầu khung ngăn xếp quái vật; Thật không may, phân vùng thường kết thúc được inlined bởi vì nó đẹp và ngắn, và không được gọi từ bất cứ nơi nào khác.
Thông thường sự khác biệt giữa 20 và 40 khung ngăn xếp là không đáng kể, nhưng nếu giá trị cân nhắc tại, 8kb, thì sự khác biệt giữa 20 và 40 khung ngăn xếp có thể có nghĩa là sự khác biệt giữa công việc và ngăn xếp ngăn xếp, nếu ngăn xếp có được giảm kích thước để cho phép nhiều chủ đề.
Nếu bạn sử dụng thuật toán "luôn luôn chấp nhận vào phân vùng nhỏ hơn", ngăn xếp không được vượt quá các khung N, trong đó N là số phần tử trong vectơ. Hơn nữa, N không thể vượt quá số lượng bộ nhớ có sẵn chia cho kích thước của một phần tử. Vì vậy, trên một máy 32-bit, ở đó chỉ có thể là 2 yếu tố 8KB trong một véc tơ, và độ sâu gọi quicksort không thể vượt quá 19.
Nói tóm lại, viết quicksort làm một cách chính xác sử dụng stack của nó dự đoán (miễn là bạn có thể dự đoán kích thước của một khung ngăn xếp). Không làm phiền với việc tối ưu hóa (để lưu một so sánh đơn!) Có thể dễ dàng làm cho chiều sâu ngăn xếp tăng gấp đôi ngay cả trong trường hợp không bệnh, và trong trường hợp bệnh lý, nó có thể tồi tệ hơn nhiều.
"tại sao tôi nên gọi Quicksort trên mảng con nhỏ hơn trước?" - bởi vì "kết hợp với đệ quy đuôi đảm bảo rằng chiều sâu ngăn xếp là log n" –
@MitchWheat Có, nhưng làm thế nào? – Moeb
Bạn đã đọc từ đâu? – Celeritas