Post on 14-Jan-2016
description
1
•Xin vui lòng yên lặng
2
Chương 1: Các kiểu dữ liệu cơ bản và cấu trúc
3
Định nghĩa và các phép toán trên danh sách đặc
• Định nghĩa• Cách biểu diễn và các phép toán trên danh sách
đặc- Khởi tạo danh sách- Thêm một phần tử vào danh sách- Loại bỏ một phần tử của danh sách- Tìm kiếm một phần tử của danh sách- Duyệt danh sách
4
1. Mảng (Array) – Định nghĩa
• Định nghĩa: Mảng là cấu trúc bao gồm các thành phần cùng kiểu dữ liệu, mỗi thành phần được gọi là phần tử và xác định qua chỉ số.
Trong C/C++ khai báo:elem a[spt];
Trong đó elem là kiểu phần tử (element type); spt là số phần tử.
Ví dụ:int a[10]; //mảng a gồm 10 phần tử kiểu intfloat b[20]; //mảng b gồm 20 phần tử kiểu float
5
Tổ chức lưu trữ
• Mảng được quản lý bằng một địa chỉ trong bộ nhớ máy tính và các phần tử được bố trí tuần tự liên tiếp theo chỉ số
• Chính vì vậy dãy dữ liệu lưu trữ trong mảng còn được gọi là danh sách đặc
0 1 2 9
a
6
Truy xuất
• Truy xuất mảng: Truy xuất qua các phần tử của mảng theo chỉ số i.
Trong C/C++:
<tên mảng>[i]
Bằng cách tính địa chỉ:
@a + i * sizeof(elem)
Ví dụ: a[3] truy xuất đến địa chỉ: 1000+3*21000 1006
0 1 2 9
a
3
7
Ví dụ
• Viết đoạn chương trình cộng dồn n giá trị của mảng vào a[0]for (i=1; i<n; i++)
a[0] = a[0]+a[i]; Viết lại
t = a[0];for (i=1; i<n; i++)
t = t+a[i];a[0] = t;
8
Mảng nhiều chiều
• Là mảng bao gồm các phần tử có kiểu là mảng
vd: int a[3][4];
Vd: viết hàm tìm max của mảng số nguyên
0 1 2 1
a
3 0
a[0] a[1] a[2]
9
int max( int a[ ], int n)
{
int m = a[0];
for (int i=1; i<n; i++)
if (a[i]>m)
m = a[i];
return m;
}
10
void main(){
int b[3][4] = { { 7, 12, 6, 8},{ 32, 17, 21, 23},{ 1, 5, 35, 32}};
int a[] = {9, 7, 18, 6, 1, 3, 2, 5, 11, 4};printf("\nMax cua b: %d", max(b[0], 12));printf("\nMax cua a: %d", max(a, 10));printf("\nMax : %d", max(a+5, 5));
}
0 1 2 1
b
3 0
b[0] b[1] b[2]
11
Con trỏ?• Con trỏ: Là kiểu dữ liệu dang địa chỉ bộ nhớ
máy tính
• Biến con trỏ: Lưu trữ địa chỉ của vùng nhớ máy tính
• Khai báo:
<type> *<pointer_var>
Ví dụ:
float *pa, a, b;
pa
*pa
12
Các phép toán• Toán tử &:
Lấy địa chỉ của 1 đối tượng
&<object>
Ví dụ:
float *pa, a, b;
pa = &a;
*pa
apa
13
Các phép toán• Toán tử *:
Truy xuất đến vùng nhớ mà con trỏ trỏ đến
*<pointer>
Ví dụ:
float *pa, a, b;
pa = &a;
*pa = 5;*pa
a
pa
5
14
Mảng và con trỏ
• Mảng được quản lý bằng địa chỉ
• Con trỏ lưu địa chỉ
Vì vậy, trong một số tình huống con trỏ được đồng nhất với mảng và ngược lại
Ví dụ:
int a[10], *pa;
pa = a;
0 1 2 9
a
3
pa
15
Mảng và con trỏ - tt*pa = 5; a[0]=5
pa = &a[5];
*pa = 7; a[5]=7
0 1 2 9
a
3
pa
5
0 1 2 9
a
3
pa
5 7
16
Phép toán +, -, ++, --• Phép +/-: Tăng hay giảm n đơn vị trỏ
<pointer> = <pointer> + n
<pointer> += n
n là số nguyên
• Phép ++/--: Tăng hay giảm 1 đơn vị trỏ
<pointer> ++
++<pointer>
Ví dụ:
pa = a;
17
Ví dụ:
pa = a;
pa = pa+3;
0 1 2 9
a
3
pa
5
0 1 2 9
a
3
pa
5
18
*pa=1; a[3]=1
*(pa+4) = 2 a[7]=2
*(a+4) = 9 a[4]=9
pa[5] = 6 a[8]=6
a++; // Sai, a không thay đổi được
0 1 2 9
a
3
pa
5 1 29 6
19
Cấp phát/thu hồi bộ nhớ
• Cấp phát bộ nhớ động– C: hàm malloc()
(void *)malloc(int size)
Cấp vùng nhớ có size byte trả về địa chỉ của vùng nhớ được cấp phát– C++: toán tử new
new <type>[size]
[size] là thành phần nhiệm ý
Cấp vùng nhớ có size phần tử trả về địa chỉ của vùng nhớ được cấp phát
Ví dụ cấp phát mảng 10 phần tử nguyên
int *pa = new int[10];
20
Cấp phát/thu hồi bộ nhớ - tt• Thu hồi bộ nhớ
– C: hàm free()
void free(<pointer>)– C++: toán tử delete
delete [size]<type>
[size] là thành phần nhiệm ý
Thu hồi vùng nhớ mà con trỏ trỏ đến
Ví dụ thu hồi vùng nhớ mà con trỏ pa trỏ đến
delete pa [10]int;
21
Chuỗi ký tự (String)
• Định nghĩa: Là 1 dãy các ký tự chọn lọc
• Cài đặt: Dựa trên mảng các ký tự, có 2 cách cài đặt– Cách 1: Sử dụng byte đầu tiên để lưu chiều dài
chuỗi (Pascal sử dụng cách này).
Ví dụ chuỗi “TIN HOC”
S[8]=‘A’ S=“TIN HOC”
S[2]=‘A’ S=“TAN HOC”
#7 T I N
0 1 2 3 4
H O C
5 6 7 8
22
–Cách 2: Sử dụng 1 ký tự đặc biệt làm ký tự kết thúc chuỗi (C/C++ sử dụng cách này).
Ví dụ chuỗi “TIN HOC”
‘\0’: kí tự có mã ASCii là 0
S[1]=‘A’ S=“TAN HOC”
T I N
0 1 2 3 4
H O C
5 6 7 8
\0
23
Các thao tác trên chuỗi• Sao chép chuỗi (strcpy)
• So sánh chuỗi (strcmp)
• Chiều dài chuỗi (strlen)
• Ghép chuỗi (strcat)
• Tìm kiếm vị trí chuỗi trong chuỗi (strstr)
• …..
24
VD sao chép chuỗi
void strcpy(char s1[], char s2[])
{
int i = 0;
while (s2[i] != ‘\0’)
{
s1[i] = s2[i];
i++;
}
s1[i] = ‘\0’;
}
25
VD sao chép chuỗi – viết lại
void strcpy(char s1[], char s2[])
{
int i = 0;
while (s1[i] = s2[i])
i++;
}
26
VD sao chép chuỗi – viết lại lần cuốivoid strcpy(char *s1, char *s2)
{
while (*s1++ = *s2++);
}
• Ghép s2 vào cuối s1
void strcat(char *s1, char *s2)
{
while (*s1) s1++;
while (*s1++ = *s2++);
}
27
Ghép chuỗi – viết theo bản 2
void strcat(char s1[], char s2[])
{
int i = 0, j=0;
while (s1[i]) i++;
while (s1[i++] = s2[j++]);
}
28
Đổi chuỗi thành số
int atoi(char *s)
{
int P = 0;
while (*s)
P = P*10 + *s++ -’0’;
return P;
}
29
So sánh 2 chuỗi
int strcmp(char *s1, char *s2){
while (*s1 == *s2 && *s1){
s1++; s2++;
}return *s1-*s2;
}
30
Trừu tượng hóa dữ liệu• Thiết kế 1 cấu trúc dữ liệu cần đạt được tính
trừu tượng hóa dữ liệu:– Dữ liệu phải được đóng gói: Người lập trình chỉ biết
kiểu dữ liệu qua tên gọi và ngữ nghĩa của nó mà không quan đến tổ chức vật lý
– Che chắn tốt: Người lập trình chỉ truy xuất đến nó thông qua các thao tác (hàm) mà kiểu dữ liệu cung cấp.
• Người thiết kế phải thiết kế kiểu dữ liệu tổng quát nhất
31
Ví dụ: Thiết kế kiểu tập hợp
#define MAX … // do người sử dụng xác định#define N (MAX/8+1)typedef unsigned char taphop[N];//============== Tao tap rong =========void taprong(taphop s){
int i;for (i=0; i<N; i++)
s[i] = 0;}
32
//========== Dua phan tu x vao tap hop svoid thempt(taphop s, int x){
s[x/8] = s[x/8] | (1<<(x%8));}
//========== Loai phan tu x ra khoi tap hop svoid loaipt(taphop s, int x){
unsigned char k = 1<<(x%8);s[x/8] = s[x/8] & ~k;
}
33
//========== Kiem tra phan tu x thuoc tap hop sint thuocve (taphop s, int x){
return s[x/8] & (1<<(x%8));}//========== Hội 2 tap hopvoid hoi(taphop a, taphop b, taphop c){
int i;for (i=0; i<N; i++)
c[i] = a[i] | b[i];}Các hàm này lưu vào tập tin “TAPHOP.CPP” và không compile
34
Ví dụ: Tìm các số nguyên tố<=n#include <iostream.h>#include <iomanip.h>#define MAX 10000#include "TAPHOP.CPP"
void main(){
int n, i, k;taphop s;cout<<"\nNhap n:";cin>>n;taprong(s);for (i=2; i<=n; i++)
thempt(s, i);i = 2;while (i*i<=n){
k = i*i;while (k<=n){
loaipt(s, k);k = k+i;
}do
i++;while (!thuocve(s, i));
}cout<<"\nKet qua:\n";for (i=2; i<=n; i++)
if (thuocve(s, i))cout<<setw(4)<<i;
}
35