BÀI TẬP MÔN THỰC HÀNH CẤU TRÚC DỮ LIỆU
*Thông tin sinh viên:
- Họ & Tên: Lê Thị Hồng Hà
- Mã sv: 102150218
- Số thứ tự: 06
- Lớp: 15TCLC1
- MSSV: 102150218
Bài làm:
Phần I: Mảng, con trỏ
1.
Sắp xếp mảng tăng dần theo phương pháp chọn trực tiếp
• Ý tưởng:
- Chọn phần tử nhỏ nhất trong n phần tử đầu, đưa phần tử này về vị trí
đầu của dãy. Tiếp tục quá trình với n-1 phần tử còn lại và bắt đầu từ vị
trí thứ 2, lặp lại quá trình trên cho dãy gồm n-1 phần tử còn lại.
- Thuật toán thực hiện n-1 lần để lần lượt đưa phần tử nhỏ nhất trong
dãy hiện hành về vị trí dẫn đầu.
• Các bước tiến hành như sau:
- Bước 1: i = 1;
- Bước 2: Tìm phần tử a[min] nhỏ nhất trong dãy hiện hành từ a[i] đến
a[N]
- Bước 3 : Hoán vị a[min] và a[i]
- Bước 4 : Nếu i < N-1 thì i = i+1; Lặp lại Bước 2
- Ngược lại: Dừng. //N-1 phần tử đã nằm đúng vị trí.
Code:
#include<stdio.h>
#include<conio.h>
int a[100];
void main()
•
{
int i, j, n,k;
printf("nhap so phan tu cua mang: ");
scanf("%d", &n);
for (i = 0; i < n; i++)
{
printf("nhap phan tu thu %d: ", i + 1);
scanf("%d", &a[i]);
}
for (i = 0; i < n-1;i++)
for (j = i+1; j < n;j++)
if (a[i]>a[j])
{
k = a[i];
a[i] = a[j];
a[j] = k;
}
printf("mang sau khi da sap xep la:\n");
for (i = 0; i < n; i++) printf(" %d ", a[i]);
getch();
}
2. Hãy tìm phần tử d có trong mảng theo pp tìm kiếm nhị phân:
• Ý tưởng:
- Đối với những dãy số đã có thứ tự (giả sử thứ tự tăng), các phần tử
trong dãy có quan hệ a(i-1) <= a(i) <= a(i+1), từ đó kết luận được
nếu x>a(i) thì x chỉ có thể xuất hiện trong đoạn [a(i+1),a(n)] của
•
dãy, ngược lại nếu x
[a(i),a(i-1)] của dãy.
- Giải thuật tìm kiếm nhị phân áp dụng nhận xét trên đây để tìm cách
giới hạn phạm vi tìm kiếm sau mỗi lần so sánh x với một phần tử
trong dãy. Ý tưởng của giải thuật là tại mỗi bước tiến hành so sánh
x với phần ưử nằm ở vị trí giữa của dãy tìm kiếm hiện hành, dựa
vào kết quả so sánh này để quyết định giới hạn dãy tìm kiếm ở
bước kế tiếp là nữa trên hay nữa dưới của dãy tìm kiếm hiện hành.
Giả sử dãy tìm kiếm hiện hành bao gồm các phần tử
a(left)....a(right),
Các bước tiến hành như sau:
-
-
•
Bước 1: left=1; right = N; // tìm kiếm trên tất cả các phần tử
Bước 2: mid = (left+right)/2;//lấy mốc so sánh
So sánh a[mid] với x, có 3 khả năng:
+ a[mid] = x: Tìm thấy. Dừng lại.
+ a[mid]>x: // tìm tiếp x trong dãy con a(left)...a(mid-1):
right = mid-1;
+ a[mid]
left = mid+1;
Bước 3: Nếu left<=right //còn phần tử chưa xét=>tìm tiếp
Lặp lại Bước 2
Ngược lại: Dừng;//Đã xét hết phần từ
Code:
int Timkiem(int a[], int N, int x)
{
int left = 0, right = N - 1;
int mid;
do
{
mid = (left + right) / 2;
if (x == a[mid])
return mid;//Thấy x tại mid
else
if (x < a[mid])
right = mid - 1;
else left = mid + 1;
}
while (left <= right);
return -1;// tìm hết dãy mà không có x
}
3. Tìm phần tử lớn nhất trong mảng dùng đệ qui:
• Ý tưởng:
- Giải bài toán bằng cách rút gọn bài toán ban đầu thành bài toán
-
-
tương tự sau một số hữu hạn bước thực hiện.
Ở mỗi bước thực hiện, dữ liệu đầu sẽ vào tiệm cận tới dữ liệu
dừng.
Là thuật giải trong đó có chứa thao tác gọi đến chính nó.
Có thể dẫn đến tiến trình gọi đệ qui không kết thúc, do không
thỏa điều kiện dừng (“phần mốc”).
4. Sắp xếp mảng giảm dần theo phương pháp nổi bọt:
• Ý tưởng:
- Cho vòng lặp Si chạy từ 1 tới (Sn-1):
- Lần lặp 1: Si = 1, lần lược so sánh với các vị trí khác bắt đầu từ
(Si + 1) tức là vị trí 2, nếu phần tử thứ 1 bé hơn các phần tử đứng sau
bắt đầu từ 2 thì hoán vị chúng.
- Lần lặp 2: Si = 2, lần lược so sánh với các vị trí khác bắt đầu từ
(Si + 1) tức là vị trí 3, nếu phần tử thứ 2 bé hơn các phần tử đứng sau
nó bắt đầu từ 3 thì hoán vụ chúng.
- Cứ như vậy cho đến khi ta lặp lần thứ (Sn – 1), lúc này biến Si = (Sn1), ta so sánh với phần tử cuối cùng (Sn) và hoán vị nếu không thỏa
mãn.
• Code:
for(i=0;i
for(j=N-1;j>i;j--)
if(a[i]
{
hoandoi(a[i],a[j]);
}
5. Tìm phần tử d trong mảng theo pp tìm tuyến tính:
• Ý tưởng:
- Thuật toán tiến hành so sánh x lần lượt với phần tử thứ nhất, thứ hai ...
của mảng a cho đến khi gặp được phần tử có khóa cần tìm, hoặc đã
tìm hết mảng mà không thấy x.
• Các bước tiến hành như sau:
-
-
•
Bước 1: i = 1;// Bắt đầu phần tử đầu tiên của dãy.
Bước 2: So sánh a[i] với x, có 2 khả năng:
+ a[i] = x: Tìm thấy. Dừng
+a[i] khác x: Sang bước 3.
Bước 3: i = i+1; //xét phần tử kế tiếp trong mảng
Nếu i>N: Hết mảng, không tìm thấy. Dừng
Ngược lại: Lặp lại Bước 2.
Code:
int Timkiemtt(int a[], int N, int x)
{
int i = 0; //mảng gồm N phần tử từ a[0]...a[N-1]
a[N] = x; //thêm phần tử thứ N+1
while (a[i] != x)
i++;
if (i == N)
return -1; //tìm hết mảng nhưng không có x
else
return i; //tìm thấy x tại vị trí i
}
6. Tìm phần tử nhỏ nhất trong mảng (ko dùng đệ qui):
Ý tưởng:
- Gán min cho phần tử thứ nhất.
- Sau đó so sánh với các phần tử còn lại.
- Phần tử nào nhỏ hơn thì gán nó cho min;
• Code:
•
Int min(int *a,int n)
{
Int x;
x=a[0];
For(i=1;i
If (x>a[i]) x=a[i];
}
Return a[i];