Tải bản đầy đủ (.docx) (31 trang)

CÁC VẤN ĐỀ CẦN QUAN TÂM CÂU TRÚC DỮ LIỆU VÀ GIẢI THUẬT

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (398.29 KB, 31 trang )

CÁC VẤN ĐỀ CẦN QUAN TÂM
CÂU TRÚC DỮ LIỆU VÀ GIẢI THUẬT

1.Hãy nêu vai trò tổ chưc dữ lieu trong máy tính. Bộ nhớ máy vi tính chưa bộ mã nào,
Các hệ cơ số đếm trong máy tính, Cách chuyển đổi cơ số trong máy tính sang cơ số
thập phân.
 Vai trò tổ chức dữ liệu trong máy tính: Nhằm mục đích khai thác hiệu quả các dữ liệu

trong máy tính.
 Bộ nhớ máy tính chứa bộ mã:
 Các hệ cơ số đếm trong máy tính: Hệ nhị phân (cơ số 2), hệ thập phân (cơ số 10), hệ thập
lục phân (cơ số 16).
 Cách chuyển đổi cơ số trong máy tính sang cơ số thập phân:
Bảng quy tắc: binary (nhị phân), hex (thập lục phân), decimal (thập phân).
binary hex
decimal
0000 | 0 | 0
0001 | 1 | 1
0010 | 2 | 2
0011 | 3 | 3
0100 | 4 | 4
0101 | 5 | 5
0110 | 6 | 6
0111 | 7 | 7
1000 | 8 | 8
1001 | 9 | 9
1010 | A | 10
1011 | B | 11
1100 | C | 12
1101 | D | 13
1110 | E | 14


1111 | F | 15


-

Chuyển từ nhị phân sang thập phân:

Lấy số 1101 làm zí dụ:
1*(2^3) + 1*(2^2) + 0*(2^1) + 1*(2^0) = 13
Số 1 thứ nhất
1 * (2^3)
Số 1 thứ hai
1 * (2^2)
Số 0 thứ ba
0 * (2^1)
Số 1 thứ tư
1*(2^0)
1101 (binary) = 13 (decimal)
=> Số thứ nhất nhân với số 2 với số mũ cao nhất cộng cho số thứ hai nhân với số 2 với số mũ giảm
dần cứ thế….

-

Chuyển từ thập lục phân sang thập phân:

Để chuyển đổi từ hex sang decimal đầu tiên ta chuyển hex sang binary, sau đó lại từ binary ta chuyển
về decimal.
Lấy số FEED làm ví dụ:
Từ hex sang binary:
FEED (hex) = 1111 1110 1110 1101 (binary)

Từ binary sang decimal:
1*(2^15) + 1*(2^14) + 1*(2^13) + 1*(2^12) + 1*(2^11) + 1*(2^10) +1*(2^9) + 0*(2^8) + 1*(2^7)
+1*(2^6) +1*(2^5) + 0*(2^4) +1*(2^3) +1*(2^2) + 0*(2^1) + 1*(2^0) = 65261
Như vậy:
FEED (hex) = 1111111011101101 (binary) = 65261 (decimal)
Cách 2:
Tính luôn FEED= (15x16^3)+(14x16^2)+(14x16^1)+(13x16^0)=(15x4096)+
(14x256)+(14x16)+(13x1)=61440+3584+224+13=65261

2, Hãy nêu mối lien hệ cấu truc dữ liệu và giải thuật trong Công nghệ lập trình. Vai
trò chương trình của máy tính đóng vai trò gì trong xử lý thong tin.
 Mối liên hệ: Các cấu trúc dữ liệu và các giải thuật được xem như là 2 yếu tố quan trọng

nhất trong lập trình, đúng như câu nói nổi tiếng của Niklaus Wirth: Chương trình = Cấu
trúc dữ liệu + Giải thuật (Programs = Data Structures + Algorithms).
 Vai trò chương trình của máy tính trong xử lý thông tin: Chương trình máy tính giúp ta

xử lý thông tin một cách nhanh hơn, chính xác hơn, tiết kiệm được nhân lực. Xử lý các
bài toán lớn một cách dễ dàng hơn.


3. Hãy đưa các khái niêm các kiểu dữ liệu trong cấu truc dữ liệu máy tính.
- Tên loại dữ liệu (Cho Ví dụ)
- Miền giá trị dữ liệu (Cho Ví dụ)
- Kích cỡ lưu trữ.
- Tập các lệnh thao tác dữ liệu. (Cho Ví dụ)
Nhiều ngôn ngữ định nghĩa sẵn các kiểu dữ liệu thông dụng như:


integer: rất thông dụng, được dùng để biểu diễn các số nguyên.




char: biểu diễn các ký tự đơn lẻ.



string: biểu diễn chuỗi các kí tự, hay còn gọi là chuỗi, để tạo thành câu hay cụm từ.

Ví dụ: trong C++, kiểu integer thông dụng có tên là int và chiếm 2 byte; kiểu string là một dãy
các char, với kí tự NULL hoặc '/0' ở vị trí chuỗi kết thúc – dãy có thể dài hơn chuỗi nó lưu trữ.

4.

4. Anh (Chị) hiểu thế nào kiểu dữ liệu tĩnh và dộng (Cho Ví dụ) chi tiết từng loại bằng
C++


Tĩnh





Được định nghĩa ở thời điểm biên
dịch.
Được cấp phát ở thời điểm liên
kết.
Có thể có giá trị ban đầu tùy theo
từng ngôn ngữ lập trình.

Tồn tại đến khi kết thúc chương
trình.

Động





Được gắn kết với một con trỏ (tại
thời điểm biên dịch chưa có).
Phát sinh lúc thực thi.
Không xác định giá trị ban đầu.
Được giải phóng khỏi bộ nhớ khi cần.


5. Hãy liệt kê các loại dữ liệu dung trong C++ (Cho Ví dụ)
-Các kiểu dữ liệu trong C++:
Kiểu cơ sở :số nguyên ,số thực, kiểu logic
Kiểu mảng , chuôi
Kiểu có cấu trúc
1.Kiểu cơ sở:
Kiểu số nguyên
Stt

Tên kiểu

Ghi chú

Kích thước


Ký tự

1 byte

Số nguyên

1 byte

unsigned char

Số nguyên dương

1 byte

3

short

Số nguyên

2 bytes

4

unsigned short

Số nguyên dương

2 bytes


5

int

Số nguyên

4 bytes

6

unsigned int

Số nguyên dương

4 bytes

7

long

Số nguyên

4 bytes

1

char

2



8

unsigned long

Số nguyên dương

4 bytes

Kiểu số thực
Stt

Tên kiểu

Ghi chú

Kích thước

1

float

4 bytes

2

double

8 bytes


3

long double

8 bytes

Kiểu luận lý

Stt

Tên kiểu

1

Boolean

Ghi chú

Gồm 2 giá trị: true hoặc false

2.Kiểu mảng, chuỗi
Màng 1 chiều


Kích thước

Khai báo

<KDL> <Tên mảng> [<Số phần tử max>];

VD: int a[100];
 Khai báo kiểu con trỏ
<KDL> *<Tên mảng>;
VD: int *a;
 Gán giá trị ban đầu
VD1: int a[100] = {0};
VD2: int a[5] = {3, 6, 2, 10, 17};
hoặc: int a[] = {3, 6, 2, 10, 17};


Phát sinh ngẫu nhiên <time.h>
-

Khởi tạo phát sinh ngẫu nhiên
srand((unsigned int)time(NULL));

-

Phát sinh giá trị ngẫu nhiên
int x = rand()%k;
k: Số nguyên dương
x ∈ [0..k-1]

VD: Phát sinh 1 số nguyên có giá trị từ 0 đến 50
srand((unsigned int)time(NULL));
int x = rand()%51;
 Chuỗi


Khai báo


char <Tên chuỗi> [<Số ký tự max>] ;
VD: char hoten[50];


Khai báo theo con trỏ

char *<Tên chuỗi>;
VD: char *hoten;
 Lưu ý khi sử dụng phải cấp phát biến con trỏ bằng lệnh new, hủy bằng lệnh delete
VD:
int *a;
int n = 10;
a = new int[n];
…..
delete a;


3.Kiểu dữ liệu có cấu trúc
Khai báo
struct tên_struct
{
khai báo các thuộc tính;
};
typedef struct tên_struct tên_kiểu;
VD: struct ttDate
{
char thu[9];
unsigned char ngay;
unsigned char thang;

int nam;
};
typedef struct ttDate DATE;


Biến cấu trúc kiểu tĩnh

<tên biến>.thành phần cấu trúc
VD:
DATE d;
d.nam = 2012;


Biến cấu trúc kiểu con trỏ

<tên biến>thành phần cấu trúc
VD:


DATE *d;
dnam = 2012;

6. Nêu các giải thuật tìm kiếm(Search) trong công nghệ lập trình. Cho ít nhất hai ví
dụ của các giải thuật này (Mô tả bằng C++)
 Các giải thuật tìm kiếm



Có 2 giải thuật thường được áp dụng: Tìm tuyến tính và tìm nhị phân.
Đặc tả:

 Tập dữ liệu được lưu trữ là dãy số a , a , ... ,a .
1 2
N
 Khai báo: int a[N];
 Khóa cần tìm: int x;
Ví dụ:



Tìm kiếm tuyến tính

int tuyentinh(long a[], long n, int x)
{
int i=0;
while((ii++;
if (i==n)
return 0;
else
return i;
}
* Tìm kiếm nhị phân
int Timkiemnhiphan(long a[], long n, int p)
{


int First=1, Last=n;
while(First <=Last)
{
int Mid=(First + Last)/2;

if(p==a[Mid])
return Mid;
if(pLast=Mid-1;
else
First=Mid+1;
}
return -1;
}

7.Nêu các ví dụ nguyên tắc cài đặt hàm tìm kiếm bằng mã giả đê thực hiện tìm kiếm
theo thuật toán tuyến tính.
Nguyên tắc cài đặt hàm tìm kiếm


Nếu có xuất hiện phần tử có giá trị x thì trả về vị trí tìm được



Ngược lại thì trả về -1

Giải thuật
Bước 1:
i = 1;

// bắt đầu từ 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] != x : Sang Bước 3.


Bước 3:



i = i+1;
// xét tiếp phần tử kế 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.

8. Nêu các ví dụ nguyên tắc cài đặt hàm tìm kiếm bằng mã giả đê thực hiện tìm kiếm
theo thuật toán nhị phân.(Binary Search)
Nguyên tắc tìm kiếm



Nếu có xuất hiện phần tử có giá trị x thì trả về vị trí tìm được
Ngược lại thì trả về -1

 Giải thuật
Bước 1: left = 1; right = N; //tìm kiếm 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



a[mid] > x:

//tìm tiếp x trong dãy con aleft .. amid -1,right =mid - 1;



a[mid] < x:

//tìm tiếp x trong dãy con amid +1 .. aright,,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 tất cả các phần tử.

9. Hãy nêu 5 giải thuật sắp xếp căn bản, nêu ý tưởng của từng loại. Cho ví dụ ít nhất
hai giải thuật (Viết bằng NN C++)
Các giải thuật sắp xếp cơ bản




Đổi chổ trực tiếp – Interchange Sort




Chọn trực tiếp – Selection Sort



Chèn trực tiếp – Insertion Sort



Nổi bọt – Bubble Sort
Quick Sort

Ý Tưởng
Đổi chổ trực tiếp – interchange sort
-giải thuật là xuất phát từ đầu dãy, tìm tất cả nghịch thế chứa phần tử này, triệt tiêu chúng
bằng cách đổi chỗ phần tử này với phần tử tương ứng trong cặp nghịch thế. Lặp lại xử lý
trên với các phần tử tiếp theo trong dãy.
Giải thuật


Bước 1 : i = 1;// bắt đầu từ đầu dãy



Bước 2 : j = i+1;//tìm các phần tử a[j] < a[i], j>i



Bước 3 :
Trong khi j <= N thực hiện
Nếu a[j]

j = j+1;



Bước 4 : i = i+1;
Nếu i < N: Lặp lại Bước 2.
Ngược lại: Dừng.



Chọn trực tiếp – Selection Sort

-Chọn phần tử nhỏ nhất trong N phần tử ban đầu, đưa phần tử này về vị trí đúng là đầu dãy
hiện hành; lúc này dãy hiện hành chỉ còn N-1 phần tử cần sắp xếp, bắt đầu từ vị trí thứ 2; lặp
lại quá trình trên cho dãy hiện hành... đến khi dãy hiện hành chỉ còn 1 phần tử
Giải thuật
Bước 1: i = 1;


Bước 2: Tìm phần tử a[vtmin] nhỏ nhất trong dãy hiện hành từ a[i] đến a[N]
Bước 3: Hoán vị a[vtmin] và a[i]
Bước 4:
i = i+1
Nếu i < N thì lặp lại Bước 2
Ngược lại: Dừng.



Nổi bọt – Bubble Sort


Xuất phát từ cuối dãy, đổi chỗ các cặp phần tử kế cận để đưa phần tử nhỏ hơn trong cặp phần
tử đó về vị trí đúng đầu dãy hiện hành, sau đó sẽ không xét đến nó ở bước tiếp theo, do vậy ở
lần xử lý thứ i sẽ có vị trí đầu dãy là i. Lặp lại xử lý trên cho đến khi không còn cặp phần tử
nào để xét.
Giải thuật
Bước 1: i = 1;
Bước 2: j = N;
Trong khi (j > i) thực hiện:
Nếu a[j]j = j-1;
Bước 3: i = i+1;
Nếu i >N-1: Hết dãy. Dừng
Ngược lại: Lặp lại Bước 2.



Chèn trực tiếp – Insertion Sort

Cho dãy ban đầu a1 , a2 ,... ,an, ta có thể xem như đã có đoạn gồm một phần tử a1 đã được sắp,
sau đó thêm a2 vào đoạn a1 sẽ có đoạn a1 a2 được sắp; tiếp tục thêm a3 vào đoạn a1 a2 để có đoạn


a1 a2 a3 được sắp; tiếp tục cho đến khi thêm xong aN vào đoạn a1 a2 ...aN-1 sẽ có dãy a1 a2 .... aN
được sắp.
Giải thuật
Bước 1: i = 2;

// giả sử có đoạn a[1] đã được sắp

Bước 2: x = a[i];

Tìm vị trí pos thích hợp trong đoạn [1..i-1] để chèn a[i] vào
Bước 3: Dời chỗ các phần tử từ pos đến i-1 sang phải 1 vị trí để dành chỗ cho a[i]
Bước 4: a[pos] = x; // có đoạn a[1]..a[i] đã được sắp
Bước 5: i = i+1;
Nếu i ≤ N : Lặp lại Bước 2.
Ngược lại : Dừng.

Quick Sort
Chia dãy cần sắp thành 2 phần
Cách “chia”: ½ dãy bên trái chứa các giá trị nhỏ hơn ½ dãy bên phải
Thực hiện việc sắp xếp trên từng dãy con (đệ qui)
Giải thuật
Cho dãy aL, aL+1, … aR
Bước 1:
Phân hoạch dãy aL … aR thành các dãy con:


Dãy con 1: aL … aj < x



Dãy con 2: aj+1 … ai-1 =x



Dãy con 3: ai … aR > x

Bước 2:





Nếu (L


Nếu (i
Giải thuật phân hoạch dãy aL, aL+1, … aR thành 2 dãy con
Bước 1.1:
Chọn tùy ý một phần tử a[k] trong dãy, L≤k≤R
x=a[k], i=L, j=R
Bước 1.2:
Phát hiện và hiệu chỉnh cặp a[i] và a[j] nằm sai chỗ:
Bước 1.2a: Trong khi (a[i]Bước 1.2b: Trong khi (a[j]>x) j-Bước 1.2c: Nếu (i≤j): Hoán vị a[i] và a[j]; i++, j-Bước 1.3:
Nếu iNgược lại: Dừng phân hoạch

10. Hãy nêu độ phức tạp của 5 loại thuật toán sắp xếp căn bản, theo Anh (Chị) loại
nào có tốc đọ tìm kiếm nhanh nhất, loại nào chậm nhất.
trong đó O biểu diễn độ phức tạp của thuật toán đi kèm với một giá trị n biểu diễn kích thước
của số lần chạy tối đa mà thuật toán đó dựa vào để xử lý trên dữ liệu.
Đổi chổ trực tiếp – interchange sort O(n2)
Chọn trực tiếp – selection sort
O(n^2)
Nổi bọt – bubble sort
O(n^2)
Chèn trực tiếp – insertion sort O(n^2)
Quick sort

 Chi phí trung bình O(n*log2n)
 Chi phí cho trường hợp xấu nhất O(n2
Vì tốc độ sắp xếp có thể thay đổi rất nhiều tùy theo đặc điểm của dữ liệu, nên để các kết quả
thống kê chính xác dựa trên kinh nghiệm đòi hỏi việc chạy các thuật toán nhiều lần trên các dữ
liệu khác nhau và tính trung bình. Thông thường tập dữ liệu kiểm tra được tạo ngẫu nhiên.


quick sort có lẽ là thuật toán nhanh nhất, nhưng nếu sử dụng nó để sắp xếp một tập 20 phần tử
thì cũng giống như vác đại bác ra bắn ruồi
Tùy vào bài toán . nhưng nhìn chung thì Bubble sort là giải pháp cực kì không hiệu quả

11. Hãy đưa ra khái niệm danh sách lien kết đơn, nêu cách tổ chức dữ liệu động bằng
danh sách liên kết và minh họa được các thao tác xử lý trên danh sách liên kết đơn.
Khái niệm
Danh sách liên kết đơn: gồm một chuỗi các phần tử (node). Trong đó mỗi phần tử chứa dữ liệu
và địa chỉ để liên kết đến phần tử tiếp theo. Các phần tử kết dính với nhau bằng “sợi dây liên
kết”
Tổ chức dữ liệu động


Biến động

<kiểu dữ liệu> *tên biến;


Vd: int *a; float *y;
 Chứa địa chỉ của một đối tượng dữ liệu
 Được cấp phát hoặc giải phóng bộ nhớ tùy thuộc vào người lập trình
 Kích thước có thể thay đổi


Biến động
 Cấp phát bộ nhớ: new int [kích thước]
 Giải phóng bộ nhớ: delete vùng nhớ
 Ví dụ:


int *a;
a=new int [10]; // Cấp phát
//Các thao tác trên a
delete a;

// Giải phóng

Các thao tác trên DSLK đơn
1.Tạo lập danh sách rỗng

pHead và pTail chưa
xác định

?

?

List

pHead và pTail trỏ vào
NULL (rỗng)

pHead


pTail


List
pHead

pTail

Trước khi tạo lập

Sau khi tạo lập

void CreateEmptyList(LIST &list)
{
list.pHead = list.pTail = NULL;
}
2.Kiểm tra danh sách rỗng
pHead

List
pHead

Danh sách rỗng

pTail

bool IsEmptyList(LIST list)
{
return ((list.pHead==NULL) &&
(list.pTail==NULL));

}
3.Thêm nút vào danh sách
TH danh sách rỗng
List.pHead=p.New

30

List
p.Head

p.Tail
p.New


List.pTail=p.New
if(IsEmptyList(list))
{
list.pHead = list.pTail = pNew;
}
TH danh sách đã có phần tử

list

pHead

pTail

pNew
Có 2 TH thêm pNew vào danh sách :
+Thêm vào đầu danh sách


2

1

30

list

pHead

pTail

pNew

30

List

pHead

25

pTail

25


List


25
pHead

30

pTail

pNew->pNext = list.pHead

1

list.pHead = pNew

2

+Thêm vào cuối danh sách

30

List

pHead

1

25

pTail

pNew


2
1

list.pTail->pNext = pNew

2

list.pTail = pNew

List

30
pHead

25

4

pTail
pNew


Chèn node vào DSLK đơn


Chèn vào sau node p

p


pNew

List

pHead



pTail

Chèn vào trước node p
+Cách 1

pNew

pPre

p

List

pHead

+Cách 2:

pTail

Bước 1. Chèn pNew vào sau p



Bước 2. Hoán vị giá trị pNew và p

p

pNew

List

Xóa một nút trong danh sách


pHead
pTail
Xóa nút đầu của
danh sách  Ảnh hưởng pHead
Cần xóa
41

pHead
hhh
pHead
pDel
sssss

List

pTail

30


25

41

78

NODE *pDel = list.pHead
list.pHead = list.pHead->pNext
delete pDel
pPrev Xóa nút cuối của danh sách  Ảnh hưởng pTail

pDel

Cần xóa


List

30
pHead

78

41

25

pTail

NODE *pDel = list.pTail

NODE *pPrev = “Tìm node trước pTail
pPrev->pNext = NULL
list.pTail = pPrev
delete pDel


Xóa nút giữa danh sách

pPrev
pDel

Cần xóa

41

List

30
pHead

pTail

NODE *pPrev = “Tìm node trước pDel”
pPrev->pNext = pDel->pNext
delete pDel

25

41


96

78


LƯU ĐỒ THUẬT TOÁN
Viết lưu đồ chương trình cho phép nhập vào một số nguyên dương N. In ra màn
mình cho biết số đảo ngược của số N. ( Ví dụ: N=12345 sẽ có số đảo là 54321 )

BẮT ĐẦU

n, sdn=0

Sai

n>0

Đúng
sdn=n*10+n%10
n=n/10

KẾT THÚC

Xuất sdn


Mảng 1 chiều

Bắt đầu


a[], n, i=0

i
Sai

Đúng
Nhập a[i]

i++

Kết thúc


Kiểm tra mảng đã cho có đối xứng không

Bắt đầu

a[], n, kt=1, i=0

ĐS

Sai

i<(n-2)/2

Đúng

Đúng
a[i]!=a[n-i-1]


Mảng đối xứng

Sai

i++

Kết thúc

Mảng không đối xứng


×