17521294 (2).docx

You might also like

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 14

1.

Vì sao các ngôn ngữ lập trình thường cung cấp trước một số kiểu dữ
liệu cơ bản? Giải thích mục đích của việc này?

Programming languages often provide some basic data types because they are extremely
common and are used frequently by programmers.
Another, we need them to simplify some complicated data types into basic data types, it will
easy for us to handle this.

2. Có nên định nghĩa thêm các kiểu dữ liệu mới từ các kiểu dữ liệu cơ
bản? Khi
nào ta cần làm việc này?
Encapsulation - Because each user-defined data type exist as a complete entity, including the
data definitions, default values, and value constraints, this entity insures uniformity and
consistency. Once defined, a user-defined data type may participate in many other user-
defined data types, such that the same logical data type, always has the same definition, default
values and value constraints, regardless of where it appears in the database.
Reusability - As a hierarchy of common data structures are assembled, these can be re-used
within many definitions, saving coding time and insuring uniformity.
Flexibility - The ability to create real-world data representations of data allows the database
object designer to model the real world as it exists

3. Cho 3 ví dụ minh họa về mối quan hệ giữa cấu trúc dữ liệu và thuật
toán.
EX1:

Với 1 mảng các số nguyên chưa được sắp xếp thì để tìm một phần từ có giá trị x chỉ có thể tìm kiếm tuần
tự từ đầu đến cuối. Nhưng nếu đã được sắp xếp thì có thể tìm rất nhanh bằng thuật toán binarysearcH.

EX2:

Dữ liệu gồm họ tên và Địa chỉ và bài toán tìm kiếm địa chỉ theo tên.

Nếu họ tên sắp xếp không theo thứ tự thì ta phải xét lần lượt từ đầu đến cuối. Nhưng nếu tên
được sắp sếp theo thứ tự a,b,c ta có thể tìm theo thuật toán tìm kiếm nhị phân chia đôi và tìm nửa có
chứa kết quả có thể tiếp kiệm được rất nhiều thời gian.

EX3:

Một chương trình quản lý điểm thi của sinh viên cần lưu trữ các điểm số của n sinh viên. Do
mỗi sinh viên có 4 điểm số ứng với 4 môn học khác nhau, nếu như chúng ta lưu dữ liệu này
vào một mảng 1 chiều ,thì việc để truy xuất điểm của 1 sinh viên ,hay điểm 1 môn của các sinh
viên rất phức tạp.
Nên thay vì lưu dữ liệu vào bảng 1 chiều thì chúng ta sử dụng mảng 2 chiều ,với cột tượng
trưng cho điểm các môn học và dòng tương ứng với các sinh viên.
Nên muốn lấy thông tin của 1 sinh viên nào đó hay là diểm tất cả các sinh viên của 1 môn thì
ta chỉ cần truy xuất cột và hang tương ứng.

4. Cho ví dụ minh họa để giải thích cho câu phát biểu sau:“Một cấu trúc
dữ liệu tồi, không thể cứu vãn được một thuật toán tốt” .
EX: Binary search là một thuật toán tốt với độ phức tạp log n,được áp dụng với mảng đã được sắp xếp.

Nhưng với những dãy chưa được sắp xếp thì ,thuật toán tìm kiếm chỉ có thể có độ phức tạp là 0(n)

Rõ rang là dữ liệu được sắp xếp sẽ giúp thời gian của việc tìm kiếm được giảm đi rất nhiều.

5. Khi tiếp cận để giải quyết một vấn đề hoặc bài toán, bạn thường quan
tâm đến xây dựng cách thức tổ chức, quản lý dữ liệu trước hay cách
thức giải quyết vấn đề hoặc bài toán trước? Vì sao? Cho ví dụ minh họa
để giải thích.
Em thường quan tâm đến cách thức tổ chức và quản lý dữ liệu trước ,vì nó sẽ giúp cho chúng ta sắp xếp
các dòng code 1 cách hiệu quả và dễ hiểu ,tìm kiếm hơn.Quản lý dữ liệu sẽ giúp ta tiết kiệm bộ nhớ một
cách tối đa ,tránh bị tràn khi bị giới hạn bộ nhớ , và từ đó chúng ta sẽ có một giải thuật hiệu quả cho vấn
đề

6. Hãy trình bày ngắn gọn tư tưởng của các giải thuật sắp xếp?
*Bubble sort:

- Is a sorting algorithm that works by swapping the adjacent elements if they are in wrong order
to put the elements has the highest value to the right most of the array .
- Then we repeated this work with the array leaving out the highest element we put before .

- we can stop the algorithm if inner loop didn’t cause any swap.
*Selection sort :
- Is a sorting algorithm that work by finding the lowest value and then swapped it with the
value in the current position .
- Then we repeat this work for all elements until the entire array is sorted.
*Insertion sort : Insertion sort: removes an element from the input data and inserts it into the correct
position in the list being sorted. This process is repeated until all input elements have gone through

*Merge sort :
- Merge Sort is a Divide and Conquer algorithm . It divides input array in two halves, calls itself
for the two halves and then the two halves will repeat this work until the array divided into one
by one element, then we merges the two sorted halves .
*Quick sort :
- Merge Sort is a Divide and Conquer algorithm. It picks an element as key and partitions the
given array around the picked key
-Then we will sort the sub-array so that the element are larger than the following key are put to
the right and smaller element than the key element in front (left).
- Then we repeat 2 works before with the sub array

7. Giả sử sử dụng hàm Random trong C/C++ để phát sinh


ngẫu nhiên dãy số nguyên có kích thước 100, 1.000, 5.000,
10.000, 50.000 số. Hãy cài đặt các giải thuật sắp xếp để sắp
dãy số nguyên đã cho theo thứ tự tăng dần và nhận xét về
thời gian thực hiện của các giải thuật.
For N=100:

For N=1000

For N=5000

For N=10000
For N=50000

Nhận xét:
Khi n còn quá nhỏ (n=100)thì chúng ta chưa thể nào so sánh đc thời gian của các thuật toán
sắp xếp.
Nhưng khi n đủ lớn n>1000 ,thì chúng ta thấy rõ được là thời gian sắp xếp của các thuật toán
đều theo thứ tự Bubble >Selection>Insertion>Merge >Quick.
Và ta cũng nhận ra rằng thời gian sắp xếp của merge và quick so với 3 thuật sắp xếp cơ bản là
nhanh hơn rất rất nhiều,do đó ta thấy được sự hiệu quả của 2 thuật sắp xếp này
Code:
#include<iostream>
#include<time.h>
using namespace std;
void swap(int& a, int& b)
{
int temp = a;
a = b;
b = temp;
}
void bubblesort(int *a, int n)
{
for (int i = 0; i < n - 1; i++)
for (int j = 0; j < n - i - 1; j++)
if (a[j] > a[j + 1]) swap(a[j], a[j + 1]);
}
void selection(int *a, int n)
{
for (int i = 0; i < n; i++)
{
int min = i;
for (int j = i + 1; j < n; j++)
if (a[i] < a[min]) min = i;
swap(a[i], a[min]);
}
}
void insertionsort(int *a, int n)
{
int key;
for (int i = 1; i <= n - 1; i++)
{
key = a[i];
int j = i;
while (a[j - 1] > key && j >= 1) {
a[j] = a[j - 1];
j--;
}
a[j] = key;
}
}
void merge(int *a, int left,int right,int m)
{
int n1 = m -left + 1;
int n2 = right - m;
int i, j,k;
int *l = new int[n1];
int *r = new int[n2];
for ( i = 0; i < n1; i++)
{
l[i] = a[i];
}

for (j = 0; j < n2; j++)


{
r[j] = a[j + m + 1];
}
i = 0;
j = 0;
k = left;
while (i < n1 && j < n2)
{
if (l[i] <= r[j])
{
a[k] = l[i];
i++;
}
else
{
a[k] = r[j];
j++;
}
k++;
}
while (i < n1)
{
a[k] = l[i];
i++;
k++;
}
while (j < n2)
{
a[k] = r[j];
j++;
k++;
}
}
void mergeSort(int arr[], int left, int right)
{
if (left < right)
{
int m = left + (right - left) / 2;
mergeSort(arr, left, m);
mergeSort(arr, m + 1, right);
merge(arr, left, right, m);
}
}
int partition(int arr[], int low, int high)
{
int pivot = arr[high];
int left = low;
int right = high - 1;
while (true) {
while (left <= right && arr[left] < pivot) left++;
while (right >= left && arr[right] > pivot) right--;
if (left >= right) break;
swap(arr[left], arr[right]);
left++;
right--;
}
swap(arr[left], arr[high]);
return left;
}
void quickSort(int arr[], int low, int high)
{
if (low < high)
{
int pi = partition(arr, low, high);
quickSort(arr, low, pi - 1);
quickSort(arr, pi + 1, high);
}
}
int main()
{
int n;
cin >> n;
int *a = new int[n];
int *b = new int[n];
int *c = new int[n];
int *d = new int[n];
int *e = new int[n];
for (int i = 0; i < n; i++)
{
a[i] = rand();
c[i] = a[i];
d[i] = a[i];
e[i] = a[i];
b[i] = a[i];
}
clock_t begin = clock();
bubblesort(a, n);
clock_t end = clock();
cout << "Bubble sort -Time run: " << (float)(end - begin) / CLOCKS_PER_SEC << " s"
<< endl;
clock_t begin1 = clock();
selection(b, n);
clock_t end1 = clock();
cout << "Selection sort -Time run: " << (float)(end1 - begin1) / CLOCKS_PER_SEC <<
" s" << endl;
clock_t begin2 = clock();
insertionsort(c, n);
clock_t end2 = clock();
cout << "Insertion sort -Time run: " << (float)(end2 - begin2) / CLOCKS_PER_SEC <<
" s" << endl;
clock_t begin3 = clock();
mergeSort(d, 0, n);
clock_t end3 = clock();
cout << "Merge sort -Time run: " << (float)(end3 - begin3) / CLOCKS_PER_SEC << "
s" << endl;
clock_t begin4 = clock();
quickSort(e, 0,n);
clock_t end4 = clock();
cout << "Quick sort -Time run: " << (float)(end4 - begin4) / CLOCKS_PER_SEC << "
s" << endl;
delete []a;
delete []b;
delete []c;
delete []d;
delete []e;
system("pause");
return 0;

}
9.Hãy viết chương trình cài đặt giải thuật Quick
sort, so sánh thời gian chạy giải thuật khi lấy x là
phần tử chính giữa dãy, đầu dãy, cuối dãy và không
dùng kỹ thuật đệ qui.
N=100000

CODE:
#include<iostream>
#include<time.h>
using namespace std;
void swap(int &a, int &b)
{
int temp = a;
a = b;
b = temp;
}
int partitionfirst(int *a, int left, int right )
{

int pivot = a[left], p1 = left + 1, i, temp;

for (i = left + 1; i <= right; i++)


{

if (a[i] < pivot)


{
if (i != p1)
{
temp = a[p1];
a[p1] = a[i];
a[i] = temp;
} p1++;
}
}

a[left] = a[p1 - 1];


a[p1 - 1] = pivot;

return p1 - 1;
}
void quicksortfirst(int *a, int left, int right)
{
int p1;
if (left < right)
{
p1 = partitionfirst(a, left, right);
quicksortfirst(a, left, p1 - 1);
quicksortfirst(a, p1 + 1, right);
}
}
int partitionlast(int a[], int left, int right)
{
int pivot = a[right];
int l = left;
int r = right - 1;
while (true) {
while (l <= r && a[l] < pivot) l++;
while (r >= l && a[r] > pivot) r--;
if (l >= r) break;
swap(a[l], a[r]);
l++;
r--;
}
swap(a[l], a[right]);
return l;
}
void quickSortlast(int a[], int left, int right)
{
if (left < right)
{
int pi = partitionlast(a, left, right);
quickSortlast(a, left, pi - 1);
quickSortlast(a, pi + 1, right);
}
}
void quickSortMiddle(int*a, int left, int right)
{
if (left >= right) return;
int pivot = a[left + (right - left) / 2];
int l = left - 1;
int r = right + 1;
while (1)
{
while (a[++l] < pivot);
while (a[--r] > pivot);
if (l >= r)break;
swap(a[l], a[r]);
}
quickSortMiddle(a, left, r);
quickSortMiddle(a, r + 1, right);
}
int main()
{
int n;
cin >> n;
int *a = new int[n];
int *b = new int[n];
int *c = new int[n];
for (int i = 0; i < n; i++)
{
a[i] = rand();
c[i] = a[i];
b[i] = a[i];
}
clock_t begin = clock();
quicksortfirst(a, 0, n);
clock_t end = clock();
cout << "first element -Time run: " << (float)(end - begin) / CLOCKS_PER_SEC << "
s" << endl;
clock_t begin2 = clock();
quickSortMiddle(b, 0, n);
clock_t end2 = clock();
cout << "middle element -Time run: " << (float)(end2 - begin2) / CLOCKS_PER_SEC <<
" s" << endl;
clock_t begin3 = clock();
quickSortlast(c, 0, n);
clock_t end3 = clock();
cout << "last element -Time run: " << (float)(end3 - begin3) / CLOCKS_PER_SEC << "
s" << endl;
system("pause");
return 0;

10. Trong ba giải thuật sắp xếp chọn trực tiếp, chèn trực tiếp
và nổi bọt, giải thuật nào thực hiện sắp xếp nhanh nhất nếu
cho một dãy đã có thứ tự, giải thích và cho ví dụ minh họa.
Nếu ta cho trước một dãy đã có thứ tự ,thì thuật toán sắp xếp thực hiện nhanh nhất sẽ là
Insertion sort , lí do:
+Bubble sort:

Theo như code thì dù chúng ta có cho trước một dãy đã sắp sếp thì ta vẫn phải chạy qua 2
vòng for n^2 lần.
+Selection sort:

Tương tự như Bubble sort, dù có cho trước một dãy đã có thứ tự thì chúng ta vẫn phải chạy
qua 2 vòng for lồng nhau n^2 lần.
+Insertion sort

Nhưng với thuật toán sắp xếp chèn trực tiếp ,dù vẫn có 2 vòng lặp lồng nhau là for với
while,nhưng vòng while điều kiện trong while sẽ không bao giờ đúng vì các phần tử trong dãy
đã có thứ tự tang dần, a[j-1] luôn bé hơn k.

11, Dựa trên ý tưởng của giải thuật chèn trực tiếp, hãy trình bày ý tưởng
cải tiến giải thuật này sao cho độ phức tạp trong trường hợp tốt nhất là
O(Nlog2N).
We can use binary search to reduce the number of comparisons in normal insertion sort. Binary Insertion Sort
uses binary search to find the proper location to insert the selected item at each iteration.
In normal insertion sort, it takes O(n) comparisons in worst case. We can reduce it to O(log n) by using binary
search.

Code:

int binarySearch(int a[], int item, int low, int high)


{
if (high <= low)
return (item > a[low]) ? (low + 1) : low;

int mid = (low + high) / 2;

if (item == a[mid])
return mid + 1;

if (item > a[mid])


return binarySearch(a, item, mid + 1, high);
return binarySearch(a, item, low, mid - 1);
}

// sort an array a[] of size 'n'


void insertionSort(int a[], int n)
{
int i, location, j, k, selected;
for (i = 1; i < n; ++i)
{
j = i - 1;
selected = a[i];

// find location where selected sould be inseretd


location = binarySearch(a, selected, 0, j);

// Move all elements after location to create space


while (j >= location)
{
a[j + 1] = a[j];
j--;
}
a[j + 1] = selected;
}
}
12,Hãy trình bày ưu điểm và hạn chế của các giải thuật sắp xếp, đề
xuất cách tốt nhất để khắc phục hạn chế của các giải thuật này.
Bubble Sort
Advantages Disadvantages
The primary advantage of the The main disadvantage of the bubble
bubble sort is that it is popular and sort is the fact that it does not deal
easy to implement. well with a list containing a huge
number of items.
In the bubble sort, elements are The bubble sort requires n-squared
swapped in place without using processing steps for every n number
additional temporary storage. of elements to be sorted.
The space requirement is at a The bubble sort is mostly suitable for
minimum academic teaching but not for real-
life applications.
It can be optimized by stopping the algorithm if inner loop didn’t cause any swap with the signal.
Insertion Sort

Advantages Disadvantages
The main advantage of the insertion The disadvantage of the insertion
sort is its simplicity. sort is that it does not perform as
well as other, better sorting
algorithms
It also exhibits a good performance With n-squared steps required for
when dealing with a small list. every n element to be sorted, the
insertion sort does not deal well with
a huge list.
The insertion sort is an in-place The insertion sort is particularly
sorting algorithm so the space useful only when sorting a list of few
requirement is minimal. items.
Selection Sort

Advantages Disadvantages
The main advantage of the selection The primary disadvantage of the
sort is that it performs well on a selection sort is its poor efficiency
small list. when dealing with a huge list of
items.
Because it is an in-place sorting The selection sort requires n-squared
number of steps for sorting n elements.
algorithm, no additional temporary
storage is required beyond what is
needed to hold the original list.
Its performance is easily influenced by the Quick Sort is much more efficient
initial ordering of the items before the than selection sort
sorting process.
The idea is to take also the maximum on every pass and place it at its correct position. So in every
pass, we keep track of both maximum and minimum and array becomes sorted from both ends.
Quick Sort

Advantages Disadvantages
The quick sort is regarded as the The slight disadvantage of quick sort
best sorting algorithm. is that its worst-case performance is
similar to average performances of
the bubble, insertion or selections
sorts.
It is able to deal well with a huge list If the list is already sorted than
of items. bubble sort is much more efficient
than quick sort
Because it sorts in place, no If the sorting element is integers than
additional storage is required as radix sort is more efficient than quick
well sort.
Quicksort is the fastest comparison-based sorting algorithm for many types of data. However, in some
cases there are better options. Insertion sort, which has quadratic worst-case time, tends to be faster
for small lists.
Merge Sort

Advantages Disadvantages
It can be applied to files of any size. Requires extra space »N
Reading of the input during the run- Merge Sort requires more space than
creation step is sequential ==> Not other sort.
much seeking.
If heap sort is used for the in- Merge sort is less efficient than other
memory part of the merge, its sort
operation can be overlapped with
I/O
Use insertion sort for small subarray . We can improve most recursive algorithms by handling small
cases differently. Switching to insertion sort for small subarrays will improve the running time of a
typical merge sort implementation
Test whether array is already in order. We can reduce the running time to be linear for arrays that are
already in order by adding a test to skip call to merge() if a[mid] is less than or equal to a[mid+1]. With
this change, we still do all the recursive calls, but the running time for any sorted subarray is linear.

You might also like