Hàng đợi (Queue)
Hàng đợi là một tập hợp trong đó có thứ tự vào trước và ra trước (FIFO). Tương tự
như là những người mua vé tàu, họ xếp thành một hàng, người nào vào trước thì sẽ
mua trước và ra trước. Hàng đợi là kiểu dữ liệu tốt để quản lý những nguồn tài
nguyên giới hạn. Ví dụ, chúng ta muốn gởi thông điệp đến một tài nguyên mà chỉ xử
lý được duy nhất một thông đi
ệp một lần. Khi đó chúng ta sẽ thiết lập một hàng đợi
thông điệp để xử lý các thông điệp theo thứ tự đưa vào.
Lớp Queue thể hiện kiểu dữ liệu như trên, trong bảng 9.4 sau liệt kê những phương
thức và thuộc tính thành viên.
Phương thức- thuộc
tính
Mục
đích
Synchronized()
Phương thức static trả về một Queue wrapper
được
th
read-safe.
Count
Thuộc tính trả về số thành phần trong hàng đợi
IsReadOnly
Thuộc tính xác định hàng đợi là chỉ đọc
IsSynchronized
Thuộc tính xác định hàng đợi được đồng bộ
SyncRoot
Thuộc tính trả về đối tượng có thể được sử dụn
g
để
đồng bộ
truy cập Queue.
Clear()
Xóa tất cả các thành phần trong hàng đợi
Clone()
Tạo ra một bản sao
Contains()
Xác định xem một thành phần có trong mảng.
CopyTo()
Sao chép những thành phần của hàng đợi đến
mảng
mộ
t chiều đã tồn tại
Dequeue()
Xóa và trả về thành phần bắt đầu của hàng đợi.
Enqueue()
Thêm một thành phần vào hàng đợi.
GetEnumerator()
Trả về một enumerator cho hàng đợi.
Peek()
Trả về phần tử đầu tiên của hàng đợi và không xóa
nó.
ToArray()
Sao chép những thành phần qua một mảng mới
Bảng 9.4: Những phương thức và thuộc tính của Queue.
Chúng ta có thể thêm những thành phần vào trong hàng đợi với phương thức Enqueue và
sau đó lấy chúng ra khỏi hàng đợi với Dequeue hay bằng sử dụng enumerator. Ví dụ
9.15 minh họa việc sử dụng hàng đợi.
Ví dụ 9.15: Làm việc với hàng đợi.
-----------------------------------------------------------------------------
namespace Programming_CSharp
{
using System;
using System.Collections;
public class Tester
{
public static void Main()
{
Queue intQueue = new Queue();
// đưa vào trong mảng
for(int i=0; i <5; i++)
{
intQueue.Enqueue(i*5);
}
// hiện thị hàng đợi
Console.Write(“intQueue values:\t”);
PrintValues( intQueue);
// xóa thành phần ra khỏi hàng đợi
Console.WriteLine(“\nDequeue\t{0}”, intQueue.Dequeue());
// hiển thị hàng đợi
Console.Write(“intQueue values:\t”);
PrintValues(intQueue);
// xóa thành phần khỏi hàng đợi
Console.WriteLine(“\nDequeue\t{0}”, intQueue.Dequeue());
// hiển thị hàng đợi
Console.Write(“intQueue values:\t”);
PrintValues(intQueue);
// Xem thành phần đầu tiên trong hàng đợi.
Console.WriteLine(“\nPeek \t{0}”, intQueue.Peek());
// hiển thị hàng đợi
Console.Write(“intQueue values:\t”);
PrintValues(intQueue);
}
public static void PrintValues(IEnumerable myCollection)
{
IEnumerator myEnumerator = myCollection.GetEnumerator();
while (myEnumerator.MoveNext()) Console.Write(“{0} ”,
myEnumerator.Current);
Console.WriteLine();
}
}
}
-----------------------------------------------------------------------------
Kết quả:
intQueue values: 0 5 10 15 20
Dequeue 0
intQueue values: 5 10 15 20
Dequeue 5
intQueue values: 10 15 2
0
Peek 10
intQueue values: 10 15 2
0
-----------------------------------------------------------------------------
Trong ví dụ này ArrayList được thay bằng Queue, chúng ta cũng có thể Enqueue
những đối tượng do ta định nghĩa. Trong trong chương trình trên đầu tiên ta đưa 5 số
nguyên vào trong hàng đợi theo tứ tự 0 5 10 15 20. Sau khi đưa vào ta lấy ra phần tử
đầu tiên là 0 nên hàng đợi còn lại 4 số là 5 10 15 20, lần thứ hai ta lấy ra 5 và chỉ
còn 3 phần tử trong mảng 10 15 20. Cuối cùng ta dùng phương thức Peek() là chỉ xem
phần tử đầu hàng đợi chứ không xóa chúng ra khỏi hàng đợi nên kết quả cuối cùng
hàng
đợi vẫn còn 3 số là 10 15 20. Một điểm lưu ý là lớp Queue là một lớp có thể
đếm được enumerable nên ta có thể truyền vào phương thức PrintValues với kiểu
tham số khai báo IEnumerable. Việc chuyển đổi này là ngầm định. Trong phương
thức PrintValues ta gọi phương thức GetEnumerator, nên nhớ rằng đây là phương
thức đơn của tất cả những lớp IEnumerable. Kết quả là một đối tượng Enumerator
được trả về, do
đó chúng ta có thể sử dụng chúng để liệt kê tất cả những đối tượng
có trong tập hợp.
Ngăn xếp (stack)
Ngăn xếp là một tập hợp mà thứ tự là vào trước ra sau hay vào sao ra trước (LIFO),
tương như một chồng đĩa được xếp trong nhà hàng. Đĩa ở trên cùng tức là đĩa xếp sau
thì được lấy ra trước do vậy đĩa nằm dưới đáy tức là đĩa đưa vào
đầu tiên sẽ được lấy ra
sau cùng.
Hai phương thức chính cho việc thêm và xóa từ stack là Push và Pop, ngoài ra ngăn
xếp cũng đưa ra phương thức Peek tương tự như Peek trong hàng đợi. Bảng 9.5
sau minh họa các phương thức và thuộc tính của lớp Stack.
Phương thức- thuộc tính Mục
đích
Synchronized()
Phương thức static trả về một Stack
wrapper
được thread-safe.
Count
Thuộc tính trả về số thành phần trong ngăn
xếp
IsReadOnly
Thuộc tính xác định ngăn xếp là chỉ đọc
IsSynchronized
Thuộc tính xác định ngăn xếp được đồng bộ
SyncRoot
Thuộc tính trả về đối tượng có thể được sử
dụng
để đồng bộ
truy cập Stack.
Clear()
Xóa tất cả các thành phần trong ngăn xếp
Clone()
Tạo ra một bản sao
Contains()
Xác định xem một thành phần có trong mảng.
CopyTo()
Sao chép những thành phần của ngăn xếp
đến
mảng mộ
t chiều đã tồn tại
Pop()
Xóa và trả về phần tử đầu Stack
Push()
Đưa một đối tượng vào đầu ngăn xếp
GetEnumerator()
Trả về một enumerator cho ngăn xếp.
Peek()
Trả về phần tử đầu tiên của ngăn xếp và
không
xóa nó.
ToArray()
Sao chép những thành phần qua một mảng
mới
Bảng 9.5 : Phương thức và thuộc tính của lớp Stack.
Ba lớp ArrayList, Queue, và Stack đều chứa phương thức nạp chồng CopyTo() và
ToArray()
dể sao chép những thành phần của chúng qua một mảng. Trong trường hợp của
ngăn xếp phương thức CopyTo() sẽ chép những thành phần của chúng đến mảng
một chiều đã hiện hữu, và viết chồng lên nội dung của mảng bắt đầu tại chỉ mục mà
ta xác nhận. Phương thức ToArray() trả về một mảng mới với những nội dung của
những thành phần trong mảng.
Ví dụ 9.16: Sử dụng kiểu Stack.
-----------------------------------------------------------------------------
namespace Programming_CSharp
{
using System;
using System.Collections;
// lớp đơn giản để lưu trữ
public class Tester
{
static void Main()
{
Stack intStack = new Stack();
// đưa vào ngăn xếp
for (int i=0; i < 8; i++)
{
intStack.Push(i*5);