Tải bản đầy đủ

ÔN TÂP CẤU TRÚC DỮ LIỆU

Câu 1: Giải thuật bổ sung nút mới vào trước nút Q bằng danh sách móc
nối hai chiều.
* Ý tưởng:
 Cho con trỏ L và R lần lượt trỏ tới nút cực trái và nút cực phải của một
danh sách móc nối kép, Q là con trỏ tới một nút trong danh sách này.
 Bổ sung một nút mới vào trước nút trỏ Q tức là nút cực trái của nút mới
trỏ đến nút trước Q, nút cực phải của nút mới trỏ đến Q.
 Ta sẽ bổ sung được nút mới vào trước Q.
Giải thuật: (R=pcuoi, L=pdau )
Insert_B(L,R,Q,X)
{
P=malloc();
P->DATA=X;
P->P_R=NULL;
P->P_L=NULL;
if(R==NULL) //danh sách rỗng
L=R=P;
else{
if(Q==L){
P->P_R=Q;
Q->P_L=P;

L=P;
}
else{
P->P_L=Q->P_L;
P->P_R=Q;
Q->P_L=P;
(P->P_L)->P_R=P;
}
}


Câu 2: Giải thuật loại nút trỏ bởi Q bằng danh sách móc nối hai chiều.
Cho L và R là hai con trỏ trái và phải của danh sách móc nối kép, Q trỏ tới một
nút trong danh sách. Ta sẽ loại bỏ nút trỏ bởi Q ra khỏi danh sách.
DELETE(L, R,Q)
{
if (R==NULL)
Printf(“Danh sách rỗng”);
else
{
if( L==R)
L=R=NULL;
else
if ( Q=L )
{
L=L->P_R;
L->P_L=NULL;
}
else
if (M=R)
{
R=R->P_L;
R->P_R=NULL;
}
else
{
Q->P_L->P_R=Q->P_R;
Q->P_R->P_L=Q->P_L;
}
free(Q);
}
}


Giải thuật duyệt cây sau không dùng đệ quy:
 Ý tưởng: Đầu tiên ta thăm các nút cây con trái, sau đó thăm các nút cây
con phải cuối cùng thăm nút gốc.
Như vậy nút gốc chỉ được thăm khi đã duyệt xong 2 cây con của nó. Tức
là nút gốc được duyệt khi đi từ con phải lên gặp gốc chứ không phải từ
lần đi từ con trái lên gặp gốc.
Dùng stack để khử đệ quy.
 Giải thuật:
TT_SAU_S(T)
{
if(T==NULL)
{
printf("Cây rỗng");
return;
}
else{
TOP=-1;
P=T;
}
while(1)
{
while(P!=NULL)
{
PUSH(S,TOP,P);
P=P->P_L;
}
while(S[TOP]<0)
{
P=POP(S,TOP);
printf(P->DATA);
if(TOP==-1)
return;
}
P=S[TOP]->P_R;
S[TOP]=S[TOP]--;
}
}


Giải thuật Quick_sort
 Ý tưởng: chọn một khóa ngẫu nhiên nào đó của dãy làm chốt. Mọi phần
tử nhỏ hơn chốt thì nằm trước phần tử chốt, mọi phần tử lớn hơn chốt thì
nằm sau chốt. Muốn vậy, các phần tử trong dãy phải được so sánh với
khóa chốt và đổi vị trí cho nhau và cho chốt nếu những phần tử lớn hơn
chốt nằm trước chốt hoặc những phần tử nhỏ hơn chốt nằm sau chốt. Khi
việc đổi chỗ này được thực hiện xong thì dãy được phân làm hai đoạn:
một đoạn gồm những phần tử nhỏ hơn chốt, một đoạn gồm những phần tử
lớn hơn chốt, còn khóa chốt nằm ở giữa hai đoạn nói trên và đây cũng là
vị trí thực cảu khóa chốt khi mà dãy được sắp xếp xong. Đây coi như kết
thúc 1 lượt sắp xếp.
Áp dụng phương pháp như trên cho mỗi đoạn và tiếp tục làm như vậy cho
đến khi mỗi đoạn chỉ còn 1 phần tử. Khi đó toàn bộ dãy đã được sắp xếp.
 Giải thuật:
Quick_sort(K,t,p)
{
if(t{
Partition(K,t,p,j);
Quick_sort(K,t,j-1);
Quick_sort(K,j+1,p);
}
}
Partition(K,t,p,j)
{//K[t] là chốt
i=t+1;
j=p;
do{
while(ii=i+1;
while(iK[t])
j=j-1;
if(i<=j){
K[i]<->K[j];//Đổi chỗ K[i] và K[j]
i=i+1;
j=j-1;
}
}
while(j<=i)
K[t]<->K[j];//Đổi chỗ K[t] và K[j]
}


Đánh giá thời gian thực hiện giải thuật Quic –Sort với dãy có n phần
tử trong trường hợp tốt nhất.
Gọi T(n) là thời gian thực hiện giải thuật ứng với một mảng n khoá,
P(n) là thời gian để phân đoạn một mảng n khoá thành hai mảng con. Ta
có thể viết:
T(n) = P(n) + T(j-t) + T(p-j)
Chú ý rằng P(n) = Cn với C là một hằng số.
Trường hợp tốt nhất xảy ra khi mảng luôn luôn được chia đôi, nghĩa
là: j =

tp
. Lúc đó:
2

Ttốt(n) = P(n) + 2Ttốt(n/2)
= Cn + 2Ttốt(n/2)
= Cn + 2C(n/2) + 4Ttốt(n/4) = 2Cn + 22Ttốt(n/4)
= Cn + 2C(n/2) + 4C(n/4) + 8Ttốt(n/8) = 23Cn + 23Ttốt(n/8)
...
= (log 2 n )Cn  2 log 2 n Ttốt(1)

= O(nlog2n)


Câu: Giải thuật sắp xếp Merge sort:
 Ý tưởng:
Để sắp xếp bảng T:
+ Chia T thành 2 bảng độ dài bằng nhau.
+ Sắp xếp mỗi bảng con này .
+ Từ 2 bảng con đã sắp, xếp xen kẽ lại để được bảng T được
sắp xếp.
 Giải thuật:
1. Hòa Nhập 2 đường:
MERGE (K, b, m, n, X)
{
i=t=b; j=m+1;
While(i<=m) and (j<=n) //Chừng nào cho 2 marngcon vẫn còn
khóa
If (K[i] < K[j]) //So sánh để chọn khóa nhỏ hơn
X[t++] = K[i++];
Else
X[t++] = K[j++];//Một trong 2 mảng con đã hết khóa
trước
If (i>m) //Mảng 1 hết khóa trước
For (;j<=n;)
X[t++]=K[j++];
Else //Mảng 2 chiều hết khóa trước
For (;i<=m;)
X[t++]=K[i++];
}


2. Sắp xếp trộn trực tiếp: (Bao gồm giải thuật 1 và 2 giải thuật sau):
MPASS (K, X, n, h)
{
i=0;
while (i<=n-2*h) //Hòa nhập cặp mạch có độ dài h
{
MERGE (K, I, i+h-1, i+2*h-1, X);
I=i+2*h;
}
If (i+hMERGE (K, I, i+h-1, i+2*h-1, X);
Else // chỉ còn 1 mạch
For (; iX[i]= K[j];
}
Hàm MPASS được gọi tới trong hàm sắp xếp sau:
MERGE_SORT (K, n)
{
h=1;
while (h{
MPASS (K, X, n, h); //Hòa nhập và chuyển các khóa vào K
MPASS (K, X, n, 2* h); //Hòa nhập và chuyển các khóa
vào K
h= 4+h;
}
}



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tải bản đầy đủ ngay

×

×