Thêm các phần tử vào một mảng được sắp xếp


31

Điều gì sẽ là cách nhanh nhất để làm điều này (từ góc độ thuật toán, cũng như một vấn đề thực tế)?

Tôi đã suy nghĩ một cái gì đó dọc theo dòng sau.

Tôi có thể thêm vào cuối một mảng và sau đó sử dụng bubbleort vì nó có trường hợp tốt nhất (mảng được sắp xếp hoàn toàn khi bắt đầu) gần với điều này và có thời gian chạy tuyến tính (trong trường hợp tốt nhất).

Mặt khác, nếu tôi biết rằng tôi bắt đầu với một mảng được sắp xếp, tôi có thể sử dụng tìm kiếm nhị phân để tìm ra điểm chèn cho một phần tử đã cho.

Linh cảm của tôi là cách thứ hai gần như tối ưu, nhưng tò mò muốn xem những gì ngoài kia.

Làm thế nào điều này có thể được thực hiện tốt nhất?


1
Cách nhanh nhất, nếu bạn phải làm điều đó thường xuyên, là không sử dụng một mảng ở vị trí đầu tiên.
Revierpost

Tự cân bằng cây nhị phân?
soandos

Vâng, có thể; xem câu trả lời ...
rebierpost

Câu trả lời:


25

Chúng tôi đếm số phần tử mảng đọc và ghi. Để làm bong bóng sắp xếp, bạn cần truy cập (write ban đầu để cuối cùng, sau đó, trong trường hợp xấu nhất, hai đọc và hai viết để làm giao dịch hoán đổi). Để thực hiện tìm kiếm nhị phân, chúng ta cần ( cho tìm kiếm nhị phân, sau đó, trong trường hợp xấu nhất, để chuyển các phần tử mảng sang phải, sau đó 1 để viết phần tử mảng sang vị trí thích hợp của nó).n 2 log n + 2 n + 1 2 log n 2 n1+4nn2đăng nhậpn+2n+12đăng nhậpn2n

Vì vậy, cả hai phương thức đều có cùng độ phức tạp đối với việc triển khai mảng, nhưng phương thức tìm kiếm nhị phân yêu cầu ít truy cập mảng hơn trong thời gian dài ... không có triệu chứng, bằng một nửa. Có những yếu tố khác khi chơi, một cách tự nhiên.

Trên thực tế, bạn có thể sử dụng các triển khai tốt hơn và chỉ tính các truy cập mảng thực tế (không truy cập vào phần tử được chèn). Bạn có thể thực hiện cho sắp xếp bong bóng và cho tìm kiếm nhị phân ... vì vậy, nếu truy cập đăng ký / bộ đệm rẻ và truy cập mảng thì tốn kém, tìm kiếm từ cuối và dịch chuyển dọc (bong bóng thông minh hơn sắp xếp để chèn) có thể tốt hơn, mặc dù không có triệu chứng như vậy.log n + 2 n + 12n+1đăng nhậpn+2n+1

Một giải pháp tốt hơn có thể liên quan đến việc sử dụng một cấu trúc dữ liệu khác nhau. Mảng cung cấp cho bạn quyền truy cập O (1) (truy cập ngẫu nhiên), nhưng việc chèn và xóa có thể phải trả giá. Một bảng băm có thể có chèn (xóa) O (1), truy cập sẽ có giá. Các tùy chọn khác bao gồm BST và đống, v.v. Có thể đáng để xem xét nhu cầu sử dụng của ứng dụng của bạn để chèn, xóa và truy cập và chọn cấu trúc chuyên biệt hơn.

Cũng lưu ý rằng nếu bạn muốn thêm phần tử vào một mảng phần tử được sắp xếp , một ý tưởng tốt có thể là sắp xếp hiệu quả các mục , sau đó hợp nhất hai mảng; Ngoài ra, các mảng được sắp xếp có thể được xây dựng một cách hiệu quả bằng cách sử dụng heaps (heap sort).n mmnm


1
"Một bảng băm có thể có chèn (xóa) O (1)" - thường được khấu hao.
Raphael

8
Khấu hao dự kiến .
JeffE

BST có để tìm kiếm và chèn (wikipedia), vậy tại sao nó không được lựa chọn hàng đầu ở đây? để tìm kiếm và chèn. O ( 2 l o g n )Ôi(tôiog n)Ôi(2 tôiog n)
Kashyap

8

Nếu bạn có bất kỳ lý do nào cho việc không sử dụng heap, hãy xem xét sử dụng Sắp xếp chèn thay vì Sắp xếp bong bóng. Sẽ tốt hơn khi bạn có một vài yếu tố chưa được sắp xếp.


8

Ôi(n)

Ôi(lgn)Ôi(n+lgn)Ôi(n)

Ôi(1)

Dù sao, tôi không thấy bất kỳ lý do nào để loại bỏ bong bóng cho vấn đề này.


2
Ôi

+1 vì bị bắt nạt .. :-)
Kashyap

4

Patrick87 giải thích tất cả điều này rất tốt. Nhưng một tối ưu hóa bổ sung mà bạn có thể thực hiện sẽ là sử dụng một cái gì đó như bộ đệm tròn: bạn có thể di chuyển các mục bên phải vị trí của phần tử được chèn sang bên phải, như thường lệ. Nhưng bạn cũng có thể di chuyển các mục ở bên trái của vị trí chính xác sang bên trái. Để làm điều này, bạn cần coi mảng là hình tròn, tức là mục cuối cùng nằm ngay trước mục đầu tiên và nó cũng yêu cầu bạn giữ chỉ mục nơi các mục hiện đang bắt đầu.

Nếu bạn làm điều này, điều đó có thể có nghĩa là bạn thực hiện khoảng một nửa số lượt truy cập mảng (giả sử phân phối thống nhất các chỉ mục bạn chèn vào). Trong trường hợp thực hiện tìm kiếm nhị phân để tìm vị trí, việc chọn chuyển sang trái hay phải là điều không quan trọng. Trong trường hợp sắp xếp bong bóng, bạn cần phải đoán chính xác trước khi bắt đầu. Nhưng làm điều đó rất đơn giản: chỉ cần so sánh mục được chèn với trung vị của mảng, có thể được thực hiện trong truy cập mảng đơn.


4

Tôi đã sử dụng thuật toán sắp xếp chèn hiệu quả cho vấn đề này. Trong một lần chúng tôi gặp vấn đề về hiệu năng với một đối tượng bảng băm, tôi đã viết một đối tượng mới sử dụng tìm kiếm nhị phân thay vào đó làm tăng hiệu suất đáng kể. Để giữ danh sách được sắp xếp, nó sẽ theo dõi số lượng mục được thêm vào kể từ lần sắp xếp cuối cùng (nghĩa là số mục chưa được sắp xếp), khi danh sách cần được sắp xếp do yêu cầu tìm kiếm, nó đã thực hiện sắp xếp chèn hoặc sắp xếp nhanh tùy thuộc trên tỷ lệ phần trăm của các mặt hàng chưa được sắp xếp. Sử dụng loại chèn là chìa khóa trong việc cải thiện hiệu suất.


Bạn có một kết quả chính thức về chi phí hoạt động khấu hao? Và chào mừng!
Raphael
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.