- H ạn chế của cách cài đặt này: kích thước của stack bị giới hạn và kém linh động, do đĩ việc sử dụng bộ nhớ kém hiệu quả (thiếu hay lãng phí bộ nhớ).
c. Cài đặt ngăn xếp bằng DSLK động
Ta cĩ thể cài đặt ngăn xếp bằng danh sách liên kết động (tương tự như DSLK đơn, chỉ khác là khơng lưu đến nút cuối hay đáy của ngăn xếp) như
sau:
typedef .... ElementType; // Kiểu dữ liệu của nút typedef struct node { ElementType Data;
struct node *Next;
} NodeType; typedef NodeType *NodePointer; NodePointer Stack;
• Các phép tốn cơ bản trên stack
Các thao tác khởi tạo một stack rỗng và kiểm tra xem mơt stack cho trước cĩ rỗng hay khơng tương tự như DSLK đơn. Ta chỉ chú trọng đến hai thao tác đặc trưng của ngăn xếp là lấy ra Pop và thêm vào Pushở đỉnh ngăn xếp.
Gọi Stack là con trỏ chỉ đến phần tửởđỉnh của ngăn xếp.
* Thao tác Push đẩy một mục dữ liệu x vào đỉnh ngăn xếp
Thao tác Push tương tự thao tác InsertElementHeadLL, nếu ta quản lý thêm nút ở đáy stack. Stack Temp x Đỉnh ngăn xếp 2 1 Stack • Hoặc ta cĩ thể viết trực tiếp như sau:
int Push(NodePointer &Stack, ElementType x)
{ NodePointer Temp;
if ((Temp = CreateNodeLL(x)) == NULL) return(0); else { Temp->Next = Stack;
Stack = Temp; return 1 ; }
}
Thao tác Pop tương tự thao tác RemoveHeadLL, nếu ta quản lý thêm nút ở đáy stack.
Temp 1 Data Next Đỉnh ngăn xếp Stack
2
•
Ta cĩ thể viết trực tiếp thao tác này như sau:
int Pop(NodePointer &Stack, ElementType &x)
{ NodePointer Temp; if (EmptyStack(Stack)) { cout << “\nNgăn xếp rỗng. Khơng thể lấy phần tử ở đỉnh ngăn xếp !"; return 0; }
else {Gan (x, Stack->Data);
Temp = Stack; Stack = Stack->Next; delete Temp;
return 1; }
}
* Thao tác Top xem một phần tửở đỉnh ngăn xếp int Top(NodePointer Stack, ElementType &x)
{ NodePointer Temp;
if (EmptyStack(Stack))
{ cout << “\nNgăn xếp rỗng. Khơng thể xem phần tử ởđỉnh ngăn xếp !";
return 0; }
else {Gan (x, Stack->Data); return 1; }
}