Làm thế nào để thực hiện hai ngăn xếp trong một mảng?


15

Tôi muốn bắt đầu bằng cách nói rằng đây KHÔNG phải là một câu hỏi bài tập về nhà. Tôi đang đọc Giới thiệu về Thuật toán - văn bản CLRS nổi tiếng để trở thành một lập trình viên tốt hơn. Tôi đang cố gắng tự mình giải quyết các vấn đề và bài tập được đưa ra trong cuốn sách.

Tôi đang cố gắng giải quyết Excercise 10.1-2 từ Chương 10 Cấu trúc dữ liệu cơ bản từ CLRS Phiên bản thứ hai. Đây là những gì trạng thái của nó:

Giải thích cách thực hiện hai ngăn xếp trong một mảng A [1..n] theo cách sao cho ngăn xếp không bị tràn trừ khi tổng số phần tử trong cả hai ngăn xếp là n . Các hoạt động PUSH và POP sẽ chạy trong thời gian O (1) .

Giải pháp mà tôi đã đưa ra cho đến nay là:

Đặt mảng A [1..n] thực hiện hai ngăn xếp: S1 [1..i]S2 [i..n] .

Đối với các hoạt động PUSH-S1PUSH-S2 , nếu ngăn xếp 'đầy' thì bắt đầu đẩy các phần tử sang ngăn xếp khác (ví dụ: nếu ngăn xếp S1 đầy khi một phần tử mới đang cố gắng được đẩy vào, sau đó đẩy phần tử đó vào chồng S2 và ngược lại).

Vấn đề với cách tiếp cận này là tôi sẽ không thể tin cậy vào POP-S1 hoặc POP-S2 vì không có cách nào để 'nhớ' phần tử nào thuộc về ngăn xếp nào. Nếu các phần tử của ngăn xếp là cặp (khóa, giá trị) , thì khóa là số ngăn xếp, sau đó để bật một phần tử tôi sẽ phải tìm kiếm, trong trường hợp xấu nhất, i hoặc (ni) lần - sẽ là O (n ) (vui lòng sửa tôi nếu tôi sai ở đây), đó không phải là O (1) .

Tôi đã đập đầu vào câu hỏi khá lâu rồi. Có phải tôi đang trên đường ray bên phải không? Ai đó có thể cho tôi gợi ý có thể để giải quyết vấn đề này?

Nói chung, tôi nên 'nghĩ' về những vấn đề này như thế nào? Hay chỉ những người thực sự thông minh mới có thể giải quyết những loại vấn đề này? Liệu việc giải quyết / giải quyết các vấn đề như thế này (tức là tích lũy kinh nghiệm) sẽ giúp tôi trở nên tốt hơn trong việc này?

Tôi chờ đợi sự giác ngộ.


3
"Việc giải quyết / giải quyết các vấn đề như thế này (tức là tích lũy kinh nghiệm) có giúp tôi trở nên tốt hơn trong việc này không?" Theo kinh nghiệm của tôi, đây chắc chắn là trường hợp. Nếu không có gì khác, bạn sẽ suy nghĩ theo nhiều cách về vấn đề, và bằng cách đó một mình phát triển cái nhìn sâu sắc hơn. Như tôi đã nói gần đây: cách tốt nhất để có những ý tưởng hay là có nhiều ý tưởng.
G. Bạch

Câu trả lời:


7

Một gợi ý khác ngoài những gì Yuval nói: nó giúp đặt các ngăn xếp theo một cách cụ thể trong các mảng khắc phục hướng phát triển của chúng cho phù hợp. Họ không phải phát triển theo cùng một hướng.


5

Dưới đây là một số gợi ý:

  1. Một trong các ngăn xếp sẽ phát triển "lên" và "ngăn xếp" khác.
  2. Không có cách nào để 'nhớ' phần tử nào thuộc về ngăn xếp nào - bạn được phép sử dụng các biến bổ sung để giúp bạn với những thứ như thế. (Điều này có ý nghĩa hơn với giải pháp được đề xuất bởi gợi ý đầu tiên.)

1

Ngăn xếp thứ nhất bắt đầu từ 1 và lớn dần về phía n, trong khi ngăn thứ hai bắt đầu từ n và tăng dần về phía 1. Quá trình tràn ngăn xếp xảy ra khi một phần tử được đẩy khi hai con trỏ ngăn xếp liền kề nhau.


1

Phương pháp này sử dụng hiệu quả không gian có sẵn. Nó không gây ra tràn nếu có khoảng trống trong mảng []. Ý tưởng là bắt đầu hai ngăn xếp từ hai góc cực của mảng []. stack1 bắt đầu từ phần tử ngoài cùng bên trái, phần tử đầu tiên trong stack1 được đẩy ở chỉ số 0. Stack2 bắt đầu từ góc ngoài cùng bên phải, phần tử đầu tiên trong stack2 được đẩy tại index (n-1). Cả hai ngăn xếp phát triển (hoặc co lại) theo hướng ngược lại. Để kiểm tra tràn, tất cả những gì chúng ta cần kiểm tra là khoảng trống giữa các phần tử trên cùng của cả hai ngăn xếp.


-1

Tôi nghĩ đến một giải pháp khác. Nếu chúng ta chia mảng thành một nửa (hoặc càng gần càng tốt nếu mảng có độ dài lẻ) và làm cho phần tử đầu tiên đi vào ngăn xếp thứ nhất và phần tử thứ hai đi vào ngăn xếp thứ hai. Trong khi popping chúng tôi có thể lấy lại các bước này. Tuy nhiên, bằng cách thực hiện theo cách này, nó sẽ vi phạm bất kỳ nguyên tắc ngăn xếp nào?


NNN/2

-2

Một số gợi ý

Tạo một mảng

Các phần tử mảng có chỉ số lẻ là cho stack1

Các phần tử mảng có chỉ mục chẵn là cho stack2

Bây giờ bạn có thể phát triển cả hai ngăn xếp từ trái sang phải

Chỉ cần giữ các biến duy trì vị trí hàng đầu của cả hai ngăn xếp. Bạn sẽ không phải tìm kiếm mảng.

và nếu stack1 trở nên đầy trong khi stack2 trống, bạn có thể theo dõi các phần tử stack1 bổ sung trong stack2 bằng cách duy trì một số biến


Điều này là rất phức tạp. Các câu trả lời hiện có đã đưa ra những cách đơn giản hơn để giải quyết vấn đề
David Richerby
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.