Sắp xếp sử dụng ngăn xếp chỉ đọc


14

Hãy xem xét các cài đặt sau:

  • chúng ta đưa ra một chồng , trong đó có mặt hàng.Sn
  • chúng ta có thể sử dụng số lượng ngăn xếp không đổi .Ôi(1)
  • chúng ta có thể áp dụng các thao tác sau trên các ngăn xếp này:
    1. kiểm tra xem một ngăn xếp có trống không
    2. so sánh các mục hàng đầu của hai ngăn xếp,
    3. xóa mục trên cùng trong ngăn xếp,
    4. in mục trên cùng trong một ngăn xếp,
    5. sao chép mục trên cùng của ngăn xếp vào ngăn xếp khác,
    6. sao chép nội dung của ngăn xếp này sang ngăn xếp khác.

Lưu ý rằng đây là những hoạt động duy nhất được phép. Chúng tôi không thể trao đổi vật phẩm và chúng tôi không được phép đẩy bất kỳ vật phẩm nào lên bất kỳ ngăn xếp nào ngoại trừ việc sao chép vật phẩm trên cùng vào ngăn xếp (sau đó nội dung trước đó của ngăn xếp mục tiêu bị loại bỏ và nó sẽ chỉ chứa vật phẩm được sao chép) .

Đây là một thuật toán để sắp xếp các ngăn xếp với các so sánh :Ôi(n2)

last := empty
for i from 1 to n
  min := empty
  w := s
  while w is not empty
    if w.top > last and w.top < min
      min := w.top
    delete w.top
  print min
  last := min

Chúng ta có thể làm tốt hơn không?

Có chương trình nào in danh sách đã sắp xếp của các mục trong ngăn xếp chỉ bằng cách so sánh không?Ôi(nđăng nhậpn)


2
Nghe có vẻ như các thanh ghi hoạt động như ngăn xếp? Có vẻ như bạn đang nói về hoạt động đẩy và pop. Đó có phải là câu hỏi của bạn? Làm thế nào bạn sẽ sắp xếp một ngăn xếp bằng cách sử dụng một số ngăn xếp và hoạt động ngăn xếp?
sói

2
Với thanh ghi, bạn có thể: chỉ cần đặt mỗi số vào một thanh ghi ( ) và sau đó áp dụng thuật toán sắp xếp thông thường ( ). O ( n ) O ( n lg n )nO(n)O(nlgn)
Kaveh

1
Bạn có muốn sử dụng thanh ghi không? Nếu không, vấn đề tầm thường hóa, như nhận xét của Kaveh. O(1)
Yuval Filmus

1
Không có gì. Tôi nghĩ rằng chúng tôi được cung cấp một số ngăn xếp, không chỉ một, tôi sẽ sửa nó.
Kaveh

2
@akappa, bạn có chắc chắn có thể được sử dụng trong lần xem này không? Chúng tôi không thể giữ bất kỳ kích thước nào bị mất tùy ý lớn hơn 1. Bạn không cần lưu trữ các khối đã sắp xếp?
Kaveh

Câu trả lời:


1

Tôi nghĩ rằng bây giờ tôi có thể chứng minh một giới hạn thấp hơn không cần thiết. Ý tưởng là để thực hiện bất kỳ chương trình như vậy với một nhóm các chương trình phân nhánh so sánh. Giả định 'chỉ đọc' có nghĩa là họ các chương trình phân nhánh của chúng ta sử dụng rất ít, tức là , khoảng trắng. Sau đó, chúng tôi áp dụng ràng buộc thấp hơn được chứng minh bởi Borodin et al. trong "Một sự đánh đổi không gian thời gian để sắp xếp trên các máy không bị lãng quên." Điều này mang lại cho chúng tôi một giới hạn thấp hơn cho thời gian.S T = Ω ( n 2 ) n 2 / log nÔi(đăng nhậpn)ST= =Ω(n2)n2/đăng nhậpn

Chi tiết hơn một chút: Chúng ta có thể phân phối với thao tác 5 ở trên. Nói một cách lỏng lẻo, nếu chúng ta đã có thể so sánh các đầu của hai danh sách và in phần đầu của danh sách, thì chúng ta không cần phải cách ly phần đầu của một danh sách trên một thanh ghi cụ thể. Giả sử điều này, chúng ta thấy rằng mọi thanh ghi trong máy chỉ lưu trữ một chuỗi con cuối cùng của đầu vào.

Giả sử chương trình đăng ký của chúng tôi có dòng mã và thanh ghi k , X 1 , Lọ , X k .kX1,Giáo dục,Xk

Sửa . Chúng tôi xây dựng chương trình phân nhánh so sánh cho các chuỗi có độ dài n như sau. Tạo một nút cho mỗi tuple ( i , d 1 , ... , d k ) nơi 1 i 0 d 1 , ... , d kn . Ý tưởng là, các tính toán trong máy đăng ký tương ứng với các đường dẫn trong chương trình phân nhánh và chúng ta đang ở nút ( i , d 1 , Lỗi , dnn(Tôi,d1,Giáo dục,dk)1Tôi0d1,Giáo dục,dkn nếu chúng ta ở dòng i trong máy đăng ký và độ dài của chuỗi được lưu trong X i d i . Bây giờ, chúng ta phải xác định các cạnh được định hướng của chương trình rẽ nhánh(Tôi,d1,Giáo dục,dk)TôiXTôidTôi

Nếu dòng có dạngTôi

nếu thì goto i 1 khác goto i 2Xbạn<XvTôi1Tôi2

sau đó cho tất cả các , nút ( i , d 1 , HP , d k ) được gắn nhãn bằng cách so sánh phần tử d u -th và d v -th của đầu vào và có cạnh "đúng" ( i 1 , d 1 , Vay , d k ) và cạnh "sai" thành ( i 2 , d 1 , Bắn , d kd1,Giáo dục,dk(Tôi,d1,Giáo dục,dk)dbạndv(Tôi1,d1,Giáo dục,dk) .(Tôi2,d1,Giáo dục,dk)

Nếu dòng có dạngTôi

, goto dòng i 'X1tmộtTôitôi(X2)Tôi'

sau đó có một mũi tên từ bất kỳ nút nào đến ( i , d 2 - 1 , Lỗi , d k ) .(Tôi,d1,Giáo dục,dk)(Tôi',d2-1,Giáo dục,dk)

Nếu dòng có dạngTôi

, goto dòng i 'prTôint(hemộtd(Xbạn))Tôi'

sau đó có một mũi tên từ bất kỳ nút nào đến ( i , d 1 , Rắc , d k ) được gắn nhãn bởi nút d u -th của đầu vào.(Tôi,d1,Giáo dục,dk)(Tôi',d1,Giáo dục,dk)dbạn

Hy vọng những ví dụ này cho thấy rõ tôi dự định xây dựng chương trình rẽ nhánh như thế nào. Khi tất cả được nói và làm, chương trình phân nhánh này có ít nhất nút, vì vậy nó có không gian O ( log n )nkÔi(logn)


0

Bạn có thể đếm các yếu tố? Sau đó, tôi nghĩ rằng, có một triển khai Mergesort khá dễ dàng. Nếu bạn có thể đặt các biểu tượng bổ sung vào ngăn xếp, bạn có thể giải quyết nó bằng 3 ngăn xếp như thế này:

Nếu chúng ta chỉ có một yếu tố, danh sách đã được sắp xếp. Bây giờ giả sử chúng ta đã sắp xếp nửa trên cùng của ngăn xếp. Chúng ta có thể sao chép nửa trên (theo thứ tự ngược lại) vào ngăn xếp thứ hai và đặt biểu tượng phân tách lên trên nó. Bây giờ chúng ta lại có 3 Ngăn xếp (vì chúng ta có thể bỏ qua các biểu tượng đã được sắp xếp bên dưới biểu tượng phân tách) và có thể sắp xếp nửa dưới. Cuối cùng, chúng ta có thể sao chép nửa dưới được sắp xếp vào ngăn xếp thứ ba theo thứ tự ngược lại và hợp nhất cả hai nửa trở lại ngăn xếp ban đầu.

Tất cả các hoạt động đều tốn thời gian tuyến tính, do đó chúng tôi đã sắp xếp danh sách trong Ôi(nđăng nhậpn)

(Lưu ý rằng chúng ta cần ngăn xếp có kích thước vì các ký hiệu phân tách, nhưng điều này có thể dễ dàng sửa bằng cách sử dụng ngăn xếp khác)nđăng nhậpn


Vì bạn không thể đặt các phần tử mới vào ngăn xếp, bạn có thể gặp sự cố tại các điểm phân tách. Để giải quyết điều này, bạn có thể làm như sau với một số ngăn xếp bổ sung:

Sao chép đầu yếu tố để một ngăn xếp bổ sung, sau đó tiến hành với các yếu tố còn lại như trước đây. Bây giờ bạn đã biết chính xác số lượng phần tử bạn cần xem xét trong mỗi bước và do đó không cần bất kỳ ký hiệu phân tách nào.n-2đăng nhậpn

Cuối cùng lặp lại thủ tục với các phần tử bổ sung nhiều nhất là lần và hợp nhất chúng vào ngăn xếp ban đầu trong thời gian tuyến tính. Sắp xếp chi phí ngăn xếp, đối với một số c không đổi , nhiều nhất là c n log n + c nđăng nhậpncthời gian, trong khi hợp nhất sẽ tốn thêm mộtO(nlogn).cnđăng nhậpn+cn2đăng nhậpn2+cn4đăng nhậpn4+ ...= =Ôi(nđăng nhậpn)Ôi(nđăng nhậpn)


Tôi không chắc là tôi hiểu. Ví dụ, làm thế nào chúng ta có thể sao chép nửa trên cùng của ngăn xếp theo thứ tự ngược lại vào ngăn xếp khác khi chúng ta không bao giờ có thể đẩy bất kỳ phần tử nào lên bất kỳ ngăn xếp nào?
Siddharth

Chúng ta không thể đẩy bất kỳ phần tử mới nào vào ngăn xếp, nhưng theo 5 chúng ta có thể đẩy phần tử trên cùng của ngăn xếp này sang ngăn xếp khác. Vì vậy, sao chép ngăn xếp theo thứ tự ngược lại đòi hỏi nhiều nhất là thời gian tuyến tính. Vì vậy, tôi cho rằng, đó không phải là những gì bạn đang yêu cầu?
cero

Bạn không thể đẩy bất cứ thứ gì lên trên các mục khác như được giải thích trong câu hỏi.
Kaveh
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.