Sự khác biệt giữa một mảng và một ngăn xếp là gì?


10

Theo Wikipedia, một ngăn xếp :

là kiểu dữ liệu trừu tượng cuối cùng, trước hết (LIFO) và cấu trúc dữ liệu tuyến tính.

Trong khi một mảng :

là một cấu trúc dữ liệu bao gồm một tập hợp các phần tử (giá trị hoặc biến), mỗi phần được xác định bởi ít nhất một chỉ mục mảng hoặc khóa.

Theo tôi hiểu, chúng khá giống nhau. Vì vậy, sự khác biệt chính là gì? Nếu chúng không giống nhau, một mảng có thể làm gì mà một ngăn xếp không thể và ngược lại?


5
Làm thế nào là câu hỏi của bạn không được trả lời bởi những gì bạn tìm thấy trong Wikipedia? Bạn có thể truy cập các phần tử của một mảng theo bất kỳ thứ tự nào; một ngăn xếp phải được truy cập theo thứ tự LIFO.
Caleb

8
@Caleb Chỉ vì bạn đọc một cái gì đó không có nghĩa là bạn hiểu khái niệm này. Trong tâm trí của tôi, tôi đã không hoàn toàn hiểu điều này cho đến khi tôi hỏi.
Năng động

3
-1 Về cơ bản, bạn đã đăng câu trả lời trong câu hỏi của riêng bạn. Bạn đang hỏi cái gì vậy?
Andres F.

1
@AresresF. Tôi không thể hiểu điều đó có nghĩa là gì ... Nếu bạn có thể xem một bài viết trên Wikipedia và hiểu những gì họ nói lần đầu tiên, thế giới sẽ trở nên hoàn hảo.
Năng động

2
Tôi vừa đọc meta.programers và hiểu lý do tại sao bạn hỏi câu hỏi không phải câu hỏi này: đó là cho một cuộc thi. Tôi thực sự nghi ngờ bạn không hiểu bài viết Wikipedia. Xấu hổ về bạn: /
Andres F.

Câu trả lời:


45

Vâng, bạn chắc chắn có thể thực hiện một ngăn xếp với một mảng. Sự khác biệt là trong truy cập. Trong một mảng, bạn có một danh sách các yếu tố và bạn có thể truy cập bất kỳ trong số chúng bất cứ lúc nào. (Hãy nghĩ về một loạt các khối gỗ được đặt trong một hàng.)

Nhưng trong một ngăn xếp, không có hoạt động truy cập ngẫu nhiên; chỉ có Push, PeekPop, tất cả trong số đó chỉ xử lý phần tử trên đỉnh của ngăn xếp. (Hãy nghĩ về các khối gỗ xếp chồng lên nhau theo chiều dọc. Bạn không thể chạm vào bất cứ thứ gì bên dưới đỉnh tháp hoặc nó sẽ rơi xuống.)


11
khối gỗ - tương tự tốt đẹp
Jesse Black

1
Bạn nói "trong một ngăn xếp, không có thao tác truy cập ngẫu nhiên" nhưng tôi không đồng ý và sẽ thêm chi tiết vào câu trả lời của tôi.
Scott Whitlock

ngăn xếp chắc chắn được thực hiện với quyền truy cập ngẫu nhiên
old_timer

4
Bạn phải hút tại Jenga.
DisgruntledGoat

1
@Mason, tôi biết. Đó là một trò đùa.
DisgruntledGoat

6

Trong một chồng thuần túy, chỉ hoạt động cho phép là Push, PopPeeknhưng trong thực tế, đó không phải là hoàn toàn chính xác. Hay đúng hơn, Peekthao tác thường cho phép bạn nhìn vào bất kỳ vị trí nào trên ngăn xếp, nhưng điều thú vị là nó liên quan đến một đầu của ngăn xếp.

Vì vậy, như những người khác đã nói, một mảng là truy cập ngẫu nhiên và mọi thứ đều được tham chiếu đến phần đầu của mảng .

Trong ngăn xếp, bạn chỉ có thể thêm / xóa ở cuối hoạt động của ngăn xếp, nhưng bạn vẫn có quyền truy cập ngẫu nhiên đọc nhưng nó được tham chiếu đến kết thúc làm việc . Đó là sự khác biệt cơ bản.

Chẳng hạn, khi bạn truyền tham số trên ngăn xếp cho hàm, callee không cần phải tắt tham số để xem chúng. Nó chỉ đẩy các biến cục bộ trên ngăn xếp và tham chiếu tất cả các biến và tham số cục bộ dựa trên phần bù từ con trỏ ngăn xếp. Nếu bạn đang sử dụng chỉ một mảng, thì làm thế nào callee biết nơi để tìm các tham số của nó? Khi callee được thực hiện, nó bật ra các biến cục bộ của nó, đẩy giá trị trả về, trả lại quyền điều khiển cho người gọi và người gọi bật giá trị trả về (nếu có), sau đó bật các tham số ra khỏi ngăn xếp. Cái hay ở đây là nó hoạt động cho dù bạn có lồng vào các lệnh gọi của bạn bao xa (giả sử bạn không hết dung lượng ngăn xếp).

Đó là một cách sử dụng / triển khai cụ thể, nhưng nó minh họa cho sự khác biệt: mảng luôn được tham chiếu từ đầu nhưng ngăn xếp luôn được tham chiếu từ một số vị trí kết thúc làm việc.

Một triển khai có thể có của ngăn xếp là một mảng cộng với một chỉ mục để ghi nhớ nơi kết thúc làm việc.


Đối với tôi đây là câu trả lời. Câu hỏi về sự khác biệt giữa một mảng và một ngăn xếp là tại sao chúng ta cần ngăn xếp khi mảng có vẻ ít ràng buộc hơn và linh hoạt hơn. Và điều này trả lời nó: chính xác là vì stack bị hạn chế hơn khi sử dụng nó trong các trường hợp phù hợp (ví dụ như các hàm gọi ở đây) làm cho việc triển khai hợp lý. Henco "người đẹp"
Todanley

4

Tôi nghĩ rằng sự nhầm lẫn lớn nhất đang diễn ra ở đây là việc thực hiện so với các cấu trúc dữ liệu cơ bản.

Trong hầu hết (các ngôn ngữ cơ bản hơn), một mảng biểu thị một tập hợp các phần tử có độ dài cố định mà bạn có thể truy cập bất kỳ tại một thời điểm nhất định. Thực tế là bạn có một loạt các yếu tố như thế này không cho bạn biết gì về cách sử dụng nó (và thật lòng mà nói, một máy tính sẽ không biết / quan tâm đến cách bạn sử dụng nó, miễn là bạn không vi phạm việc sử dụng).

Một ngăn xếp là một sự trừu tượng được sử dụng để thể hiện dữ liệu cần được xử lý theo một cách nhất định. Đây là một khái niệm trừu tượng bởi vì nó chỉ nói rằng nó phải có một số chương trình con / phương thức / hàm có thể thêm vào đầu hoặc xóa khỏi đầu, trong khi dữ liệu bên dưới đỉnh không bị chạm vào. Hoàn toàn là sự lựa chọn của bạn để sử dụng một mảng theo cách này.

Bạn có thể tạo một ngăn xếp từ nhiều loại cấu trúc dữ liệu khác nhau: mảng (với một số kích thước tối đa), mảng động (có thể phát triển khi hết dung lượng) hoặc danh sách được liên kết. Cá nhân tôi cảm thấy rằng một danh sách được liên kết đại diện cho các hạn chế của ngăn xếp là tốt nhất vì bạn phải nỗ lực một chút để thấy mọi thứ nằm ngoài yếu tố đầu tiên và rất dễ dàng để thêm vào phía trước và loại bỏ từ phía trước.

Vì vậy, bạn có thể sử dụng một mảng để KIẾM một ngăn xếp, nhưng chúng không tương đương


3

Trách nhiệm của họ là khác nhau:

  • Ngăn xếp phải có khả năng bật các phần tử lên ngăn xếp và đẩy các phần tử từ ngăn xếp, do đó tại sao nó thường có các phương thức Pop()Push()

  • Trách nhiệm của mảng là lấy / đặt phần tử tại một chỉ mục được chỉ định


3

Bạn có thể truy xuất một mục từ bất kỳ chỉ mục nào của mảng A \.

Với ngăn xếp, bạn có thể truy xuất một mục ở giữa ngăn A, bằng cách sử dụng ngăn xếp khác: B.

Bạn tiếp tục lấy vật phẩm trên cùng ra khỏi A và đặt nó vào B cho đến khi bạn ở vật phẩm mong muốn của A, sau đó bạn đặt vật phẩm từ B trở lại trên đỉnh A.

Vì vậy, đối với dữ liệu yêu cầu khả năng truy xuất một chỉ mục tùy ý, ngăn xếp sẽ khó thực hiện hơn.

Trong trường hợp bạn muốn hành vi "vào trước, ra trước", một ngăn xếp sẽ cung cấp cho bạn ít chi phí hơn một mảng.


0

Tôi sẽ không đi xa để nói rằng họ "rất giống nhau."

Một mảng được sử dụng để giữ những thứ mà sau này sẽ được truy cập tuần tự hoặc thông qua chỉ mục. Cấu trúc dữ liệu không ngụ ý bất kỳ loại phương thức truy cập nào (FIFO, LIFO, FILO, v.v.) nhưng nó có thể được sử dụng theo cách đó nếu bạn muốn.

Một ngăn xếp là cách theo dõi mọi thứ khi chúng được tạo ra. Một phương thức truy cập được ngụ ý / yêu cầu tùy thuộc vào loại ngăn xếp được tạo. Một ngăn xếp khung sẽ là một ví dụ LIFO. Tuyên bố miễn trừ trách nhiệm - Tôi có thể trộn lẫn phân loại cấu trúc dữ liệu của mình ở đây và một ngăn xếp có thể thực sự chỉ cho phép LIFO. Nó sẽ là một loại hàng đợi khác.

Vì vậy, tôi có thể sử dụng một mảng như một ngăn xếp (mặc dù tôi không muốn) nhưng tôi không thể sử dụng một ngăn xếp như một mảng (trừ khi tôi làm việc rất chăm chỉ với nó).


1
Trong miền 'cấu trúc để lưu trữ các bộ sưu tập các đối tượng', tôi sẽ không nói rằng chúng rất giống nhau. Trong lĩnh vực khái niệm lập trình, tôi muốn nói rằng chúng khá giống nhau. Trong lĩnh vực của mọi thứ nói chung, tôi muốn nói rằng chúng gần như giống hệt nhau.
Kirk Broadhurst

0

Dữ liệu trong một mảng có thể được truy cập bằng khóa hoặc chỉ mục. Dữ liệu trong ngăn xếp có thể được truy cập khi nó được bật ra khỏi đỉnh của ngăn xếp. Điều này có nghĩa là việc truy cập dữ liệu từ một mảng rất dễ dàng nếu bạn biết chỉ mục của nó. Truy cập dữ liệu từ ngăn xếp có nghĩa là bạn phải tiếp tục bật các phần tử cho đến khi bạn tìm thấy phần tử bạn đang tìm kiếm, điều đó có nghĩa là việc truy cập dữ liệu có thể mất nhiều thời gian hơn.


0

Một mảng là từ quan điểm lập trình viên, cố định tại chỗ và kích thước, bạn biết bạn đang ở đâu trong đó và toàn bộ sự việc ở đâu. Bạn có quyền truy cập vào tất cả của nó.

Với một chồng, bạn ngồi ở một đầu của nó nhưng không biết kích thước của nó hoặc bạn có thể đi bao xa một cách an toàn. Quyền truy cập của bạn bị giới hạn ở số tiền bạn đã phân bổ, bạn thậm chí không biết liệu khi phân bổ số tiền bạn muốn nếu bạn chỉ đâm sầm vào không gian hoặc chương trình. Quan điểm của bạn về ngăn xếp là một mảng nhỏ mà bạn đã tự phân bổ, kích thước bạn muốn, bạn có quyền kiểm soát và có thể nhìn thấy. Phần của bạn không khác gì một mảng. Sự khác biệt nằm trong mảng của bạn được giải quyết ở một đầu của mảng khác vì lý lẽ và thuật ngữ mà bạn không thể thấy được, không biết lớn hay nhỏ và bạn không thể chạm vào nó mà không gây hại. Một mảng, trừ khi toàn cục, thường được triển khai trên ngăn xếp, vì vậy mảng và ngăn xếp chia sẻ cùng một không gian trong suốt thời gian của hàm đó.

Nếu bạn muốn vào phần cứng, thì dĩ nhiên đó là bộ xử lý cụ thể, nhưng nhìn chung mảng dựa trên điểm / địa chỉ bắt đầu đã biết, kích thước được trình biên dịch / lập trình viên biết và địa chỉ được tính vào nó, đôi khi sử dụng địa chỉ bù thanh ghi (tải một giá trị từ địa chỉ được xác định bởi giá trị thanh ghi cơ sở này cộng với giá trị thanh ghi bù này, tương tự như vậy khi được biên dịch, nó có thể là một bù trừ ngay lập tức không nhất thiết phải đăng ký, phụ thuộc vào bộ xử lý) tương tự như truy cập một mảng trong mã cấp cao. Tương tự như vậy với ngăn xếp, nếu có sẵn, bạn có thể sử dụng thanh ghi hoặc địa chỉ bù ngay lập tức, mặc dù nó sử dụng một thanh ghi đặc biệt, hoặc chính con trỏ ngăn xếp hoặc một thanh ghi dành cho trình biên dịch / lập trình viên được sử dụng để truy cập khung ngăn xếp cho điều đó chức năng. Và đối với một số bộ xử lý, các hàm truy cập ngăn xếp đặc biệt được sử dụng và / hoặc được yêu cầu để truy cập ngăn xếp. Bạn có hướng dẫn đẩy và bật nhưng chúng không được sử dụng thường xuyên như bạn nghĩ và không thực sự áp dụng cho câu hỏi này. Đối với một số bộ xử lý, đẩy và pop là bí danh cho các hướng dẫn có thể được sử dụng với bất kỳ thanh ghi nào, ở bất cứ đâu, không chỉ con trỏ ngăn xếp trên ngăn xếp, tiếp tục loại bỏ đẩy và bật khỏi liên quan đến câu hỏi này.

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.