You are on page 1of 16

Cấu trúc dữ liệu và giải thuật

Câu loại I. Đánh giá độ phức tạp của thuật toán


Câu loại II. Trình bầy cấu trúc của lớp
1. Trình bầy cấu trúc dữ liệu của lớp Vector
+ Cấu trúc dữ liệu của lớp Vector:
- Thuộc tính:
int capacity; // số chiều tối đa của Vector
Object *V; // lưu tọa độ
int n; // chỉ số của chiều thứ n
- Phương thức:
int getAtRank(integer r, object &o): trả lại phần tử có chỉ số r, nhưng
không loại bỏ nó.
int replaceAtRank(integer r, object &o, object &o1): thay thế phần tử có
chỉ số r bằng phần tử o và trả lại phần tử bị thay thế.
int insertArRank(integer r, object o): chèn phần tử o vào vị trí r
int removetRank(integer r, object &o): loại bỏ phần tử tại vị trí r, và trả
lại phần tử bị loại bỏ.
int size(): cho biết kích thước của Vector
int isEmpty(): cho biết Vector có rỗng hay không.
+ Bộ lặp cho các đối tượng Vector:
template <class Object>
class VectorItr{
private :
int Vector<Object>* theVector;
int current_Index;
int number_Element;
public:
VectorItr(Vector<Object>*V1,int nb)
{
theVector = V1;
number_Element = nb;
current_Index = 0;
}
int hasNext(){
if (current_Index<number_Element)
return 1;
else
return 0;
}
Object next(){
Object o;
theVector->getAtRank(current_index, o);
current_Index++;
return o; }
};//End of class VectorItr
2. Trình bầy cấu trúc dữ liệu của lớp danh sách liên kết đơn (cả lớp Node)
+ Cấu trúc của một Node
- Các thuộc tính:
Element *elem;
Node *next;
- Các phương thức:
Node *getnext() - trả lại địa chỉ của nút kế tiếp.
Element *getElem() - trả lại địa chỉ của phần tử mà nút trỏ tới trong nút.
void setNext(Node *) - đặt thuộc tính next trỏ đến địa chỉ phần tử là đối
của phương thức.
void setElem(Element e) - đặt phần tử e vào nút.
+ Cấu trúc danh sách liên kết đơn:
- Các thuộc tính:
Node *header
Node *trailer
- Các phương thức chung:
long size(),
int isEmpty()
- Các phương thức truy cập:
Node *first()
Node *last()
- Các phương thức cập nhật:
void replace(Node *p, e)
Node *insertAfter(Node *p,Elemnt e)
Node * insertFirst(Element e)
Node * insertLast(Element e)
void remove(Node *p)
3. Trình bầy cấu trúc dữ liệu của lớp danh sách liên kết kép (cả lớp Node)
+ Cấu trúc của một Node:
- Các thuộc tính:
Element *elem;
Node *next, *pre;
- Các phương thức:
Node *getnext() - trả lại địa chỉ của nút kể tiếp.
Node *getPre() - trả lại địa chỉ của nút trước đó.
Element *getElem() - trả lại địa chỉ của phần tử lưu trong nút
void setNext(Node *) - đặt thuộc tính Next trỏ đến đ/c của phần tử là đối
của phương thức.
void setPre(Node *) - đặt thuộc tính Pre trỏ đến đ/c của phần tử là đối
của phương thức.
void setElem(Element e) - đặt phần tử e vào nút.
+ Cấu trúc danh sách liên kết kép:
- Các thuộc tính:
Node *header
Node *trailer
- Các phương thức chung:
long size(),
int isEmpty()
- Các phương thức truy cập:
Node *first()
Node *last()
- Các phương thức cập nhật:
void replace(Node *p, e)
Node *insertAfter(Node *p,Elemnt e)
Node *insertBefore(Node *p,Element e)
Node * insertFirst(Element e)
Node * insertLast(Element e)
void remove(Node *p)
4. Trình bầy cấu trúc dữ liệu biểu diễn cây tổng quát (cả lớp Node)
+ Cấu trúc dữ liệu một Node của cây tổng quát:
- Thuộc tính:
Object elem
Node *Parent
List<Node*>Child
- Phương thức:
Node *getParent()
Node *getChild(int i)
void setChild(Node*)
Object getElem()
void setElem(Object o)
+ Cấu trúc cây tổng quát:
- Thuộc tính:
Node * root
- Phương thức:
int size()
int isEmpty()
int isInternal(Node*)
int isExternal(Node*)
int isRoot(Node*)
void preOrder(Node*)
void inOrder(Node*)
void postOrder(Node*)
- Các phương thức truy cập:
Node *root()
5. Trình bầy cấu trúc dữ liệu biểu diễn cây nhị phân (cả lớp Node)
+ Cấu trúc Node biểu diễn cây nhị phân:
- Thuộc tính:
Object elem
Node *Parent
List<Node*>Child
- Phương thức:
Node *getParent()
Node *getChild(int i)
void setChild(Node*)
Object getElem()
void setElem(Object o)
+ Cấu trúc dữ liệu cây nhị phân:
- Thuộc tính:
Node * root
- Phương thức:
int size()
int isEmpty()
int isInternal(Node*)
int isExternal(Node*)
int isRoot(Node*)
void preOrder(Node*)
void inOrder(Node*)
void postOrder(Node*)
- Các phương thức truy cập:
Node *root()
6. Trình bầy cấu trúc dữ liệu biểu diễn cây tìm kiếm nhị phân
+ Cấu trúc của cây tìm kiếm nhị phân:
- Thuộc tính:
Node * root
- Phương thức:
int size()
int isEmpty()
int isInternal(Node*)
int isExternal(Node*)
int isRoot(Node*)
void preOrder(Node*)
void inOrder(Node*)
void postOrder(Node*)
Node * TreeSearch(Keys, Node*)
Node * InsertTree(Keys, Object )
void Remove(Keys)
- Các phương thức truy cập:
Node *root()
Câu loại III. Cài đặt một phương thức của lớp
1. Cài đặt phương thức Chèn, Xóa một phần tử của lớp Vector
// Hàm insertAtRank – Chèn một phần tử của lớp Vector
template<class Object>
int Vector<Object>::insertAtRank(int r, Object o)
{
if(n==N)
{
Object *A;
N = 2*N;
A = new Object[N];
for(int i=0;i<n;i++)
A[i] = V[i];
delete V;
V = A;
}
if(r<0 || r >n )
return 0;
int k = n-1;
while(k>=r)
{
V[k+1] = V[k];
k--;
}
V[r]= o;
n++;
return 1;
}
// Hàm removeAtRank – Xóa một phần tử của lớp Vector
template<class Object>
int Vector<Object>::removeAtRank(int r, Object &o)
{
if(r<0 || r>n-1)
return 0;
o = V[r];
int k = r;
while(k<n-1)
{
V[k] = V[k+1];
k++;
}
n--;
return 1;
}
2. Cài đặt phương thức bổ sung phần tử vào cuối danh sách liên kết đơn, Cài đặt phương
thức xóa một phần tử khỏi danh sách liên kết đơn.
// Hàm insertAfter – Bổ sung phần tử vào cuối danh sách liên kết đơn
template<class Element>
Node<Element>* List<Element>::insertAfter(Node<Element>*p, Element e)
{
Node<Element>* q;
q = new Node<Element>;
q->setElem(e);
if(p = = trailer)
{
p->setNext(q);
trailer=q;
}
else
{
q->setNext(p->getNext());
p->setNext(q);
}
count++;
return q;
}
// Hàm remove – Xóa một phần tử khỏi danh sách liên kết đơn
template <class Element>
void List<Element>::remove(Node<Element> *p)
{
if(p = = header)
{
header =header->getNext();
}
else
{
Node<Element>*q;
q = header;
while(q->getNext()!=p)
q = q->getNext();
q->setNext(p->getNext());
if(p = = trailer)
trailer = q;
delete p;
count--;
}
}
3. Cài đặt phương thức thêm một phần tử vào đầu danh sách liên kết kép, xóa một phần
tử khỏi danh sách liên kết kép.
// Hàm insertFirst – Bổ sung phần tử vào đầu danh sách liên kết kép
template <class Element>
Node<Element>* List<Element>::insertFirst(Element e)
{
Node<Element>* q;
q = new Node<Element>;
q->setElem(e);
if(isEmpty())
{
trailer = q;
header = q;
}
else
{
q->setNext(header);
header->setPre(q);
header = q;
}
count++;
return q;
}
// Hàm remove – Xóa một phần tử khỏi danh sách liên kết kép
template <class Element>
void List<Element>::remove(Node<Element> *p)
{
if(p = = header)
{
header =header->getNext();
if(header!=NULL)
header->setPre(NULL);
}
else
if(trailer = = p)
{
trailer = trailer->getPre();
if(trailer!=NULL)
trailer->setNext(NULL);
}
else
{
p->getNext()->setPre(p->getPre());
p->getPre()->setNext(p->getNext());
}
delete p;
count--;
}
4. Cài đặt phương thức PUSH, POP của lớp Stack
// Phương thức PUSH:
template<class Object>
int ArrayStack<Object>::push(Object o)
{
if(t=capacity-1)
return 0;
else{
S[t++] = o;
return 1;
}
}
// Phương thức POP
template<class Object>
int ArrayStack<Object>::pop(Object&o )
{
if(t<0)
return 0; //stack rỗng
else{
o = S[t--];
return 1;
}
}
5. Cài đặt các phương thức Queue, Dequeue của lớp Queue (Hàng Đợi)
template <class Object>
class Queue{
private:
Object Q[N];
int f, r;
public:
int isEmpty();
int size();
Object front();
int enqueue(Object o);
int dequeue(Object &o);
}
int Queue<Object>::dequeue(Object o)
{
if (size() = N-1)
return 0;
else {
Q[f] = o;
r =(r+1)%N;
return 1;
}
}
6. Cài đặt các phương thức duyệt cây tổng quát (preOrder, InOder)
Câu loại IV. Tìm kiếm
1. Cài đặt thuật toán tìm kiếm nhị phân trên mảng
Algorithm BinarySearch(S, k, n);
Found = 0;
i = 1;
j = n;
while(i<=j && Found!=1)
mid = (i+j) / 2;
if (k==S[mid].Key) Found = 1;
else
if (k < S[mid].Key)
j = mid – 1;
else
i = mid+1;
return Found;
2. Cài đặt thuật toán chèn một phần tử vào cây tìm kiếm nhị phân
voidTreeInsert(Keys k, Object elem)
if(root==NULL){ q = new Node(); q->setKey(k); q->setEmlem(elem);
q->setLeft(NULL); q->setRight(NULL); q->setParent(NULL); root = q;}
else{ p = root;
while(p != NULL){
if(k< p->getKey())
if(p->left==NULL){q = new Node(); q->setKey(k);
q->setEmlem(elem); q->setLeft(NULL); q->setRight(NULL);
q->setParent(p); p->setLeft(q); p = NULL;
}else p = p->Left();
else if(k> p->getKey()) // nam ben cay con ben phai
if(p->right == NULL){ q = new Node(); q->setKey(k);
q->setEmlem(elem);q->setLeft(NULL); q->setRight(NULL);
q->setParent(p); p->setRight(q); p = NULL;
}else p = p->Right;
else break;
}
}
3. Cài đặt thuật toán tìm một phần tử trên cây tìm kiếm nhị phân
Node*TreeSearch(Keys k, Node* v)
if(v==NULL)
return v;
else
if (k< v->getKey())
return TreeSearch(k,v->Left());
else if (k== v->getKey())
return v
else{ k> key(v) }
return TreeSearch(k,v->Right());
4. Cài đặt thuật toán xóa một phần tử trên cây tìm kiếm nhị phân
void Remove(Keys k)
{
Node *v = TreeSearch(root, k);
if(v==NULL) return;
if((v->hasLeft() && !v->hasRight()) || ((v->hasRight() && !v->hasLeft()))
Remove(v);
else{
Node *first; int kt=0;
InOrder(v->Right(), first, kt);
v->setKey(first->getKeys());
v->setElem(first->getElem());
Remove(first);
}
}
5. Cài đặt thuật toán tìm kiếm trên bảng băm (Không học)
Câu loại V. Ý tưởng thuật toán sắp xếp
1. Trình bầy ý tưởng của của thuật toán sắp xếp QuickSort
Ý tưởng (sử dụng phương pháp chia và trị):
- Thực hiện phân hoạch dãy S cần sắp thành 3 dãy S1, S2, S3. Trong đó:
+ S2 chỉ có một phần tử, tất cả các phần tử của dãy S3 đều > phần tử của dãy S2.
+ Tất cả các phần tử của dãy S1 đều ≤ phần tử của dãy S2
+ Dãy S1, S3 có thể là rỗng
- Tiếp tục phân hoạch dãy S1 và S3 độc lập theo nguyên tắc trên đến khi dãy cần thực
hiện phân hoạch chỉ có một phần tử thì dưng lại. Khi đó ta được dãy các phần tử
được sắp.
2. Trình bầy ý tưởng của thuật toán sắp xếp MergeSort
Ý tưởng:
- Giả sử ta có hai dãy A[i],..,A[k] và A[k+1],..,A[j] và hai dãy này đã được sắp.
- Thực hiện trộn hai dãy trên để được dãy A[i],..,A[j] cũng được sắp
- Do hai dãy A[i],..,A[k] và dãy A[k+1],..,A[j] đã được sắp nên việc trộn hai dãy
thành một dãy được sắp là rất đơn giản.
3. Trình bầy ý tưởng của thuật toán sắp xếp HeapSort
Ý tưởng:
- Tạo mảng A[1],..,A[n] biểu diễn cây Heap.
- Tráo đổi phần tử A[1] với phần tử A[n].
- Tạo mảng A[1],..,A[n-1] biểu diễn cây heap
- Tráo đổi phần tử A[1] với phần tử A[n-1].
- Lặp lại quá trình trên đến khi mảng chỉ còn 1 phần tử
Câu loại VI. Thủ tục thuật toán sắp xếp
1. Cài đặt thuật toán sắp xếp QuickSort
Algorithm QuickSort (array A, i, j );
Input: Dãy các phần tử A[i],..,A[j] và hai số nguyên i, j
Output: Dãy A[i],..,A[j] được sắp.
if i < j then
Partition (A,i, j, k); //k lấy chỉ số của phần tử làm S2
Quicksort (A,i, k-1);
Quicksort (A,k+1, j);
2. Cài đặt thuật toán sắp xếp MergeSort
Algorithm Mergesort(array A,int i, int j)
Input: Dãy các phần tử A[i],..,A[j]
Output:Dãy A[i],..,A[j] được sắp.
if i<j then
k←(i+j)/2;
Mergesort(A,i, k);
Mergesort(A, k+1,j);
Merge(A, i, k, j);
3. Cài đặt thuật toán sắp xếp HeapSort (thuật toán vun đống)
Algorithm Heapsort(Array A, n);
Input: Mảng A có và số nguyên n
Output: Mảng A được sắp theo thứ tự tăng dần của thuộc tính khóa
for i← n/2 downto 1 do
Pushdown(A, i, n);
for i← ndownto 2 do
swap(A[1],A[i]);
Pushdown(A,1,i-1);
Câu loại VII. Mô tả thuật toán sẵp xếp dãy số cho trước
(Xem trong Lectures 14 Sorting - nlogn)
1. Mô tả quá trình sắp xếp dãy số sau đây bằng thuật toán sẵp xếp QuickSort
3 23 1 31 22 23 323
2. Mô tả quá trình sắp xếp dãy số sau đây bằng thuật toán sẵp xếp MergeSort
3 23 1 31 22 23 323
3.Mô tả quá trình sắp xếp dãy số sau đây bằng thuật toán sẵp xếp HeapSort
3 23 1 31 22 23 323
Câu loại VIII. Bài tập ứng dụng

You might also like