1. Trang chủ
  2. » Giáo Dục - Đào Tạo

bài tập thực hành cấu trúc dữ liệu và giải thuật

96 461 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 96
Dung lượng 505,51 KB

Nội dung

+ Đầu tiên , ta thực hiện việc khai báo một mảng một chiều []tg có n phần tử chứa các phần tử a[i,j] trên đường chéo chính của ma trậnvới i=j theo chiều từ góc bên trái phía trên đến bên

Trang 1

TRƯỜNG ĐẠI HỌC SƯ PHẠM KỸ THUẬT HƯNG YÊN

KHOA CÔNG NGHỆ THÔNG TIN

BÀI TẬP THỰC HÀNH HỌC PHẦN: CẤU TRÚC DỮ LIỆU

VÀ GIẢI THUẬT

Trình độ đào tạo

Hệ đào tạo

: :

Đại học Chính quy

Hưng Yên năm 2012

Trang 2

MỤC LỤC

BÀI THỰC HÀNH 1 KIỂU DỮ LIỆU CÓ CẤU TRÚC 3

BÀI THỰC HÀNH 2 ĐỘ PHỨC TẠP TÍNH TOÁN 16

BÀI THỰC HÀNH 3+4 DANH SÁCH NỐI ĐƠN 22

BÀI THỰC HÀNH 5 NGĂN XẾP - STACK 42

BÀI THỰC HÀNH 6 HÀNG ĐỢI - QUEUE 53

BÀI THỰC HÀNH 7 DANH SÁCH LIÊN KẾT KÉP 59

BÀI THỰC HÀNH 8 DANH SÁCH LIÊN KẾT VÒNG 70

BÀI THỰC HÀNH 9 CÂY NHỊ PHÂN 81

BÀI THỰC HÀNH 10 Kiểm tra thực hành 96

Trang 3

BÀI THỰC HÀNH 1 KIỂU DỮ LIỆU CÓ CẤU TRÚC

Bài 1: Cho n số nguyên dương a0,a1,a2, ,an-1

a.Chèn phần tử x vào vị trí k của dãy

b.Xóa tất cả các số nguyên tố trong dãy

+Ngược lại, chuyển sang kiểm tra phần tử kế tiếp

Lời giản mẫu

Console.Write("Nhap n=");

n = int.Parse(Console.ReadLine());

a = newint[n];

Trang 4

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

{

Console.Write("a[" + i + "]=");

a[i] = int.Parse(Console.ReadLine());

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

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

Trang 5

int[] tmp = newint[n];

for (int i = 0; i < n; ++i)

Trang 6

- Phòng ban

- Lương cơ bản (số nguyên)

- Thưởng (số nguyên)

- Thực lĩnh (số nguyên, trong đó thực lĩnh = lương cơ bản + thưởng )

Hãy thực hiện các yêu cầu sau:

a.Tính tổng thực lĩnh tháng của tất cả nhân viên trong công ty

b.In danh sách những nhân viên có mức lương cơ bản thấp nhất

Gợi ý:

Để lưu trữ thông tin của từng nhân viên ta khai báo một cấu trúc lưu trữ các thông tin structNhanVien

{

publicstring MaNV;

publicstring Hoten;

publicint Namsinh;

publicstring Phongban;

publicint LuongCB;

publicint Thuong;

b.Trước tiên ta tìm mức lương cơ bản thấp nhất bằng cách :

+ Gán một giá trị min bằng lớn vô cùng : int min = int.MaxValue;

+Duyệt qua từng nhân viên nếu nhân viên nào có mức lương nhỏ hơn min thì gán min bằng mức lương đó

Cuối cùng in ra thông tin của các nhân viên có mức lương bằng min

Lời giản mẫu

using System;

structNhanVien

{

Trang 7

publicstring MaNV;

publicstring Hoten;

publicint Namsinh;

publicstring Phongban;

publicint LuongCB;

publicint Thuong;

Console.WriteLine("Nhap thong tin NV thu:" + i);

Console.Write("Ma nhan vien:"); DS[i].MaNV = Console.ReadLine();

Console.Write("Ho ten:"); DS[i].Hoten = Console.ReadLine();

Console.Write("Nam sinh:"); DS[i].Namsinh = int.Parse(Console.ReadLine()); Console.Write("Phong ban:"); DS[i].Phongban = Console.ReadLine();

Console.Write("Luong co ban:"); DS[i].LuongCB =

int.Parse(Console.ReadLine());

Console.Write("Thuong:"); DS[i].Thuong = int.Parse(Console.ReadLine()); }

Trang 8

{

int min = int.MaxValue;

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

if (min > DS[i].LuongCB) min = DS[i].LuongCB;

Console.WriteLine("Danh sach luong cb min");

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

Bài 1: Cho n số nguyên dương a0,a1,a2, ,an-1

a.Chèn phần tử x vào vị trí k của dãy

b.Xóa tất cả các số nguyên tố trong dãy

c.Kiểm tra dãy có tăng dần hay không ?

d.Tìm số nhỏ nhất chia hết cho tất cả các số của dãy

Trang 9

e.Tìm các cặp số nguyên tố cùng nhau (hai số nguyên dương được gọi là nguyên

tố cùng nhau nếu ước số chung lớn nhất của chúng bằng 1)

f.Tìm tần số xuất hiện của các số trong dãy

+ Ngược lại,chuyển sang kiểm tra phần tử kế tiếp

c Duyệt qua các phần tử a[i] của mảng với i từ 0->n-2, tại mỗi phần tử kiểm tra xem nó có nhỏ hơn các phần tử a[j] kế tiếp không với j=i+1->n-1

+ Nếu không, thoát khỏi vòng lặp trả ra giá trị False (không tăng dần)

+ Ngược lại, kiểm tra phần tử a[i] kế tiếp

d Đầu tiên ta xây dựng một hàm BCNN(int x,int y) tính BCNN của 2 số Sau đó

ta khởi tạo giá trị int bc = 1 rồi thực hiện tính BCNN của bc với từng phần tử của mảng, kết quả thu được đưa vào bc

e Xây dựng một hàm tìm UCLN của 2 số

Thực hiện duyệt qua từng phần tử a[i] của mảng với i từ 0->n-2, với mỗi phần tử

ta tìm UCLN của phần tử đó với từng phần tử a[j] kế tiếp nó với j từ i+1 -> n-1 nếu UCLN =1 ta in ra cặp a[i],a[j] đó

f Ta tạo 2 mảng mới: mảng b chứa các phần tử không trùng nhau của mảng a, mảng c chứa tần số xuất hiện của các số tương ứng ở mảng b ( khởi tạo các phần

tử của c =0)

Khởi tạo b[0]=a[0] Duyệt qua các phần tử của mảng a:

+Nếu a[i] = b[i] thì c[i] =c[i]+1

+Nếu a[i] !=b[i] thì b[i+1]=a[i]

Trang 10

Bài 2: Cho ma trận vuông n dòng và n cột; các phần tử là các số nguyên (0≤ n < 100) Viết các hàm thực hiện các yêu cầu sau:

a.Tính tổng tất cả các phần tử của ma trận

b.Tìm giá trị dương nhỏ nhất của ma trận

c.Tính tổng các phần tử nằm trên đường chéo phụ

d.Kiểm tra xem các phần tử nằm trên đuờng chéo chính có tăng dần hay không ? (theo chiều từ góc trên bên trái xuống góc dưới bên phải)

Gợi ý:

a Khởi tạo 1 giá trị t=0.Sau đó duyệt qua từng phần tử của ma trận , thực hiện cộng t với từng phần tử trong ma trận:

b Khởi tạo giá trị min bằng dương vô cùng int min = int.MaxValue;

Thực hiện duyệt qua các phần tử của ma trận,nếu thấy phần tử đó nhỏ hơn min và lớn hơn 0 thì gán vào min

c.Ta nhận thấy rằng các phần tử a[i,j] thuộc đường chéo chính của ma trận cấp n thì có j=(n-1)-i với i ,j chạy từ 0 ->n-1

Để tính tổng các phần tử đường chéo phụ ta duyệt qua các phần tử a[i,j] của

ma trận nếu phần tử nào thỏa mãn j=(n-1)-i thì ta thực hiện cộng các phần tử đó lại d.Ta thấy trong ma trận cấp n thì số phần tử trên đường chéo chính la n

+ Đầu tiên , ta thực hiện việc khai báo một mảng một chiều []tg có n phần tử chứa các phần tử a[i,j] trên đường chéo chính của ma trận(với i=j) theo chiều từ góc bên trái phía trên đến bên phải phía dưới

+ Duyệt qua các phần tử tg[i] của mảng tg với i từ 0->n-2, tại mỗi phần tử kiểm tra xem nó có nhỏ hơn các phần tử tg[j] kế tiếp không với j=i+1 ->n-1

*Nếu không ,thoát khỏi vòng lặp trả ra giá trị False (không tăng dần)

*Ngược lại,kiểm tra phần tử tg[i] kế tiếp

Bài 3: Cho ma trận vuông n dòng n cột; mỗi phần tử của ma trận là một phân số (giả thiết rằng tử số và mẫu số của các phân số này là các số nguyên) Hãy thực hiện các yêu cầu sau:

a.Tìm phân số có giá trị nhỏ nhất nằm trong khoảng.(0;1)

b.Đếm số lượng phân số nằm trong ma trận tam giác trên có giá trị nằm trong khoảng (0,1)

Trang 11

c.Sắp xếp các phân số trong ma trận tăng dần từ trái qua phải và từ trên xuống dưới

publicint Tu;

publicint Mau;

}

classVD

{

staticPhanso[] DS;

a.Khởi tạo giá trị nhỏ nhất double min = 1

+Thực hiện duyệt qua các phần tử của ma trận.Tại mỗi phần tử thực hiện so sánh giá trị của tử số chia cho mẫu số với min ,nếu nhỏ hơn min va lớn hơn 0 thì gán min bằng giá trị đó:

+Hiện ra phần tử có giá trị tử số chia mẫu số bằng min Dùng một biến đếm int d=0 đếm các giá trị bằng min,nếu ra khỏi vòng lặp mà d=0 ta kết luận không có phân số cần tìm

b.Ta thấy các phần tử nằm trong ma trận tam giác trên thì luôn có vị trí hàng nhỏ hơn vị trí cột (i<j) Từ đó ta thực hiện việc đếm các phần tử của mảng o vi trí DS[i,j] thỏa mãn i<j và có giá trị Tử chia cho mẫu trong khoảng (0,1):

c.Thực hiện duyệt các phần tử DS[i,j] của mảng với i từ 0->n-1 và j từ 0->n-2, Với mỗi phần tử ta so sánh với từng phần tử kế tiếp nó nếu phần tử kế tiếp có giá trị nhỏ hơn thì thực hiện đổi chỗ 2 phần tử đó với nhau:

Bài 4: Cho một danh sách lưu trữ thông tin về các nhân viên trong một công ty, thông tin gồm :

- Mã nhân viên

- Họ và tên

- Năm sinh (số nguyên)

- Phòng ban

Trang 12

- Lương cơ bản (số nguyên)

- Thưởng (số nguyên)

- Thực lĩnh (số nguyên, trong đó thực lĩnh = lương cơ bản + thưởng )

Hãy thực hiện các yêu cầu sau:

a.Tính tổng thực lĩnh tháng của tất cả nhân viên trong công ty

b In danh sách những nhân viên có mức lương cơ bản thấp nhất

c Đếm số lượng nhân viên có mức thưởng >= 1200000

d In danh sách các nhân viên tăng dần theo phòng ban, nếu phòng ban trùng nhau thì giảm dần theo mã nhân viên

e Cập nhật tăng lương của tất cả các nhân viên lên 5%

Gợi ý: Để lưu trữ thông tin của từng nhân viên ta khai báo một trường lưu trữ các thông tin

structNhanVien

{

publicstring MaNV;

publicstring Hoten;

publicint Namsinh;

publicstring Phongban;

publicint LuongCB;

publicint Thuong;

b.Đầu tiên ta gán một biến min=int.MaxValue(giá trị dương vô cùng)

Trang 13

+Tiếp theo duyệt qua tất cả các nhân viên kiểm tra xem min>DS[i].LuongCB hay không?

-Nếu thoả mãn min = DS[i].LuongCB

-Ngược lại,tiếp tục duyệt các nhân viên tiếp theo

+Khi kết thúc vòng lặp kiểm tra đó ta sẽ tìm được danh sách những người có mức lương cơ bản thấp nhất

Bài 5:Viết chương trình tạo tập tin văn bản có tên là “BANGSO.INP” có cấu trúc như sau:

-Dòng đầu tiên ghi hai số m và n (m, n là các số nguyên dương nhập từ bàn phím) -Trong m dòng tiếp theo mỗi dòng ghi n số nguyên ngẫu nhiên trong phạm vi từ 0 đến 1000 (các số cách nhau ít nhất một dấu cách)

Hãy thực hiện các công việc sau:

a.Hãy cho biết chỉ số các dòng có chứa số nguyên tố (giả thiết các dòng trong tập tin văn bản được đánh số từ 0 đến m-1)

b.Xoay vòng các cột qua phải một vị trí (cột 0 sẽ qua cột 1, cột 1 qua cột 2, cột n-1 về cột 0)

c.Sắp xếp các phần tử tăng dần trên từng cột

Hãy ghi các kết quả trên vào file văn bản có tên là “BANGSO.OUT”

Bài 6: Cho mảng vuông n Hãy tìm phần tử lớn nhất trên mỗi đường chéo song song với đường chéo chính

Gợi ý: Xây dựng 2 hàm tính max của đường chéo thuộc ma trận đường chéo trên có phần

tử đầu tiên thuộc cột jvà max của đường chéo thuộc ma trận đường chéo dưới có phần tử đầu tiên thuộc hàng i:

Trang 14

*Với đường chéo thuộc ma trận đường chéo trên.Khởi tạo giá trị max=int.MinValue.Duyệt qua các phần tử của mảng tại mỗi phần tử a[i ,j] có j-i =địa chỉ cột nếu a[i ,j]>max gán max =a[i,j]

* Với đường chéo thuộc ma trận đường chéo dưới.Khởi tạo giá trị max=int.MinValue.Duyệt qua các phần tử của mảng tại mỗi phần tử a[i ,j] có i-j =địa chỉ hàng nếu a[i ,j]>max gán max =a[i,j]

Tại hàm Main() thực hiện:

+Duyệt qua số cột của ma trận ,tại mỗi cột gọi hàm tính max chéo trên của cột đó va in ra +Duyệt qua số hang của ma trận ,tại mỗi hang gọi hàm tính max chéo dưới của hàng đó

và in ra

C Bài tập làm thêm

Bài 1: Cho mảng một chiều gồm n tọa độ điểm (giả sử hoành độ và tung độ của các điểm là các số nguyên)

a.Hãy tìm một điểm trong mảng xa gốc tọa độ nhất

b.Hãy tìm tọa độ hai điểm gần nhau nhất

c.Hãy xác định tọa độ của hình chữ nhật nhỏ nhất bao hết cả n điểm trên (tọa độ góc trên bên trái và tọa độ góc dưới bên phải của hình chữ nhật)

-Trong các dòng tiếp theo ghi n số nguyên ngẫu nhiên trong phạm vi từ 1 đến

10000, mỗi dòng 10 số (các số cách nhau ít nhất một dấu cách)

Hãy thực hiện các công việc sau đây:

a.Tìm giá trị lớn nhất của các số trong tập tin DAYSO.INP

b.Đếm số lượng số chẵn, số lượng số lẻ trong tập tin DAYSO.INP

c.Hãy đếm số lượng số nguyên tố, số chính phương, số hoàn hảo, số Amstrong trong tập tin DAYSO.INP

Hãy ghi kết quả của các câu a,b,c trên vào tập tin văn bản có tên là “DAYSO.OUT”

Trang 15

Bài 3: Một đơn vị quan tâm về dân số lặp một bản thống kê số lượng người sinh trong từng năm, kể từ năm 1920 đến 1970 và lưu trữ bảng đó trong máy tính tính bằng một mảng một chiều N[1920 1970] với N[k] có giá trị bằng số người sinh trong năm k Hãy viết giải thuật thực hiện:

a In ra những năm mà không có người nào được sinh ra

b Tính số lượng những năm mà số người sinh ra không quá 10

c Tính số người trên 50 tuổi tính đến năm 1985

Trang 16

for (int i=1;i<=n;i++)

s=s+pow(x,i)/giaithua(i);// giaithua(i) = i!=1.2.3….i

Độ phức tạp theo cách này là O(N2), tuy nhiên chương trình không thể thực hiện được khi n lớn; chẳng hạn n =100 - do phép tính giai thừa của n không thể thực hiện

Algorithms2: O(N2

) double s=1,p;

for (int i=1; i<=n;i++)

Trang 17

Console.Write("Nhap n="); n = int.Parse(Console.ReadLine());

Console.Write("Nhap x="); x = double.Parse(Console.ReadLine());

for (int i = 1; i <= n; i++)

Bài 2: Cộng hai số nguyên lớn a và b, trong đó số a có m chữ số và số b có n chữ số

Số nguyên lớn ở đây là số có thể có đến vài trăm chữ số Để lưu trữ các số nguyên lớn này ta có thể dùng chuỗi (mỗi ký tự của chuỗi là một chữ số) hoặc dùng mảng một chiều (mỗi phần tử của mảng một chiều là một chữ số)

Gợi ý :Giả sử có 2 số a,b nhập vào ở dạng xâu so1 và so2

Đầu tiên ta thực hiện chuẩn hóa 2 số như sau : kiểm tra xem xâu nào có độ dài nhỏ hơn thì thêm 0 vào đầu xâu cho đến khi thu được 2 xâu so1 và so2 có độ dài như nhau

Thực hiện tính tổng :Khai báo một biến nhớ =0; Thực hiện duyệt qua các phần tử của 2 xâu từ phần tử cuối đến phần tử đầu, tại mỗi phần

Trang 18

Lời giản mẫu

StringBuilder s1 = newStringBuilder(so1);

StringBuilder s2 = newStringBuilder(so2);

chuanHoaSo(ref so1, ref so2);

StringBuilder kq = newStringBuilder("");

Trang 19

string so1, so2;

StringBuilder x = newStringBuilder("");

StringBuilder y = newStringBuilder("");

StringBuilder s = newStringBuilder("");

Console.WriteLine("\t\t BAN HAY NHAP VAO HAI SO NGUYEN");

Console.Write(" "); so1 = Console.ReadLine();

Console.WriteLine("+");

Console.Write(" "); so2 = Console.ReadLine();

x.Append('-', so1.Length > so2.Length ? so1.Length : so2.Length);

y.Append(' ', Math.Abs(so1.Length - so2.Length));

s.AppendFormat("\t\t{0}\n\n", "BAN HAY NHAP VAO HAI SO NGUYEN");

Trang 20

Duyệt qua các số tự nhiên từ 1->n ,tại mỗi số ta thực hiện tính tích của thương x

và số đó với thương x và các số trước nó (p=p*x/i) sau đó thực hiện cộng dồn các kết quả đó lại ta được tổng S

Bài 2: Cho dãy n số nguyên a0,a1, ,an-1 Hãy chuyển k phần tử đầu tiên của dãy về cuối dãy

Gợi ý: Sử dụng một mảng tg chứa k phần tử và mảng tmp chứa n-k phần tử Duyệt qua các phần tử a[i] của mảng (i: 0->n):

+Nếu i < k tg[i]=a[i] (chuyển k phần tử đầu sang tg

+Ngược lai, tmp[j++] =a[i] ( khởi tạo j=0) chuyển các phần tử còn lại sang tmp

Sau đó thực hiện ghép 2 mảng tmp và tg với nhau

Bài 3: Cho dãy n số nguyên {ai, ở đây giả sử i=1 n} Dãy con liên tiếp là dãy mà thành phần của nó là các thành phần liên tiếp nhau trong {a}, ta gọi tổng của dãy con là tổng tất

cả các thành phần của nó Tìm tổng lớn nhất trong tất cả các tổng của các dãy con của {a} Ví dụ nếu n = 7;

4 –5 6 –4 2 3 -7

Trang 21

Bài 2: Tìm số hạng thứ n của dãy Fibonasci (giải quyết khi n là một số lớn – khi đó ta không thể sử dụng đệ quy và cũng không thể sử dụng mảng để lưu trữ)

Bài 3: Cho dãy n số nguyên a0,a1, ,an-1.Hãy tìm dãy con liên tiếp tăng dài nhất

Bài 4: Cho dãy n số nguyên a0,a1, ,an-1.Hãy tìm đoạn con dài nhất chứa toàn số 0 Bài 5: Cho dãy n số nguyên a0,a1, ,an-1.Hãy tìm dãy con tăng chứa nhiều số

Trang 22

BÀI THỰC HÀNH 3+4 DANH SÁCH NỐI ĐƠN

a.Đếm xem trong danh sách có bao nhiêu số bằng x ?

b.Tìm phần tử dương nhỏ nhất trong danh sách

c Xóa phần tử x xuất hiện đầu tiên trong danh sách

Gợi ý: Khởi tạo một danh sách toàn cục l

a.Khởi tạo một biến đếm d=0.Duyệt qua từng phần tử của danh sách, nếu phần tử nào có giá trị là x thì tăng d=d+1;

b.Khởi tạo biến minduong=int.MaxValue Duyệt qua từng phần tử của danh sách nếu phần tử nào nhỏ hơn min thì gán bằng min

c.Sử dụng 2 nút p và t ,với p=l ,t trỏ vào nút phía trước nút p.Duyệt qua các phần

tử của danh sách đến khi gặp phần tử có giá trị x Lúc này p trỏ vào phần tử cần xóa ,ta xóa nút p bằng cách cho nút t nắm thông tin của nút sau nút p

*Chú ý:

+ Có 3 trường hợp p trỏ vào l (phần tử đầu), p trỏ vào cuối (p=null), p trỏ vào giữa

+ Để quan sát kết quả ta nhập dữ liệu cho danh sách liên kết l

Lời giản mẫu

using System;

classNode

{

publicint info;

publicNode link;

}

classDSLKD

Trang 23

{

staticNode l = newNode(); // l dùng để chứa địa chỉ của nút đầu tiên trong danh sách staticvoid Nhap()

{

Console.WriteLine("Nhap vao day so nguyen");

int i = 0; l = null; Node tg; char kt;

Trang 25

if (p == null) Console.WriteLine("x khong ton tai trong danh sach");

else

{

if (p == l) l = l.link;

elseif (p.link == null) t.link = null;

else t.link = p.link;

}

}

//Ham thuc hien cac chuc nang cua chuong trinh

staticvoid Main()

Gợi ý: Khởi tạo 1 danh sách toàn cục l

a.Tạo một danh sách l1 Sử dụng một nút tg duyệt qua từng phần tử của danh sách

l nếu có phần tử thỏa mãn là số chẵn và chia hết cho 3 thì ta gán 1 nút tmp =tg và tmp.link=null và đưa tmp vào danh sách l1 :

+Nếu l1 =null thì l=tmp

+Ngược lại them tmp vào danh sách l1 ( tmp.link=l1;l1=tmp)

b.Thực hiện so sánh từng nút i của danh sách với các nút j ở phía sau nó nếu giá trị của nút i > nút j ta đổi giá trị của 2 nút cho nhau

Lời giải mẫu

using System;

Trang 26

{

publicint info;

publicNode link;

Console.WriteLine("Nhap vao day so nguyen");

int i = 1; l = null; Node tg; char kt;

Trang 28

//Ham thuc hien cac chuc nang cua chuong trinh

staticvoid Main()

Khai báo các danh sách toàn cục P,Q, R

Nhập vào danh sách P va Q

Xây dựng một hàm thêm 1 nút tg vào danh sách l:

+Nếu l=null thì l=tg;

+Ngược lại l!=null : Duyệt qua các phần tử của danh sách l bằng một nút p

*Nếu p.số mũ =tg.số mũ thì cộng hệ số của p với hệ số của tg đưa kết quả vào p.hệ số

*Nếu trong ds l không có số mũ = số mũ của tg ta thực hiện chèn tg vào sau nút cuối cùng có số mũ nhỏ hơn tg ( có 3 th :chèn đầu –chèn cuối –chèn giữa)

Xây dựng hàm tính tổng như sau: khai báo R=null

Trang 29

Duyệt qua các nút của danh sách chứa đa thức P và Q tại mỗi phần tử ta gọi hàm thêm nút với tham số truyền vào là ds R và nút đang duyệt

Lời giải mẫu

using System;

classNode

{

publicint hs;

publicint mu;

publicNode next;

Console.WriteLine("Nhap thong tin cho da thuc");

int i = 1; l = null; Node tg; char kt;

do

{

Console.WriteLine("Nhapa thong tin cho phan tu thu:" + i);

tg = newNode();

Console.Write("He so:"); tg.hs = int.Parse(Console.ReadLine());

Console.Write("Mu:"); tg.mu = int.Parse(Console.ReadLine());

tg.next = null;

Add(ref l, tg); // bổ sung nút tg vào vị trí thích hợp theo số mũ

Console.WriteLine("Ban nhap tiep C/K"); kt = char.Parse(Console.ReadLine()); } while (char.ToUpper(kt) == 'C');

}

staticvoid Add(refNode l, Node tg)

{

if (l == null) l = tg;

Trang 30

//Them vao sau

else if (p == null && t.next == null) t.next = tg;

//Them vao giua

Trang 32

}

//Ham thuc hien cac chuc nang cua chuong trinh

staticvoid Main()

c.Đếm xem trong danh sách l có bao nhiêu số nguyên tố ?

d.Đếm xem trong danh sách có bao nhiêu số âm ? bao nhiêu số bằng 0 ? bao nhiêu

số dương ?

e.Đếm xem trong danh sách có bao nhiêu số bằng x ?

f.Tìm phần tử dương nhỏ nhất trong danh sách

Gợi ý: Khai báo danh sách toàn cục l

a.Khởi tạo giá trị max=int.MinValue.Duyệt qua các phần tử của danh sách tại mỗi phần tử so sánh với max, nếu lớn hơn max gán max bằng phần tử đó

b.Khởi tạo t=0.Duyệt qua các phần tử của danh sách và thực hiện cộng dồn các giá trị của nó vào t

Trang 33

c.Xây dựng một hàm kiểm tra một số bất kì có phải là số nguyên tố không ( giả sử hàm KTNT(int x) Sau đó duyệt qua các phần tử của danh sách với mỗi phần tử ta gọi hàm KTNT( giá trị phần tử) nếu trả giá trị True ta tăng biến đếm lên 1 ( với khởi tạo biến đếm =0)

d.Khởi 3 biến đếm âm ,dương và 0 bằng 0.Duyệt qua các phần tử của danh sách tại mỗi phần tử tiến hành kiểm tra:

+Nếu có giá trị <0 tăng biến đếm âm lên 1

+Nếu có giá trị >0 tăng biến đếm dương lên 1

+Nếu có giá trị =0 tăng biến đếm 0 lên 1

e.Duyệt qua các phần tử của danh sách ,tại mỗi phần tử nếu có giá trị = x ta thực hiện tăng giá trị biến đếm lên 1 (với khởi tạo biến đếm =0)

f.Khởi tạo giá trị minduong=int.MaxValue Thực hiện duyệt qua các phần tử của danh sách ,nếu có giá trị nhỏ hơn minduong và lớn hơn 0 thì gán min= giá trị đó Bài 2: Cho một danh sách liên kết đơn l, mỗi nút là một số nguyên dương

a.Xóa phần tử đầu tiên trong danh sách

b.Xóa phần tử cuối cùng trong danh sách

c.Xóa một phần tử được trỏ bởi con trỏ q

d.Xóa một phần tử ngay trước phần tử được trỏ bởi con trỏ q

e.Xóa một nút có giá trị k

Gợi ý: Khai báo danh sách toàn cục l

a.Muốn xóa phần tử đầu ta cho phần tử đầu nắm thông tin của phần tử kế tiếp nó(l=l.next)

b.Để xóa phần tử cuối ta cho phần tử đó trỏ vào null

c.Xóa con trỏ q:

+Nếu q trỏ vào đầu danh sách ta thực hiện xóa đầu ( l=l.next –câu a)

+Nếu q trỏ vào cuối danh sách ta thực hiện xóa cuối ( cho phần tử cuối trỏ vào null –câu b)

+Còn lai, ta cho con trỏ t ( với t trỏ vào phần tử phía trước q) nắm bắt thong tin của phần tử mà q nắm bắt (t.next =q.next)

d.Sử dụng 2 con trỏ t và p ( t trỏ vào phần tử trước p,p=l) duyệt qua các phần tử của danh sách đến khi p.next =q.Sau khi thoát khỏi vòng lặp p là nút cần xóa: +Nếu p=l thực hiện xóa đầu

Trang 34

+Nếu q=null thực hiện xóa cuối

+Ngược lại,cho t nắm bắt thông tin của q

e.Sử dụng 2 con trỏ t và p( t trỏ vào phần tử trước p,p=l) duyệt qua các phần tử của danh sách đến khi p=null hoặc giá trị của p =k.Thoát khỏi vòng lặp p trỏ vào nút

có giá trị k và t trỏ vào nút trước p

+Nếu p=l thực hiện xóa đầu

+Nếu p.next=null thực hiện xóa cuối

+Ngược lại,cho t nắm bắt thông tin của nút sau p (t.next =p.next)

Bài 3: Cho một danh sách liên kết đơn l, mỗi nút là một số nguyên dương

a.Hãy tạo danh sách l1 chỉ chứa các số nguyên tố từ danh sách l

b.Tách danh sách l thành 2 danh sách: một danh sách chứa toàn số chẵn, một danh sách chứa toàn số lẻ

Gợi ý: Khởi tạo danh sách toàn cục l

a.Xây dựng hàm kiểm tra 1 số bất kỳ có là số nguyên tố không giả sử là hàm KTNT(int x).Khai báo danh sách l1=null và con trỏ p=l1.Duyệt qua các phần tử của danh sách ,tại mỗi phần tử gọi hàm KTNT(phần tử đó) nếu giá trị trả về True

ta đưa nó vào danh sách l1 ( p.info=giá trị phần tử đó và p next=null)

b.Khởi tạo 2 danh sách l1=null , l2=null và 2 con trỏ p=l1 ,q=l2 Duyệt qua các phần tử của danh sách l:

Nếu phần tử đó là chẵn đưa vào l1: p.info=giá trị phần tử đó và p.next=null

Nếu phần tử đó là lẻ đưa vào l2: q.info=giá trị phần tử đó và q.next=null

Bài 4: Cho một danh sách liên kết đơn l, mỗi nút là một số nguyên dương

a.Trộn hai danh sách tăng dần thành một danh sách tăng dần

b.Sắp xếp các phần tử của L giảm dần theo phương pháp chọn trực tiếp

Gợi ý: Khai báo danh sách toàn cục l

a.Trước tiên ta xây dựng hàm thêm 1 nút tg vào danh sách l sao cho danh sách tăng dần:

+Nếu l=null thì l=tg ,l.next=null

+Ngược lại Sử dụng 1 con trỏ p duyệt qua các phần tử của l cho đến khi danh sách rỗng hoặc gặp giá trị lớn hơn giá trị nút tg Sau vòng lặp:

*Nếu p=null

Bài 5: Viết chương trình thực hiện các yêu cầu sau:

Trang 35

a.Khai báo cấu trúc dữ liệu của một danh sách liên kết đơn các tỉnh Biết rằng thông tin của mỗi tỉnh bao gồm: tên tỉnh, diện tích, dân số

b.Cài đặt các thao tác cơ bản cho danh sách liên kết đơn các tỉnh (thêm, sửa , xóa, duyệt)

c.Tính tổng diện tích của tất cả các tỉnh trong danh sách liên kết

d.Tìm địa chỉ của node chứa tính có diện tích lớn nhất trong danh sách liên kết e.Tìm một tỉnh có dân số lớn nhất

f.Sắp xếp danh sách tăng dần theo diện tích

Gợi ý : Khai báo danh sách toàn cục l

a.Khai báo lớp Node bao gồm 3 trường thông tin giá trị tên tỉnh (string) ,diện tích

và dan số (int) và địa chỉ nút kế tiếp

b.Các thao tác :

*Thêm :Khai báo nút tg chứa thông tin tỉnh cần thêm và tg.next=null Sử dụng con trỏ t và p=l ( t trỏ vào nút phía trước p) duyệt qua các phần tử của danh sách cho đến vị trí cần thêm :

+Nếu p=null báo lỗi vị trí

+Ngược lại ,cho t nắm thông tin của tg và tg nắm thông tin của p

*Sửa: Sử dụng một nút tg =l duyệt qua các phần tử của danh sách đến khi gặp vị trí cần sửa

+Nếu tg=null báo lỗi

+Ngược lại,gán các trường thông tin giá trị của nút tg trỏ vào bằng các giá trị mới

*Xóa: Khai báo nút tg chứa thông tin tỉnh cần thêm và tg.next=null Sử dụng con trỏ t và p=l ( t trỏ vào nút phía trước p) duyệt qua các phần tử của danh sách cho đến vị trí cần xóa :

+Nếu p=null báo lỗi

+Ngược lại, xóa nút p :

Nếu p=l, thực hiện xóa nút đầu Ngược lại, cho t nắm thông tin của nút sau p (xóa giữa và cuối)

c Sử dụng con trỏ tg =l duyệt qua các phần tử trong danh sách và thực hiện cộng dồn giá trị thông tin Diện tích của từng phần tử vào một biến tổng

d Khai báo một biến max có giá trị là giá trị Diện tích của phần tử đầu tiên trong danh sách và một biến vị trí =0 Thực hiện duyệt qua các phần tử trong danh sách

Trang 36

nếu phần tử nào có giá trị diện tích lớn hơn max thì gán bằng max và tăng biến vị trí lên 1

e Khai báo một biến max có giá trị là giá trị Dân số của phần tử đầu tiên trong danh sách Thực hiện duyệt qua các phần tử trong danh sách nếu phần tử nào có giá trị dân số lớn hơn max thì gán bằng max Để hiện ra tỉnh có dân số max ta duyệt qua các phần tử của danh sách nếu phần tử nào có giá trị dân số = max thì hiện các thông tin của phần tử đó ra màn hình

f Thực hiện duyệt qua các phần tử của danh sách tại mỗi phần tử so sánh giá trị diện tích của phần tử đó với từng phâng tử kế tiếp nó nếu lớn hơn thực hiện đổi chỗ toàn bộ các giá trị (tên tỉnh –dân số - diện tích)của 2 nút đó với nhau

Buổi 2

Bài 6: Cho danh sách nối đơn, có con trỏ LIST trỏ tới nút đầu tiên của danh sách này Hãy viết giải thuật thực hiện:

a Cộng thêm một số A vào số đang chứa tại trường INFO của mỗi nút

b Đếm số lượng các nút có trong danh sách đó

c Đếm số lượng các nút đang chứa số dương thuộc danh sách đó (giả sử các số chứa trong mỗi nút là số đại số khác không)

Bài 7: Hãy viết phần khai báo cấu trúc dữ liệu để mô tả một danh sách liên kết đơn mà mỗi phần tử chứa một số nguyên Viết các hàm thực hiện các yêu cầu sau:

a.Đếm các số nguyên tố của danh sách

b.Tạo một danh sách l1 chỉ chứa các số chẵn và chia hết cho 3 từ danh sách l c.Sắp xếp các phần tử của danh sách theo chiều giảm dần

Trang 37

Sau đó với mỗi yêu cầu ta thực hiện như sau:

a Ta phải xây dựng một hàm kiểm tra xem một số bất kỳ nào đó có phải là số nguyên tố không giả sử hàm đó là bool kiemtraNT(int n) Sau đó chúng ta duyệt qua tất cả các phần tử của danh sách, với mỗi phần tử tg.info chúng ta gọi hàm kiemtraNT ra thực hiện nếu kiemtraNT (tg.info) trả về giá trị là True nghĩa là phần tử tg.info chúng ta đang kiểm tra là số nguyên tố ta tăng biến đếm khởi tạo bằng 0 lên 1 Số nguyên tố bằng giá trị của biến đếm đó

b Ta khai báo mới danh sách mới l1=null,một node c=null và node tg=l Duyệt các phần tử trong danh sách tg cho đến khi tg=null,kiểm tra nếu phần tử đó chia hết cho 3 và chia hết cho 2(số chia hết cho 2 là số chẵn) thì ta thêm phần tử đó vào l1 bằng cách:khai báo 1 node tmp mới để chứa phần tử đang xét,rồi kiểm tra,nếu l1=null thì ta gán l1=tmp,ngược lại c.link = tg;c = tmp;

c Khai báo node i,j,gán i=l,ta sử dụng 2 vòng lặp while Trong khi i.link!=null ta gán j=i.link,rồi duyệt j cho đến khi j=null Kiểm tra giá trị của phần tử i.info nếu lớn hơn j.info thì ta hoán đổi giá trị của hai phần tử này qua một biến trung gian nào đó Kết thúc công việc đó ta được 1 danh sách giảm dần

Bài 8: Hãy khai báo kiểu danh sách liên kết đơn có tên LIST mà mỗi phần tử chứa các thông tin về một sinh viên bao gồm một số nguyên dương chỉ mã số sinh viên và một chuỗi ký tự cho biết họ và tên của sinh viên

Thực hiện các công việc sau:

a.Xây dựng hàm sắp xếp danh sách sinh viên theo thứ tự tăng dần của mã số sinh viên

b.Xây dựng hàm thêm một sinh viên mới vào danh sách(đã có thứ tự) sao cho vẫn bảo đảm thứ tự tăng dần của mã số

Gợi ý: Đầu tiên ta khai báo cấu trúc sinhvien gồm họ tên và mã sinh viên,sau đó khai 1 lớp node gồm thành phần dữ liệu info kiểu sinhvien,thành phần lưu trữ địa chỉ phần tử kế tiếp trong danh sách

a.Khai báo 2 node mới i=l(l là danh sách toàn cục)và j Trong khi phần tử tiếp theo của i chưa bằng null thì ta sẽ gán j=i.next(nghĩa là j sẽ chạy trước i,j bằng phần tử kế tiếp của i),trong khi j khác null thì kiểm tra nếu giá trị của i.masv.info<j.masv.info thì đổi chỗ i.masv.info và j.masv.info với nhau qua 1 biến trung gian nào đó

Trang 38

b Khai báo 2 node mới p=l,t=l Trong khi p.masv.info<mã sinh viên mới nhập vào

và p chưa rỗng thì gán t=p Khởi tạo 1 node tg mới gán tg.masv.info=mã sinh viên mới nhập vào Kiểm tra nếu l rỗng gán l=tg luôn,nếu p=l thì thêm vào đầu gán phần

tử tiếp theo của tg:tg.next=l;l=tg.,nếu p rỗng thì them vào sau gán t.next=tg,ngược lại tất cả điều trên ta thêm vào giữa

Bài 9: Cho một danh sách liên kết, mỗi nút chứa một số nguyên

a.Thêm một phần tử có giá trị x vào đầu danh sách

b.Chỉ giữ lại một giá trị trong số các giá trị giống nhau

c.Kiểm tra xem danh sách có được sắp xếp tăng dần hay không?

d.Đảo ngược danh sách

e.Sắp xếp các số chẵn trong danh sách theo thứ tự tăng, sắp xếp các số lẻ

theo thứ tự giảm dần, các số 0 giữ nguyên vị trí

Gợi ý: Trước tiên ta khai báo 1 lớp node gồm trường lưu trữ thông tin ,trường chứa địa chỉ và nhập một danh sách mới, sau đó với mỗi yêu cầu ta thực hiện như sau:

a.Kiểm tra danh sách nếu rỗng thì ta gán l=tg nghĩa là đó là phần tử đầu tiên của danh sách,ngược lại ta cho địa chỉ tiếp theo của tg nắm bắt lấy l(tg.next=l)và gán l=tg

b.Đầu tiên kiểm tra xem danh sách nếu rỗng(l=null) thì in ra thông báo danh sách rỗng Ngược lại khởi tạo node i=l,j,ta sử dụng 2 vòng lặp Thực hiện các công việc sau cho đến khi j=l:gán j=i.next,trong khi j!=l thì kiểm tra nếu i.info=j.info thì xóa

j đi

c Kiểm tra xem danh sách nếu rỗng(l=null) thì in ra thông báo danh sách rỗng Ngược lại khai báo node tg=l,kiểm tra xem phần tử bên phải của tg không bằng l(tg.next!=l) và giá trị của tg lớn hơn giá trị của phần tử tiếp theo(tg.next.info) thì gán ok=false(ok là biến theo dõi tính đúng hay sai) rồi thoát khỏi vòng lặp Nếu ok=true thì dãy tăng dần ngược lại là dãy k tăng dần

d Đầu tiên ta đếm xem danh sách đó có bao nhiêu phần tử Sau đó ta duyệt ngược danh sách đó cho 1 vòng lặp lồng trong 1 vòng lặp khác Vòng lặp bên trong chạy sau vòng lặp ngoài 1 phần tử ta hoán vị 2 phần tử kế nhau cho đến khi nào hết danh sách thì thôi

e.Khởi tạo thêm 2 node l1,l2 rỗng duyệt hết danh sách nếu phần tử chia hết cho 2 thì them vào danh sách l1,không chia hết them vào danh sách l2,bằng 0 thì giữ

Trang 39

nguyên Sau đó sắp xếp tăng dần cho l1,giảm dần cho l2 Cuối cùng ta chèn l1,l2 vào l

C Bài tập làm thêm

Bài 1:.Viết chương trình thực hiện các yêu cầu sau:

a.Khai báo cấu trúc dữ liệu của một danh sách liên kết đơn để lưu tọa độ các đỉnh của một đa giác lồi trong mặt phẳng OXY

b.Tính chu vi của đa giác

c.Tính diện tích của đa giác

Gợi ý: Tạo một lớp node gồm 2 trường info lưu trữ thông tin tung độ, hoành độ và 1 con trỏ chỉ đến cấu trúc node để lưu tọa độ các đỉnh của một đa giác lồi Sau đó thực hiện việc nhập danh sách với các tọa độ của các đỉnh đa giác đó

a Tính độ dài vectơ các cạnh của đa giác Sau đó áp dụng công thức tính chu vi

đa giác bằng tổng các cạnh của đa giác đó

b Diện tích của 1 đa giác lồi áp dụng công thức x3y2+….+(xn-1)yn-xn(yn-1)+xny1-x1yn)

s=1/2(x1.y2-x2.y1+x2y3-Ghi chú: Đa giác lồi (Convex polygon): toàn bộ đa giác nằm về một phía của đường thẳng chứa cạnh bất kỳ nào của đa giác

Bài 2: Cho một danh sách nối đơn có con trỏ P trỏ tới nút đầu tiên của nó Biết rằng danh sách này không rỗng Hãy viết giải thuật:

a Bổ sung một nút mới vào sau nút có địa chỉ T (hay : con trỏ T trỏ tới nó) đang có trong danh dách đó

b Bổ sung một nút mới vào trước nút trỏ bởi T đang có trong danh sách đó

Biết rằng phần thông tin dành cho nút mới đang chứa trong ô có địa chỉ là X

c Bổ sung một nút vào vị trí thứ k của danh sách

d Tìm xem trong danh sách có nút mang giá trị là Y hay không? Nếu thấy thì trả ra địa chỉ của nút đó, ngược lại trả ra giá trị null

Bài 3: Cho một danh sách nối đơn có con trỏ Q trỏ tới nút đầu tiên của danh sách Biết rằng danh sáhc này không rỗng Hãy viết giải thuật:

a Loại bỏ nút đầu tiên của danh sách

b loại bỏ nút trỏ bởi T đang có trong danh sách Biết rằng T không phải là đại chỉ nút đầu tiên và cũng không phải là đại chỉ nút cuối cùng

c Loại bỏ nút thứ k của danh sách

Trang 40

Bài 4: Cho ba danh sách nối đơn, lần lượt có nút đầu tiên được trỏ bởi L1, L2, L3 Hãy viết giải thuật:

a Ghép danh sách L2 vào sau danh sách L1 và cho L trỏ tới danh sách tổng hợp

b Ghép danh sách L3 vào trước L2 và L1 vào sau L2 và cho L trỏ tới danh sách tổng hợp

Giả sử rằng cả ba danh sách này đều không rỗng

Bài 5: Cho một danh sách nối đơn có con trỏ P trỏ tới nút đầu tiên của nó, danh sách này không rỗng Cho con tỏ Q trỏ tới một nút đang có trong danh sách Hãy viết giải thuật tách danh sách này thành hai danh sách con Danh sách thứ nhất sẽ được trỏ bởi P

Danh sách thứ hai sẽ trỏ bởi Q (nút trỏ bởi Q sẽ là nút đầu tiên của danh sách thứ hai) Bài 6: Cho danh sách nối đơn, không rỗng, có con trỏ LIST trỏ tới nút đầu tiên Biết rằng trường INFO của mỗi nút đều chứa một số dương Hãy viết giải thuật:

Tính giá trị trung bình của các số chứa trong danh sách

Bài 7: Viết khai báo và các thủ tục cài đặt danh sách bằng mảng Dùng các thủ tục này để viết:

a Thủ tục nhận một dãy các số nguyên nhập từ bàn phớm, lưu trữ nó trong danh sách theo thứ tự nhập vào

b Thủ tục nhận một dãy các số nguyên nhập từ bàn phím, lưu trữ nó trong danh sách theo thứ tự ngược với thứ tự nhập vào

c Viết thủ tục in ra màn hình các phần tử trong danh sách theo thứ tự của nó trong danh sách

Bài 8: Viết thủ tục thêm một phần tử trong danh sách liên kết đã có thứ tự sao cho ta vẫn

có một danh sách có thứ tự

Bài 9: Viết thủ tục nhận vào từ bàn phím một dãy số nguyên, lưu trữ nó trong một danh sách có thứ tự không giảm, theo cách sau: với mỗi phần tử được nhập vào thủ tục phải tìm vị trí thích hợp để xen nó vào danh sách cho đúng thứ tự Viết thủ tục trên cho trường hợp danh sách được cài đặt bằng mảng và cài đặt bằng con trỏ

Bài 10: Viết thủ tục loại bỏ các phần tử trùng nhau (giữ lại duy nhất 1 phần tử) trong một danh sách có thứ tự không giảm, trong hai trường hợp: cài đặt bằng mảng và cài đặt bằng con trỏ

Ngày đăng: 16/05/2019, 18:04

TỪ KHÓA LIÊN QUAN

w