K  THU T L P TRÌNH Chương 2 Kỹ thuật xử lý dữ liệu có cấu trúc (12 tiết)

minhthai@huflit.edu.vn, www.minhthai.edu.vn

Ầ Ạ

phamducthanh@huflit.edu.vn,

TR N MINH THÁI –  Ứ PH M Đ C THÀNH –   www.phamthao.com

1 9/17/16 Trần Minh Thái - Phạm Đức Thành

Nội dung

v 2.1. Giới thiệu v 2.2. Kỹ thuật xử lý và tổ chức dữ liệu biểu

diễn danh sách

v 2.3. Kỹ thuật xử lý mảng v 2.4. Thuật toán xử lý chuỗi v 2.5. Phương pháp biểu diễn đồ thị và

thuật toán cơ bản

v 2.6. Tổ chức dữ liệu biểu diễn cấu trúc

cây

v 2.7. Tóm tắt chương

2 9/17/16 Trần Minh Thái - Phạm Đức Thành

[2.1] Giới thiệu

v Tìm hiểu về các kỹ thuật xử lý trên kiểu dữ diệu người dùng tự định nghĩa như: danh sách (list), mảng (array), chuỗi (string), cây (tree)..

v C# hỗ trợ rất tốt về dữ liệu có cấu trúc và các

thao tác trên đó thông qua: Ø Namespace System.Collections. Ø Namespace System.Collections.Generic.

3 9/17/16 Trần Minh Thái - Phạm Đức Thành

[2.2] Kỹ thuật xử lý và tổ chức dữ liệu biểu diễn danh sách

v Khái niệm. v Tổ chức dữ liệu bằng danh sách (list). v Kỹ thuật xử lý danh sách.

4 9/17/16 Trần Minh Thái - Phạm Đức Thành

Khái niệm danh sách

v Một tập sắp theo thứ tự các phần tử có cùng

kiểu.

v Cấu trúc dữ liệu tuyến tính, trong đó các phần tử dữ liệu được sắp theo một thứ tự xác định.

5 9/17/16 Trần Minh Thái - Phạm Đức Thành

Khái niệm danh sách

v Một số thao tác:

Ø Kiểm tra danh sách có rỗng không. Ø Đếm số phần tử theo tiêu chí xác định

trước.

Ø Tìm một phần tử trong danh sách. Ø Chèn một phần tử vào danh sách. Ø Xóa một phần tử khỏi danh sách. Ø Sắp xếp theo tiêu chí nào đó...

v Các phép toán trên danh sách không phụ thuộc vào kiểu dữ liệu của phần tử trong danh sách.

6 9/17/16 Trần Minh Thái - Phạm Đức Thành

Khái niệm danh sách

v Ví dụ:

Ø Danh sách sinh viên. Ø Danh sách diện thoại (danh bạ điện thoại). Ø Danh sách môn học. Ø Danh sách nhân viên. Ø Danh sách hàng hóa (danh mục hàng hóa).

7 9/17/16 Trần Minh Thái - Phạm Đức Thành

Tổ chức dữ liệu bằng danh sách

v Cú pháp: Danh sách

List list = new List();

v Ví dụ, khai báo danh sách số nguyên

List list = new List();

8 9/17/16 Trần Minh Thái - Phạm Đức Thành

Tổ chức dữ liệu bằng danh sách

v Ví dụ, khai báo danh sách có tên list là danh

sách chứa các sinh viên.

struct sinhVien

{

public string maSV, hoTen;

public DateTime ngaySinh;

public string diaChi, maLop;

}

List list = new List();

9 9/17/16 Trần Minh Thái - Phạm Đức Thành

Tổ chức dữ liệu bằng danh sách

linkList

=

new

v Danh sách liên kết: class Node { int key; Node next; } LinkedList LinkedList();

10 9/17/16 Trần Minh Thái - Phạm Đức Thành

Kỹ thuật xử lý danh sách

v Kiểm tra danh sách rỗng: if (list.Count == 0)

Console.WriteLine("Danh sách rỗng");

else

Console.WriteLine("Danh sách không rỗng");

11 9/17/16 Trần Minh Thái - Phạm Đức Thành

Kỹ thuật xử lý danh sách

v Thêm một phần tử vào danh sách:

list.Add(100);

v Thêm nhiều phần tử vào danh sách:

list.AddRange(new int[] { 33, 44, 55 });

12 9/17/16 Trần Minh Thái - Phạm Đức Thành

Kỹ thuật xử lý danh sách

v Chèn phần tử vào cuối danh sách: list.Insert(list.Count, 9999); v Truy xuất đến các phần tử trong danh sách: foreach (int x in list)

Console.WriteLine(x);

13 9/17/16 Trần Minh Thái - Phạm Đức Thành

Kỹ thuật xử lý danh sách

v Đếm số phần tử bằng giá trị X cho trước: int X = 5, dem = 0; foreach (int ai in list) if (ai == X) dem++; Console.WriteLine("Co {0} phan tu bang {1}", dem, X);

14 9/17/16 Trần Minh Thái - Phạm Đức Thành

Kỹ thuật xử lý danh sách

v Tìm một phần tử có giá trị X cho trước: int index=list.IndexOf(X); if (index == -1) Console.WriteLine("Tim khong thay"); else Console.WriteLine("Tim thay");

15 9/17/16 Trần Minh Thái - Phạm Đức Thành

Kỹ thuật xử lý danh sách

v Chèn một phần tử vào danh sách:

list.Insert(3, 5); v Xóa một phần tử khỏi danh sách tại vị trí xác

định:

list.RemoveAt(4);

v Sắp xếp danh sách:

list.Sort();

16 9/17/16 Trần Minh Thái - Phạm Đức Thành

Bài tập ví dụ

Cho danh sách các mặt hàng, mỗi mặt hàng gồm các thông tin: mã hàng, tên hàng, số lượng, đơn giá, ngày nhập hàng. Hãy viết các hàm: v Nhập danh sách các mặt hàng v In danh sách các mặt hàng được nhập vào

cách đây ít nhất 10 ngày

v Sắp xếp danh sách các mặt hàng theo thứ tự

tăng dần của tên hàng

17 9/17/16 Trần Minh Thái - Phạm Đức Thành

Bài tập ví dụ

Khai báo cấu trúc mặt hàng

struct MatHang {

public string maHang; public string tenHang; public DateTime ngayNhap;

public int soLuong;

public int donGia; }

18 9/17/16 Trần Minh Thái - Phạm Đức Thành

Bài tập ví dụ

Nhập thông tin của một mặt hàng

static void NhapMatHang(out MatHang x) {

Console.Write("- Nhap ma hang: "); x.maHang = Console.ReadLine(); Console.Write("- Nhap ten hang: "); x.tenHang = Console.ReadLine(); Console.Write("- Nhap so luong: "); x.soLuong = int.Parse(Console.ReadLine()); Console.Write("- Nhap don gia: "); x.donGia = int.Parse(Console.ReadLine()); Console.Write("- Nhap vao ngay nhap hang (dd/mm/yyyy):

");

string ngay = Console.ReadLine(); x.ngayNhap = DateTime.Parse(ngay);

19 } 9/17/16 Trần Minh Thái - Phạm Đức Thành

Bài tập ví dụ

Nhập danh sách mặt hàng

static void NhapDanhSach(List dshang) {

MatHang x; char nhap; do {

NhapMatHang(out x); dshang.Add(x); Console.Write("Nhap tiep mat hang (Y/N)?: "); nhap = char.Parse(Console.ReadLine());

} while (nhap == 'Y' || nhap == 'y');

}

20 9/17/16 Trần Minh Thái - Phạm Đức Thành

Bài tập ví dụ

Xuất thông tin mặt hàng

static void XuatMatHang(MatHang mh) {

Console.Write("{0, 8}|{1, 15}|{2, 8}|{3, 8}|{4, 8}", mh.maHang, mh.tenHang, mh.soLuong, mh.donGia,

mh.ngayNhap.ToShortDateString()); } static void XuatDanhSach(List dsmh) {

Console.WriteLine("{0, 8}|{1, 15}|{2, 8}|{3, 8}|{4, 8}",

"Ma hang", "Ten hang", "So luong", "Don gia", "Ngay nhap");

foreach (MatHang x in dsmh)

{

XuatMatHang(x); Console.WriteLine();

}

}

21 9/17/16 Trần Minh Thái - Phạm Đức Thành

Bài tập ví dụ

Xuất mặt hàng được nhập ít nhất 10 ngày & sắp xếp theo tên hàng

static void XuatMHNhapTu10Ngay(List dsmh) {

Console.WriteLine("{0, 8}|{1, 15}|{2, 8}|{3, 8}|{4, 8}",

"Ma hang", "Ten hang", "So luong", "Don gia", "Ngay nhap"); foreach (MatHang mh in dsmh)

{

if ((DateTime.Now - mh.ngayNhap).Days >= 10)

{

XuatMatHang(mh);

Console.WriteLine();

}

}

} static int SoSanhMhTheoTen(MatHang x, MatHang y) {

return x.tenHang.CompareTo(y.tenHang);

22 } 9/17/16 Trần Minh Thái - Phạm Đức Thành

Bài tập ví dụ

static void Main(string[] args) {

List dsmh = new List(); NhapDanhSach(dsmh); Console.WriteLine("Danh sach mat hang:"); XuatDanhSach(dsmh); Console.WriteLine("\nDanh sach mat hang duoc nhap vao

it nhat 10 ngay:");

ắ ế ầ

XuatMHNhapTu10Ngay(dsmh); //S p x p danh sách mặt hàng tăng d n theo tên hàng dsmh.Sort(SoSanhMhTheoTen); Console.WriteLine("\nDanh sach mat hang duoc sap tang

theo ten hang:");

XuatDanhSach(dsmh);

}

23 9/17/16 Trần Minh Thái - Phạm Đức Thành

ả ử Gi  s  ngày  ươ ạ ch y ch ng  trình là  23/02/2016

24 9/17/16 Trần Minh Thái - Phạm Đức Thành

Bài tập về nhà

Bổ sung vào chương trình của bài tập ví dụ một số chức năng sau: v Nhập vào mã số mặt hàng x, tìm và in ra thông tin mặt hàng và tổng tiền có mã số x (nếu có)

v Chèn thêm thông tin một mặt hàng p sao cho danh sách mặt hàng vẫn có thứ tự tăng dần theo tên hàng

v Cập nhật giá mới cho mặt hàng có mã số x

sao cho tăng thêm 15% so với giá cũ

v Xóa mặt hàng có ngày nhập vào là d (nếu có) v Sắp xếp danh sách mặt hàng giảm dần theo Trần Minh Thái - Phạm Đức Thành

25 9/17/16

số lượng

[2.3] Kỹ thuật xử lý mảng

v Mảng một chiều. v Array và ArrayList. v Mảng hai chiều (ma trận – matrix). v Mảng hai chiều vuông. v Jagged Array.

26 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng một chiều

v Chứa các biến có cùng kiểu dữ liệu. v Truy xuất phần tử thông qua chỉ số (index). v Chỉ số bắt đầu bằng 0.

Chi số

0

1

2

3

4

Ph n tầ ử A[0] A[1] A[2] A[3] A[4]

̉

27 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng một chiều

v Khai báo:

Datatype[ ] array-name;

Ví d  1:ụ

int [ ] myArr = new int [5];   string [ ] myStr = new string[5];   string [] myStr2 = {“abc”, “def”};

28 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng một chiều

static void Main(string[] args) { int[] Arr = new int[] { 2, 3, 4, 1, 6, 5 }; for (int i = 0; i < Arr.Length; i++) Console.Write("{0,4}", Arr[i]); Console.ReadLine(); }

29 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng một chiều

v Kỹ thuật liệt kê: void LietKeXXX(int [ ]a) {

for (int i = 0; i

Xuất a[i];

}

30 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng một chiều

v Liệt kê các phần tử có giá trị chẵn trong

mảng:

static void lietKeChan(int []A) { foreach (int ai in A) if (ai % 2 == 0) Console.Write("{0,4}", ai); }

31 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng một chiều

v Kỹ thuật liệt kê: void LietKeXXX(int [ ]a, int x) {

for (int i = 0; i

if (a[i] thỏa điều kiện so với x)

Xuất a[i];

}

32 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng một chiều

v Liệt kê các phần tử có giá trị lớn hơn x trong

mảng:

static void lietKeLonHonX(int[] A,int X) { foreach (int ai in A) if (ai > X) Console.Write("{0,4}", ai); }

33 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng một chiều

v Tính tổng/tích: int TongXXX(int []A) int s = 0; { for (int i = 0; i

s += a[i];

return s;

}

34 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng một chiều

v Tính tổng các phần tử có giá trị lẻ trong

mảng:

static int tongLe(int[] A) { int S = 0; foreach (int ai in A) if (ai % 2 != 0) S += ai; return S; }

35 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng một chiều

v Kĩ thuật đặt cờ hiệu :

Ø Kĩ thuật áp dụng cho những bài toán “kiểm

tra” hay “đánh dấu”.

Ø Ví dụ: Viết hàm kiểm tra xem mảng các số

nguyên có thứ tự tăng dần không?

(Hàm này trả về true nếu mảng tăng dần, ngược lại trả về false).

36 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng một chiều

static bool kiemTraTang(int[] A) { bool flag = true; for(int i=0; iA[i+1]) //vi phạm điều kiện tăng dần {

flag = false; break;

37

} return flag; } 9/17/16

Trần Minh Thái - Phạm Đức Thành

Mảng một chiều

v Đếm: int DemXXX(int []A) int d = 0; { for (int i = 0; i

d++; return d;

}

38 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng một chiều

v Đếm các phần tử có giá trị là số âm: static int demAm(int[] A) { int dem = 0; foreach (int ai in A) if (ai % 2 != 0) dem++; return dem; }

39 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng một chiều

v Đếm: int DemXXX(int []A, int x) {

int d = 0; for (int i = 0; i

if (A[i] thỏa điều kiện so với x)

d++; return d;

}

40 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng một chiều

v Đếm các phần tử có giá trị là số âm: static int demNhoHonX(int []a, int x) { int d = 0; for (int i = 0; i < a.Length; i++) if (a[i] < x) d++; return d; }

41 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng một chiều

v Tìm kiếm: vị trí phần tử lớn nhất trong mảng. static int TimVTMax(int []a) { int vtmax = 0; for (int i = 1; i < a.Length; i++) if (a[i] > a[vtmax]) vtmax = i; return vtmax; }

42 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng một chiều

v Kĩ thuật đặt lính canh: Ví dụ: Viết hàm tìm phần tử x có xuất hiện trong mảng một chiều các số nguyên hay không? Nếu có trả về vị trí đầu tiên của x trong mảng, ngược lại trả về -1.

43 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng một chiều

static int Tim_x(int []a, int x) { int i = 0; while (i < a.Length && a[i] != x) i++; if (i < a.Length) return i; return -1; }

44 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng một chiều

static int tim_X(int []a, int x) {

a[a.Length] = x; // đặt lính canh

int i = 0; while (a[i] != x) i++; if (i < a.Length) return i; return -1; }

45 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng một chiều

v Kiểm tra xem mảng có thỏa điều kiện cho

trước:

Trường hợp 1: kiểm tra tồn tại một phần tử trong mảng thỏa điều kiện nào đó cho trước  tìm phần tử thỏa điều kiện để kết luận.

46 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng một chiều

bool KiemTraTonTaiXXX(int []a) {

for (int i = 0; i

return true;

return false; }

47 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng một chiều

Kiểm tra xem mảng có tồn tại số lẻ không? static bool kiemTraTonTaiLe(int []a) { for (int i = 0; i < a.Length; i++) if (a[i] % 2 != 0) return true; return false; }

48 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng một chiều

v Kiểm tra xem mảng có thỏa điều kiện cho

trước:

Trường hợp 2: kiểm tra tất cả các phần tử thỏa điều kiện nào đó cho trước  tìm phần tử không thỏa điều kiện để kết luận mảng không thỏa điều kiện.

49 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng một chiều

bool KiemTraXXX(int []a) {

for (int i = 0; i

if (a[i] không thỏa điều kiện)

return false;

return true;

}

50 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng một chiều

Kiểm tra xem mảng có toàn bộ là giá trị âm không? static bool kiemTraToanAm(int []a) { for (int i = 0; i < a.Length; i++) if (a[i] >= 0) return false; return true; }

51 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng một chiều

vTính giá trị trung bình có điều kiện

float TrungBinhXXX(int []a) {

int d = 0;

float s = 0; for (int i = 0; i

if (d==0) return 0; return s / d;

}

52 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng một chiều

vTính giá trị trung bình giá trị âm trong mảng

static float trungBinhAm(int []a)

{ float s = 0; int d = 0;

for (int i = 0; i < a.Length; i++)

if (a[i] < 0)

{ s += a[i]; d++; }

if (d == 0) return 0;

53 9/17/16 Trần Minh Thái - Phạm Đức Thành

return s / d;

}

Mảng một chiều

vSắp xếp:

static void Hoanvi(ref int a,ref int b)

{

int tam = a;

a = b;

b = tam;

}

54 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng một chiều

static void SapTang(int []a) { for (int i = 0; i < a.Length - 1; i++) for (int j = i + 1; j < a.Length; j++) if (a[i] > a[j]) Hoanvi(ref a[i],ref a[j]); }

55 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng một chiều

vXóa: phần tử đầu tiên của mảng

static void xoaDau(ref int []a)

{

int[] tam = new int[a.Length - 1];

for (int i = 0; i < a.Length-1; i++)

tam[i] = a[i + 1];

a=tam;

56

} 9/17/16

Trần Minh Thái - Phạm Đức Thành

Mảng một chiều

vHàm xóa phần tử tại vị trí (vitri) cho trước.

static void xoaTaiViTri(ref int []a, int vitri)

{

int[] tam = new int[a.Length - 1];

for (int i = vitri; i < a.Length - 1; i++)

tam[i] = a[i + 1];

a = tam;

57 Trần Minh Thái - Phạm Đức Thành

9/17/16 }

Mảng một chiều

vChèn: Thêm X vào cuối mảng

static void themCuoi(ref int []a, int X)

{

int[] tam = new int[a.Length + 1];

for (int i = 0; i < a.Length; i++)

tam[i] = a[i];

tam[a.Length] = X;

a = tam;

58 Trần Minh Thái - Phạm Đức Thành

9/17/16 }

Mảng một chiều

vChèn: phần tử X vào mảng tại vị trí k cho trước

static void chenXTaiViTri(ref int []a, int X, int k)

{ int[] tam = new int[a.Length + 1]; int i;

for (i = 0; i < k; i++)

tam[i] = a[i];

59 9/17/16 Trần Minh Thái - Phạm Đức Thành

tam[k] = X;

for (; i < a.Length; i++)

tam[i+1] = a[i];

a = tam;

}

Mảng một chiều

vTách mảng :

v Ví dụ: Cho mảng a kích thước n (n chẵn). Tách mảng a thành 2 mảng b và c sao cho: b có ½ phần tử đầu của mảng a, ½ phần tử còn lại đưa vào mảng c.

60 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng một chiều

static void tachMang(int []a, out int []b, out int []c) { int k = a.Length / 2; b = new int[k]; c = new int[k]; int m = 0, l = 0; for (int i = 0; i < k; i++) { b[m++] = a[i]; c[l++] = a[k + i]; } }

61 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng một chiều

vGhép mảng:

v Ví dụ: Cho 2 mảng số nguyên a và b. Viết chương trình nối mảng b vào cuối mảng a.

62 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng một chiều

static void noiMang(ref int []a, int []b) { int[] tam = new int[a.Length + b.Length]; int i; for (i = 0; i < a.Length; i++) tam[i] = a[i]; for (i = 0; i < b.Length; i++) tam[i+a.Length] = b[i]; a = tam; }

63 9/17/16 Trần Minh Thái - Phạm Đức Thành

Array và ArrayList

Array: C# cung cấp sẵn lớp Array giúp ta sử dụng giống như mảng một chiều, chỉ khác là mỗi thành phần của Array là kiểu Object.

Array Arr = new int[5];

int[] A = new int[5];

static void xuatMang(int []A) { foreach (int ai in A) Console.Write("{0,4}", ai); Console.WriteLine();

static void xuatMang(Array A) { foreach (int ai in A) Console.Write("{0,4}", ai); Console.WriteLine(); }

}

64 9/17/16 Trần Minh Thái - Phạm Đức Thành

Array và ArrayList

void nhapMang(out Array A) { int n; Console.Write("Moi nhap so phan tu="); n = int.Parse(Console.ReadLine()); A = new int[n]; for (int i = 0; i < A.Length; i++) { Console.Write("A[{0}]=", i); A.SetValue(int.Parse(Console.ReadLine()), i); } }

void nhapMang(out int []A) { int n; Console.Write("nhap n="); n = int.Parse(Console.ReadLine()); A = new int[n]; for(int i=0; i

67 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng hai chiều

v Giống như mảng một chiều. Chỉ khác có kích

thước dòng, kích thước cột

v Truy xuất phần tử thông qua chỉ số (index)

dòng, chỉ số cột.

v Chỉ số bắt đầu bằng 0. Thường ta dùng i cho

chỉ số dòng, j cho chỉ số cột.

68 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng hai chiều

v Giống như mảng một chiều. Chỉ khác có kích

thước dòng, kích thước cột

v Truy xuất phần tử thông qua chỉ số (index)

dòng, chỉ số cột.

v Chỉ số bắt đầu bằng 0. Thường ta dùng i cho

chỉ số dòng, j cho chỉ số cột.

69 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng hai chiều

0

1

2

3

4

0 A[0,0] A[0,1] A[0,2] A[0,3] A[0,4]

1 A[1,0] A[1,1] A[1,2] A[1,3] A[1,4]

2 A[2,0] A[2,1] A[2,2] A[2,3] A[2,4]

3 A[3,0] A[3,1] A[3,2] A[3,3] A[3,4]

70 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng hai chiều

v Khai báo:

Datatype[,] array- name;

v Ví dụ 1: Khai báo mảng int 2 dòng 3 cột

int[,] myMatrix = new int[2, 3];

71 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng hai chiều

v Có thể khởi gán

Ø int[,] matrix1 = new int[,] {{1,2},{3,4},{5,6},

{7,8}};

Ø int[,] matrix2 = {{1,2},{3,4},{5,6},{7,8}}; Ø string[,] beatleName = {"Lennon","John"},

{ {"McCartney","Paul"}, {"Harrison","George"}, {"Starkey","Richard"}

};

72 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng hai chiều

static void Main(string[] args) { double[,] matrix = new double[5, 4]; int count = 0; for (int i = 0; i < matrix.GetLength(0); i++) for (int j = 0; j < matrix.GetLength(1); j++) matrix[i, j] = ++count; foreach (double d in matrix) Console.Write("{0,4}", d); Console.ReadLine(); }

73 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng hai chiều

Liệt kê các phần tử có giá trị chẵn trong mảng: static void lietKeDuong(double[,] A) { for (int i = 0; i < A.GetLength(0); i++) for (int j = 0; j < A.GetLength(1); j++) if(A[i,j]>0) Console.Write("{0,4}", A[i, j]); }

74 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng hai chiều

Tính tổng các phần tử có giá trị lẻ trong mảng : static int tongLe(int[,] A) { int S = 0; for (int i = 0; i < A.GetLength(0); i++) for (int j = 0; j < A.GetLength(1); j++) if (A[i,j] % 2 != 0) S += ai; return S; }

75 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng hai chiều

Kĩ thuật đặt cờ hiệu: Ví dụ: Viết hàm kiểm tra xem trong mảng các số nguyên có tồn tại số nguyên chẵn lớn hơn 10 hay không? (Trả về 1: Nếu có tồn tại số chẵn và lớn hơn 10, ngược lại trả về 0).

76 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng hai chiều

static bool Ktra_chanLH10(int[,] A) { bool flag = false; for (int i = 0; i < A.GetLength(0); i++) for (int j = 0; j < A.GetLength(1); j++) if(A[i,j] % 2 == 0 && A[i,j] > 10)//Gặp ptử thỏa đk { flag = true; break; } return flag; }

77 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng hai chiều

if (A[i,j] % 2 != 0) dem++;

Đếm: các phần tử có giá trị là số âm. static int demAm(int[,] A) { int dem = 0; for (int i = 0; i < a.GetLength(0); i++) for (int j = 0; j < a.GetLength(1); j++) return dem; }

78 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng hai chiều

Tìm kiếm: vị trí phần tử lớn nhất trong mảng. static int TimVTMax(int[,] a, out int vtd,out int vtc) { vtd = vtc= 0; for (int i = 0; i < a.GetLength(0); i++) for (int j = 0; j < a.GetLength(1); j++) if (a[i,j] > a[vtd,vtc]) { vtd = i; vtc = j; } return a[vtd,vtc]; }

79 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng hai chiều

if (A[i,j] % 2 != 0) return true;

Kiểm tra xem mảng có tồn tại số lẻ không. static bool kiemTraTonTaiLe(int [,]A) { for (int i = 0; i < a.GetLength(0); i++) for (int j = 0; j < a.GetLength(1); j++) return false; }

80 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng hai chiều

float s = 0; int d = 0;

Tính trung bình phần tử có giá trị âm trong mảng. static float trungBinhAm(int [,]a) { for (int i = 0; i < a.GetLength(0); i++) for (int j = 0; j < a.GetLength(1); j++) if (a[i,j] < 0) { s+=a[i,j]; d++; }

if( d==0 ) return 0; return s/d;

}

81 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng hai chiều

Sắp xếp. static void Hoanvi(ref int a,ref int b) { int tam = a; a = b; b = tam; }

82 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng hai chiều

static void SapTang(int []a) { for (int i = 0; i < a.Length - 1; i++) for (int j = i + 1; j < a.Length; j++) if (a[i] > a[j]) Hoanvi(ref a[i],ref a[j]); }

83 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng hai chiều

static void Copy(int [,]a,out int []b) { b = new int[a.GetLength(0) * a.GetLength(1)]; int i = 0; foreach (int ai in a) b.SetValue(ai,i++); }

84 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng hai chiều

static void Copy(int[] a,ref int[,] b) { int k = 0; for (int i = 0; i < b.GetLength(0); i++) for (int j = 0; j < b.GetLength(1); j++) b[i,j]=a[k++]; }

85 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng hai chiều

static void sapTang(int [,]a) { int[] b; Copy(a, out b); SapTang(b); Copy(b, ref a); }

86 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng hai chiều

xóa dòng đầu tiên của mảng static void xoaDongDau(ref int[,] a) { int[,] tam = new int[a.GetLength(0) –

1,a.GetLength(1)];

for (int i = 1; i < a.GetLength(0); i++) for (int j = 0; j < a.GetLength(1); j++) tam[i-1,j] = a[i,j]; a = tam; }

87 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng hai chiều

- 1,

int[,]tam=new

int[a.GetLength(0)

88

static void xoaDongTaiViTri(ref int[,] a,int vitri) { a.GetLength(1)]; int i; for (i = 0; i < vitri; i++) for (int j = 0; j < a.GetLength(1); j++) tam[i , j] = a[i, j]; for (i++; i < a.GetLength(0); i++) for (int j = 0; j < a.GetLength(1); j++) tam[i-1, j] = a[i, j]; a = tam; }9/17/16

Trần Minh Thái - Phạm Đức Thành

,

tam = new

int[a.GetLength(0)

89 Trần Minh Thái - Phạm Đức Thành

Mảng hai chiều static void xoaCotTaiViTri(ref int[,] a, int vitri) int[,] { a.GetLength(1)-1]; int j; for (j = 0; j < vitri; j++) for (int i = 0; i < a.GetLength(0); i++) tam[i, j] = a[i, j]; for (j++; j < a.GetLength(1); j++) for (int i=0; i < a.GetLength(0); i++) tam[i , j-1] = a[i, j]; a = tam; 9/17/16 }

int[,] tam = new

int[a.GetLength(0) + 1,

90 Trần Minh Thái - Phạm Đức Thành

static void themDongTaiVT(ref int[,] a, int[] b, int vt) { a.GetLength(1)]; int i; for (i = 0; i < vt; i++) for (int j = 0; j < a.GetLength(1); j++) tam[i, j] = a[i, j]; for (int j = 0; j < a.GetLength(1); j++) tam[i, j] = b[j]; for (; i < a.GetLength(0); i++) for (int j = 0; j < a.GetLength(1); j++) tam[i+1, j] = a[i, j]; 9/17/16 a = tam;

}

static void tachMang(int[,] a, out int[,] b, out int[,] c) { int k = a.GetLength(0) / 2; b = new int[k,a.GetLength(1)]; c = new int[k,a.GetLength(1)]; int i = 0, j = 0; for (i = 0; i < k; i++) for (j = 0; j < a.GetLength(1); j++) { b[i, j] = a[i, j]; c[i, j] = a[k + i, j]; }

91

}9/17/16

Trần Minh Thái - Phạm Đức Thành

92

static void noiMang(ref int[,] a, int[,] b) {int[,]tam=new int[a.GetLength(0)+b.GetLength(0),a.GetLength(1) ]; int i; for (i = 0; i < a.GetLength(0); i++) for (int j = 0; j < a.GetLength(1); j++) tam[i, j] = a[i, j]; for (int k = 0; k < b.GetLength(0); k++,i++) for (int j = 0; j < b.GetLength(1); j++) tam[i, j] = b[k, j]; a = tam; } 9/17/16

Trần Minh Thái - Phạm Đức Thành

Mảng hai chiều vuông

0

1

2

3

4

0 A[0,0] A[0,1] A[0,2] A[0,3] A[0,4]

1 A[1,0] A[1,1] A[1,2] A[1,3] A[1,4]

2 A[2,0] A[2,1] A[2,2] A[2,3] A[2,4]

3 A[3,0] A[3,1] A[3,2] A[3,3] A[3,4]

4 A[4,0] A[4,1] A[4,2] A[4,3] A[4,4]

93 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng hai chiều vuông

v Đường chéo chính:

Ø Chỉ số dòng bằng chỉ số cột: i = j.

0,0

1,1

2,2

3,3

4,4

94 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng hai chiều vuông

v Liệt kê các phần tử nằm trên đường chéo

chính:

static void lietKeCheoChinh(double[,] A) { for (int i = 0; i < A.GetLength(0); i++) for (int j = 0; j < A.GetLength(1); j++) if(i == j) Console.Write("{0,4}", A[i, j]); }

95 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng hai chiều vuông

v Tổng giá trị lẻ nằm phía trên chéo chính trong ma trận vuông số nguyên (không kể chéo chính).

96 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng hai chiều vuông

static int tongLe(int[,] A) { int S = 0; for (int i = 0; i < A.GetLength(0); i++) for (int j = i+1; j < A.GetLength(1); j++) if (A[i,j] % 2 != 0) S += A[i,j]; return S; }

97 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng hai chiều vuông

v Đường chéo phụ :

Ø Cs dòng = kt mtrận vuông – cs cột -1: i=n-j-

1.

0,4

1,3

2,2

3,1

4,0

98 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng hai chiều vuông

v Đếm các phần tử âm trên chéo phụ: static int demAm(int[,] A) { int dem = 0, n= A.GetLength(0); for (int i = 0; i < n; i++) if (A[i,n-i-1] < 0) dem++; return dem; }

99 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng hai chiều vuông

v Đếm các phần tử nhỏ hơn x nằm phía dưới

đường chéo phụ (kể cả chéo phụ).

0,4

1,3

2,2

3,1

4,0

100 9/17/16 Trần Minh Thái - Phạm Đức Thành

Mảng hai chiều vuông

static int demNhoHonX(int [,]a, int x) { int d = 0, n= A.GetLength(0); for (int i = 0; i < n; i++) for (int j = n-i-1; j < n; j++) if (a[i,j] < x) d++; return d; }

101 9/17/16 Trần Minh Thái - Phạm Đức Thành

Jagged Array

v Jagged là mảng C# cung cấp, mà mỗi phần

tử là một mảng có kích thước khác nhau

v Những mảng con này phải được khai báo

riêng .

Datatype[ ][ ] array- name

102 9/17/16 Trần Minh Thái - Phạm Đức Thành

Jagged Array

v Khai báo mảng 3 dòng, mỗi dòng là một

mảng 1 chiều

int[][] a = new int[3][];

1

2

a[0] = new int[4];

3

a[1] = new int[3];

4

a[2] = new int[1];

103 9/17/16 Trần Minh Thái - Phạm Đức Thành

static void Main(string[] args) { string[][] softwares = new string[3][]; softwares[0] = new string[] { "Bitdefender", "Karperky", "NAV" }; softwares[1] = new string[] { "IE", "Mozilla", "Opera", "Avant" }; softwares[2] = new string[] { "MS Word", "OpenOffice" }; for (int i = 0; i < softwares.GetLength(0); i++) for (int j = 0; j < softwares[i].GetLength(0); j++) Console.WriteLine(softwares[i][j]); Console.ReadLine(); }

104 9/17/16 Trần Minh Thái - Phạm Đức Thành

static void Main(string[] args) { string[][] softwares = new string[3][]; softwares[0] = new string[] { "Bitdefender", "Karperky", "NAV" }; softwares[1] = new string[] { "IE", "Mozilla", "Opera", "Avant" }; softwares[2] = new string[] { "MS Word", "OpenOffice" }; foreach(string[] srr in softwares) foreach(string s in srr) Console.WriteLine(s); Console.ReadLine(); }

105 9/17/16 Trần Minh Thái - Phạm Đức Thành

Thuật toán xử lý chuỗi

v Trong C# string là kiểu dữ liệu cơ bản thể

hiện mảng tuần tự các ký tự.

v Một hằng chuỗi có thể được khai báo trong

code bằng cách đặt trong nháy đôi.

v Ví dụ: Console.WriteLine("Khoa Cong nghe

Thong tin - Huflit");

106 9/17/16 Trần Minh Thái - Phạm Đức Thành

Thuật toán xử lý chuỗi

v Nhập chuỗi:

string S = Console.ReadLine();

v Xuất chuỗi:

Console.WriteLine(S);

v Truy cập đến các ký tự trong chuỗi:

foreach (char c in S) Console.Write(c);

107 9/17/16 Trần Minh Thái - Phạm Đức Thành

Thuật toán xử lý chuỗi

v Đếm số khoảng trắng trong chuỗi: static int demKhoangTrang(string S) { int dem = 0; for (int i = 0; i < S.Length; i++) if (S[i] == 32) dem++; return dem; }

108 9/17/16 Trần Minh Thái - Phạm Đức Thành

Thuật toán xử lý chuỗi

v Các hàm do C# cung cấp sẵn: (trang 54) v string của C# hỗ trợ hai dạng phương thức:

(t. 55)

109 9/17/16 Trần Minh Thái - Phạm Đức Thành

Thuật toán xử lý chuỗi

v Chuỗi trong C# là giá trị không thể modify v Do đó nếu dùng để modify string thì phải tạo

ra các bản copy để thực hiện.

v Thay

đó

vào

thể

dùng System.Text.StringBuilder để modify chuỗi mà không phải tạo ra bản copy như là string thực hiện.

v Các phương thức của StringBuilder bao

gồm: Ø Append( ), AppendFormat( ),

Insert( ),

Remove( ) và Replace( ).

110 9/17/16 Trần Minh Thái - Phạm Đức Thành

Thuật toán xử lý chuỗi

v Ví dụ: StringBuilder S =new StringBuilder( "Hello");

S.Append(" Everybody");

Console.WriteLine(S);

111 9/17/16 Trần Minh Thái - Phạm Đức Thành

PP biểu diễn đồ thị & thuật toán cơ bản

v Khái niệm:

Ø Đồ thị là một cấu trúc rời rạc gồm các đỉnh

và các cạnh nối nhau.

Ø Được mô tả hình thức sau: G=(V,E).

Trong đó:

– G là đồ thị (Graph). – V là tập các đỉnh (Vertices). – E là tập các cạnh (Edges).

112 9/17/16 Trần Minh Thái - Phạm Đức Thành

PP biểu diễn đồ thị & thuật toán cơ bản

v Ví dụ ta có đồ thị vô hướng sau:

D

B

A

F

C

E

113 9/17/16 Trần Minh Thái - Phạm Đức Thành

PP biểu diễn đồ thị & thuật toán cơ bản

v Ví dụ ta có đồ thị có hướng sau:

D

B

A

F

C

E

114 9/17/16 Trần Minh Thái - Phạm Đức Thành

PP biểu diễn đồ thị & thuật toán cơ bản

v Ví dụ ta có đồ thị vô hướng, có trọng số sau:

1

D

B

3

5

5

A

F

6

2

2

4

C

E

3

115 9/17/16 Trần Minh Thái - Phạm Đức Thành

PP biểu diễn đồ thị & thuật toán cơ bản

v Ma trận kề: ma trận vuông có kích thước là

số đỉnh.

v Ma trận A, với A[i,j] ta định nghĩa như sau:

Ø A[i,j] = 1 nếu (i,j) (cid:0) Ø A[i,j] = 0 nếu (i,j) (cid:0)

E. E.

v Với (cid:0)

i, A[i,i] = 0. Tùy theo mục đích có thể đặt giá trị khác nhau, khi lập trình tìm đường đi ngắn nhất, giá trị A[i,i]=(cid:0)

(vô cực).

116 9/17/16 Trần Minh Thái - Phạm Đức Thành

PP biểu diễn đồ thị & thuật toán cơ bản

v Ví dụ: Để biểu diễn cho hình slide 146.

117 9/17/16 Trần Minh Thái - Phạm Đức Thành

PP biểu diễn đồ thị & thuật toán cơ bản

v Ví dụ: Để biểu diễn cho hình slide 147.

118 9/17/16 Trần Minh Thái - Phạm Đức Thành

Biểu diễn đồ thị trên máy tính

v Ma trận trọng số: giống ma trận kề, khác ở

định nghĩa A[i,j] như sau: Ø A[i,j] = x nếu (i,j) (cid:0)

E, x là trọng số của

cạnh (i,j).

Ø A[i,j] = 0 (hoặc (cid:0)

) nếu (i,j) (cid:0)

E.

119 9/17/16 Trần Minh Thái - Phạm Đức Thành

Biểu diễn đồ thị trên máy tính

v Ví dụ: Để biểu diễn cho hình slide 148.

120 9/17/16 Trần Minh Thái - Phạm Đức Thành

Biểu diễn đồ thị trên máy tính

v Danh sách cạnh: Là danh sách chứa các

cạnh của đồ thị.

v Ví dụ: Để biểu diễn cho hình slide 146 ta có

danh sách cạnh như sau:

(A,B) 0

(A,C) 1

(B,C) 2

(B,D) 3

(C,D) 4

(C,E) 5

(D,E) 6

(D,F) 7

(E,F) 8

121 9/17/16 Trần Minh Thái - Phạm Đức Thành

Biểu diễn đồ thị trên máy tính

v Danh sách cạnh: Cài đặt bằng C# như sau: public struct Canh

{

public int dinhdau;

public int dinhcuoi;

}

List list = new List();

122 9/17/16 Trần Minh Thái - Phạm Đức Thành

Các thuật toán cơ bản

v Tìm kiếm theo chiều rộng: Thuật toán [BFS]: Cho G=(V, E) và 1 đỉnh xuất phát s. Bước 1: Viếng thăm đỉnh s.

Bước 2: Tìm các đỉnh (gọi là S1) chưa được viếng thăm và kề với s, rồi viếng thăm các đỉnh trong S1.

Bước 3: Tìm các đỉnh (gọi là S2) chưa được viếng thăm và kề với S1, rồi viếng thăm các đỉnh trong S2.

Bước 4: Quá trình này thực hiện cho đến khi không thể tìm được các đỉnh kế tiếp.

123 9/17/16 Trần Minh Thái - Phạm Đức Thành

Các thuật toán cơ bản

v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:

5

6

0

4

3

1

2

124 9/17/16 Trần Minh Thái - Phạm Đức Thành

Các thuật toán cơ bản

v Tìm kiếm theo chiều rộng: Thuật toán [BFS]: 6

5

0

4

3

1

2

125 9/17/16 Trần Minh Thái - Phạm Đức Thành

Các thuật toán cơ bản

v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:

5

6

0

4

3

1

2

126 9/17/16 Trần Minh Thái - Phạm Đức Thành

Các thuật toán cơ bản

v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:

5

6

0

4

3

1

2

127 9/17/16 Trần Minh Thái - Phạm Đức Thành

Các thuật toán cơ bản

v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:

5

6

0

4

3

1

2

128 9/17/16 Trần Minh Thái - Phạm Đức Thành

Các thuật toán cơ bản

v Tìm kiếm theo chiều rộng: Thuật toán [BFS]: v Nhận xét:

Ø Những đỉnh gần với s nhất sẽ được viếng

thăm trước

Ø Các đỉnh chỉ được viếng thăm duy nhất 1

lần

v Cài đặt thuật toán: Ta dùng hàng đợi:

Queue q = new Queue();

129 9/17/16 Trần Minh Thái - Phạm Đức Thành

Tìm kiếm theo chiều rộng

v Thuật toán cài đặt bằng hàng đợi như sau:

Ø Bước 1: Khởi tạo

§ Đánh dấu mọi đỉnh chưa được viếng thăm § Thăm đỉnh s (Đánh dấu đỉnh s đã viếng thăm) § Khởi tạo hàng đợi q chỉ chứa s

Ø Bước 2: Lặp cho đến khi hàng đợi q rỗng

§ Lấy đỉnh u ra khỏi hàng đợi q § Tìm tất cả đỉnh v chưa viếng thăm và kề với

đỉnh u

– Tham đỉnh v (Đánh dấu đỉnh v đã viếng

thăm)

– Đẩy đỉnh v vào hàng đợi

130 9/17/16 Trần Minh Thái - Phạm Đức Thành

Các thuật toán cơ bản

v Tìm kiếm theo chiều sâu: Thuật toán DFS: v Cho G=(V, E) và 1 đỉnh xuất phát s.

Ø Bước 1: Viếng thăm đỉnh s Ø Bước 2: Tìm đỉnh u chưa được viếng thăm và kề

với s § Nếu có đỉnh u thì đặt s=u và quay về Bước 1 § Nếu không có đỉnh u thì quay về đỉnh k là đỉnh trước của đỉnh s, đặt s=k và quay về bước 2

v Quá trình này được thực hiện cho đến khi không

131

thể quay về đỉnh trước đó 9/17/16

Trần Minh Thái - Phạm Đức Thành

Các thuật toán cơ bản

v Tìm kiếm theo chiều sâu: Thuật toán DFS:

D

B

A

F

C

E

132 9/17/16 Trần Minh Thái - Phạm Đức Thành

Các thuật toán cơ bản

v Tìm kiếm theo chiều sâu: Thuật toán DFS:

D

B

A

F

C

E

133 9/17/16 Trần Minh Thái - Phạm Đức Thành

Các thuật toán cơ bản

v Tìm kiếm theo chiều sâu: Thuật toán DFS:

D

B

A

F

C

E

134 9/17/16 Trần Minh Thái - Phạm Đức Thành

Các thuật toán cơ bản

v Tìm kiếm theo chiều sâu: Thuật toán DFS:

D

B

A

F

C

E

135 9/17/16 Trần Minh Thái - Phạm Đức Thành

Các thuật toán cơ bản

v Tìm kiếm theo chiều sâu: Thuật toán DFS:

D

B

A

F

C

E

136 9/17/16 Trần Minh Thái - Phạm Đức Thành

Các thuật toán cơ bản

v Tìm kiếm theo chiều sâu: Thuật toán DFS:

D

B

A

F

C

E

137 9/17/16 Trần Minh Thái - Phạm Đức Thành

Các thuật toán cơ bản

v Tìm kiếm theo chiều sâu: Thuật toán DFS:

D

B

A

F

C

E

138 9/17/16 Trần Minh Thái - Phạm Đức Thành

Tìm kiếm theo chiều sâu

v Cài đặt thuật toán: Stack s = new Stack(); v Thuật toán cài đặt bằng stack như sau: Ø Bước 1. Đánh dấu s đã viếng thăm. Ø Bước 2. Đưa s vào stack. Ø Bước 3. Trong khi stack chưa rỗng.

§ B3.1 Lấy 1 đỉnh u từ stack. § B3.2 Tìm 1 đỉnh v chưa được viếng thăm và kề

u.

– B3.2.1 Đánh dấu v đã viếng thăm. – B3.2.2 Đẩy u vào lại stack. – B3.2.3 Đẩy v vào stack. – B3.2.4 Quay lại bước 3

139 9/17/16 Trần Minh Thái - Phạm Đức Thành

Các thuật toán cơ bản

v Thuật toán Dijkstra: Tìm đường đi từ s đến t. v Ý tưởng: xây dựng dần các đỉnh đi từ s và

gần s nhất.

v Thuật toán Dijkstra không thể thực hiện khi đồ thị có cạnh âm (đồ thị vô hướng) hay đồ thị có chu trình âm (đồ thị có hướng)

140 9/17/16 Trần Minh Thái - Phạm Đức Thành

Các thuật toán cơ bản

v Thuật toán Dijkstra: Bước 1 [Khởi tạo]: d(v) = +∞, (cid:0)

v(cid:0) V. d(s)=0 và tập S=V.

S sao cho d(u) có giá trị

Bước 2: [Lặp] [Chọn Min] Chọn đỉnh u (cid:0) min.

[Cập Nhật] Với mọi đỉnh v kề u.

d(v) = min{d(v), d(u) + w(u,v)}

S = S - {u} Lặp cho đến khi t (cid:0)

S

141 9/17/16 Trần Minh Thái - Phạm Đức Thành

Các thuật toán cơ bản

v Thuật toán Ford – Bellman: chu trình âm hay trả về

cây đường đi.

v Bước 1 [Khởi tạo]: d0(v) = +∞, (cid:0)

v(cid:0) V. d0(s)=0,

k=0

v Bước 2: [Lặp]

§ k = k+1 § [Cập Nhật] Với mọi đỉnh u kề v

dk(s) = 0. dk(v) = min{dk-1(u) + w(u,v)} § [Kiểm tra] Nếu dk(v) = dk-1(v), (cid:0) v, thì dừng.

Lặp cho đến khi k=n

v Bước 3: Nếu k=n thì đồ thị có chu trình âm

142 9/17/16 Trần Minh Thái - Phạm Đức Thành

Các thuật toán cơ bản

v Tìm đường đi ngắn nhất: Thuật toán Floyd. v Hoặc chỉ ra đồ thị có chu trình âm.

Ø Input: G=(V, E) Ø Output:

§ Ma trận đường đi ngắn nhất giữa các cặp

đỉnh

– d[i, j]: độ dài đường đi ngắn nhất từ đỉnh i

đến đỉnh j

§ Ma trận ghi nhận đường đi

– p[i, j]: ghi nhận đỉnh đi trước đỉnh j trong

đường đi ngắn nhất từ đỉnh i đến đỉnh j

143 9/17/16 Trần Minh Thái - Phạm Đức Thành

Các thuật toán cơ bản

v Tìm đường đi ngắn nhất: Thuật toán Floyd. v Bước 1: [Khởi tạo]

§ d[i, j]=a[i, j] § p[i, j] = j; v Bước 2: [Lặp]

§ Cho k, i, j chạy từ 0 đến n-1

Nếu (d[i, j] > d[i, k] + d[k, j]) thì

d[i, j] = d[i, k] + d[k, j] p[i, j] = k

144 9/17/16 Trần Minh Thái - Phạm Đức Thành

Tổ chức dữ liệu biểu diễn cấu trúc cây

v Khái niệm cơ bản. v Cây là một cấu trúc dữ liệu gồm tập hữu hạn các nút, giữa các nút có một quan hệ phân cấp “cha - con”. Có một nút đặc biệt gọi là gốc (root).

v Cây rỗng (null tree) là cây không có nút nào

cả.

145 9/17/16 Trần Minh Thái - Phạm Đức Thành

Tổ chức dữ liệu biểu diễn cấu trúc cây

A

Mức 0

C

B

D

Mức 1

I

E

F

G

H

Mức 2

K

J

Mức 3

146 9/17/16 Trần Minh Thái - Phạm Đức Thành

Tổ chức dữ liệu biểu diễn cấu trúc cây

v Nút A là gốc, là cha của B, C, D. v Nút G, H, I là con của nút D. v Số các nút con là bậc của nút đó. Ví dụ: nút D bậc

3, H bậc 2.

v Nút có bậc bằng 0 là nút là (leaf). Ví dụ: nút C, E, F. v Nút không phải là gốc hoặc lá gọi là nhánh. v Bậc cao nhất của tất cả các nút gọi là bậc của cây.

Cây ở hình trên là cây bậc 3.

147 9/17/16 Trần Minh Thái - Phạm Đức Thành

Tổ chức dữ liệu biểu diễn cấu trúc cây

v Ví dụ ứng dụng thực tế:

Ø Mục lục của một cuốn sách. Ø Cấu trúc thư mục trên đĩa trong cửa sồ File

Explorer/Windows Explorer.

Ø Gia phả của một họ tộc. Ø Một biểu thức toán học.

148 9/17/16 Trần Minh Thái - Phạm Đức Thành

Biểu diễn cây trên máy tính

v Biểu diễn bằng danh sách kề:

ề 4

0

Đ nh k 9 6

1 3

(cid:0)

(cid:0)

9

1

4

7

5

2

(cid:0)

(cid:0)

8

3

6

7

5

2

(cid:0)

Đ nhỉ 0 1 2 3 4 5 6 7 8 9

8

(cid:0)

149 9/17/16 Trần Minh Thái - Phạm Đức Thành

Biểu diễn cây trên máy tính

v Biểu diễn bằng danh sách kề: Cài đặt trên máy:

int sodinh = 10;

Vertices[3] = null;

int[][] Vertices = new int[sodinh][]; Vertices[0] = new int[] { 1,9, 4 }; Vertices[1] = new int[] { 3,6 }; Vertices[2] = null; Vertices[4] = new int[] { 7,5,2 }; Vertices[5] = null; Vertices[6] = null; Vertices[7] = null; Vertices[8] = null; Vertices[9] = new int[] { 8 };

150 9/17/16 Trần Minh Thái - Phạm Đức Thành

Biểu diễn cây trên máy tính

v Biểu diễn bằng danh sách liên kết:

null

adj[0]

1

9

4

null

adj[1]

3

6

adj[2] null adj[3] null

null

adj[4]

7

5

2

151 9/17/16 Trần Minh Thái - Phạm Đức Thành

Biểu diễn cây trên máy tính

v Biểu diễn bằng danh sách liên kết: Cài đặt trên

máy: int[] dinhS0 = { 1, 9, 4 };

LinkedList

listAdj0

= new

LinkedList

listAdj1

= new

LinkedList

listAdj2

= new

152 Trần Minh Thái - Phạm Đức Thành

LinkedList(dinhS0); int[] dinhS1 = { 3,6 }; LinkedList(dinhS1); int[] dinhS2 = null; LinkedList(dinhS2); int[] dinhS3 = null;

9/17/16

LinkedList

listAdj3

= new

LinkedList(dinhS3);

Biểu diễn cây trên máy tính

LinkedList

listAdj4

= new

LinkedList

listAdj5

= new

LinkedList

listAdj6

= new

LinkedList

listAdj7

= new

153 9/17/16 Trần Minh Thái - Phạm Đức Thành

int[] dinhS4 = { 7,5,2 }; LinkedList(dinhS4); int[] dinhS5 = { 1, 9, 4 }; LinkedList(dinhS5); int[] dinhS6 = null; LinkedList(dinhS6); int[] dinhS7 = null; LinkedList(dinhS7); int[] dinhS8 = null;

LinkedList

listAdj8

= new

LinkedList(dinhS8);

int[] dinhS9 = { 8 };

listAdj9

=

new

Graphs

=

new

154 9/17/16 Trần Minh Thái - Phạm Đức Thành

LinkedList LinkedList(dinhS9); List> List>(); Graphs.Add(listAdj0); Graphs.Add(listAdj1); Graphs.Add(listAdj2); Graphs.Add(listAdj3); Graphs.Add(listAdj4); Graphs.Add(listAdj5); Graphs.Add(listAdj6); Graphs.Add(listAdj7); Graphs.Add(listAdj8); Graphs.Add(listAdj9);

Biểu diễn cây trên máy tính

v Biểu diễn bằng mảng các đỉnh kề:

0

1

2

3

4

5

6

7

8

9

a

1

9

4

3

6

7

5

2

8

previous

0

1

4

9

3

8

8

8

8

index

0

5

5

5

8

v Trong đó:

v Đỉnh kề với 0: 0-2 Đỉnh kề với 1: 3-4 v Đỉnh kề với 4: 5-7 Đỉnh kề với 9: 8-8

155 9/17/16 Trần Minh Thái - Phạm Đức Thành

Biểu diễn cây trên máy tính

v Mảng các đỉnh kề: công thức tính đỉnh kề với i:

Đỉnh kề với i: a[index[i]]  a[index[i+1]-1]

v Cài đặt trên máy: int n = 10; int[] a = new int[n]; int[] index = new int[n];

156 9/17/16 Trần Minh Thái - Phạm Đức Thành

Tóm tắt chương

v Kiểu dữ liệu + các thao tác xử lý được định nghĩa

trên nó.

v Danh sách là một tập thứ tự các phần tử có cùng kiểu. Danh sách là cấu trúc dữ liệu tuyến tính, các phần tử dữ liệu được sắp thứ tự xác định.

v Dữ liệu kiểu mảng dùng cho việc biểu diễn những

thông tin có cùng kiểu dữ liệu liên tiếp nhau.

v Khi cài đặt bài tập mảng một chiều nên xây dựng thành những hàm chuẩn để dùng lại cho các bài tập khác.

157 9/17/16 Trần Minh Thái - Phạm Đức Thành

Tóm tắt chương

v Các thao tác mảng theo quy tắc nhất định, ứng dụng mảng trong việc biểu diễn số lớn, dùng bảng tra, khử đệ qui, …

v Giống mảng một chiều, thao tác truy xuất trên mảng hai chiều, trên chuỗi hoàn toàn tương tự. Bên cạnh đó, kiểu chuỗi còn được cài đặt sẵn một số hàm thư viện rất hữu ích, khi cài đặt, cố gắng tận dụng tối đa hàm thư viện này.

v C# hỗ trợ cho người lập trình rất nhiều trong và

System.Collections

namespace System.Collections.Generic.

158 9/17/16 Trần Minh Thái - Phạm Đức Thành

Tóm tắt chương

v Biểu diễn đồ thị: dùng ma trận kề, ma trận trọng số và danh sách mà giáo trình trình bày ở chương này. Với các thuật toán tìm đường đi...

v Biểu diễn cây: dùng mảng, danh sách kề và danh

sách liên kết.

v Đồ thị và cây trong tài liệu chỉ giới thiệu tổ chức dữ liệu là chính. Tìm hiểu sâu hơn, các bạn tìm hiểu ở 2 giáo trình khác là: Lý thuyết đồ thị, Cấu trúc Dữ liệu và Thuật toán.

159 9/17/16 Trần Minh Thái - Phạm Đức Thành

BÀI TẬP

v Viết hàm tìm vị trí phần tử có giá trị x xuất hiện

cuối cùng trong mảng.

v Viết hàm tìm vị trí của phần tử lớn nhất trong

mảng các số thực.

v Viết hàm in vị trí các phần tử nguyên tố trong

mảng các số nguyên.

v Viết hàm tìm vị trí phần tử âm đầu tiên trong

mảng. Nếu không có phần tử âm trả về –1.

v Viết hàm tìm vị trí phần tử âm lớn nhất trong

mảng.

160 9/17/16 Trần Minh Thái - Phạm Đức Thành

BÀI TẬP

v Viết hàm đếm số lần xuất hiện của phần tử x

trong mảng.

v Viết hàm đếm các phần tử là số hoàn thiện trong

mảng.

v Viết hàm tính tổng các phần tử nguyên tố trong

mảng.

v Viết hàm tính tích các phần tử nằm ở vị trí chẵn

trong mảng các số nguyên.

v Viết hàm sắp xếp các phần tử chẵn giảm dần. v Viết hàm xóa phần tử tại vị trí lẻ trong mảng.

161 9/17/16 Trần Minh Thái - Phạm Đức Thành

BÀI TẬP

v Nhập vào giá trị X. Viết hàm xóa tất cả các phần

tử có giá trị nhỏ hơn X.

v Viết hàm chèn phần tử có giá trị X vào vị trí đầu

tiên của mảng.

v Viết hàm chèn phần tử có giá trị X vào phía sau

phần tử có giá trị lớn nhất trong mảng.

v Viết hàm chèn phần tử có giá trị X vào phía sau tất cả các phần tử có giá trị chẵn trong mảng.

162 9/17/16 Trần Minh Thái - Phạm Đức Thành

BÀI TẬP

v Viết hàm tách 1 mảng a các số nguyên thành 2 mảng b và c, sao cho mảng b chứa toàn số lẻ và mảng c chứa số chẵn.

v Ví dụ: Mảng ban đầu a: 1 3 8 2 7 5 9 0 10

Ø

Ø

Mảng b: 1 3 7 5 9 Mảng c: 8 2 10

v Viết hàm ghép 2 mảng a và b các số nguyên đã được sắp tăng thành mảng c, sao cho mảng c cũng được sắp tăng. v Ví dụ: Mảng a:2 8 10

Ø

Mảng b:1 3 5 7 9 Mảng c:1 2 3 5 7 8 9 10

Ø 9/17/16

163 Trần Minh Thái - Phạm Đức Thành

BÀI TẬP

v VCT nhập vào một chuỗi ký tự, đếm số ký tự có

trong chuỗi.

v VCT đếm có bao nhiêu khoảng trắng trong

chuỗi.

v VCT nhập vào một chuỗi, hãy loại bỏ những

khoảng trắng thừa trong chuỗi.

v VCT nhập vào hai chuỗi s1 và s2, nối chuỗi s2

vào s1. Xuất chuỗi s1 ra màn hình.

v Đổi tất cả các ký tự có trong chuỗi thành chữ

thường (không dùng hàm strlwr).

v Đổi tất cả các ký tự trong chuỗi sang chữ in hoa

(không dùng hàm struppr).

164 9/17/16 Trần Minh Thái - Phạm Đức Thành

BÀI TẬP

v VCT đếm một ký tự xuất hiện bao nhiêu lần

trong chuỗi.

v VCT tìm kiếm tên trong chuỗi họ tên. Nếu có thì xuất ra là tên này đã nhập đúng, ngược lại thông báo là đã nhập sai.

v VCT đảo vị trí của từ đầu và từ cuối.

Ø Ví dụ: nhập “bo an co” xuat ra “co an bo”

v Viết hàm cắt chuỗi họ tên thành chuỗi họ lót và

chuỗi tên. Ø Ví dụ: chuỗi họ tên là:”Nguyễn Văn A” cắt ra 2 chuỗi là chuỗi họ lót:”Nguyễn Văn”,chuỗi tên là:”A”

165 9/17/16 Trần Minh Thái - Phạm Đức Thành

BÀI TẬP

v Nhập một chuỗi bất kỳ, sau đó hỏi người dùng cần tách bắt đầu từ đâu trong chuỗi trở về sau. Ø Ví dụ: Nhập chuỗi S1: “Trường Đại học Ngoại ngữ Tin học TPHCM”. Người nhập muốn tách bắt đầu từ chữ “học” thì sẽ xuất ra chuỗi “Ngoại ngữ Tin học TPHCM” ra màn hình. v Viết hàm kiểm tra xem chuỗi có đối xứng hay

không?.

v Viết hàm kiểm tra xem trong chuỗi có ký tự số hay không nếu có tách ra thành một mảng số riêng.

166 9/17/16 Trần Minh Thái - Phạm Đức Thành

v Nhập một chuỗi bất kì, yêu cầu nhập 1 ký tự muốn xóa. Thực hiện xóa tất cả những ký tự đó trong chuỗi.

BÀI TẬP

v Nhập một chuỗi bất kỳ, sau đó hỏi người dùng cần tách bắt đầu từ đâu trong chuỗi trở về sau. Ø Ví dụ: Nhập chuỗi S1: “Trường Đại học Ngoại ngữ Tin học TPHCM”. Người nhập muốn tách bắt đầu từ chữ “học” thì sẽ xuất ra chuỗi “Ngoại ngữ Tin học TPHCM” ra màn hình. v Viết hàm kiểm tra xem chuỗi có đối xứng hay

không?.

v Viết hàm kiểm tra xem trong chuỗi có ký tự số hay không nếu có tách ra thành một mảng số riêng.

167 9/17/16 Trần Minh Thái - Phạm Đức Thành

v Nhập một chuỗi bất kì, yêu cầu nhập 1 ký tự muốn xóa. Thực hiện xóa tất cả những ký tự đó trong chuỗi.