You are on page 1of 33

ĐẠI HỌC ĐÀ NẴNG

TRƯỜNG ĐẠI HỌC BÁCH KHOA


KHOA CÔNG NGHỆ THÔNG TIN

ĐỒ ÁN CƠ SỞ
Đề tài 319: SỬ DỤNG THAO TÁC LÀM VIỆC VỚI
DANH SÁCH LIÊN KẾT STACK VÀ FILE, GIẢI
PHƯƠNG TRÌNH BẬC CAO BẰNG PHƯƠNG PHÁP
DÂY CUNG.

NGƯỜI HƯỚNG DẪN: TS. PHẠM CÔNG THẮNG


SINH VIÊN THỰC HIỆN: HUỲNH VIẾT TRIỀU
LỚP: 19TCLC_Nhat2
NHÓM: 19N99B

Đà Nẵng, 7/2020
Đồ án Cơ sở

LỜI MỞ ĐẦU

Trước tiên em xin chân thành cảm ơn thầy Phạm Công Thắng, người đã từng
bước hướng dẫn, giúp đỡ em trong quá trình thực hiện đồ án cơ sở này.
Trong quá trình học tập, cũng như trong quá trình làm đồ án cơ sở không thể
tránh khỏi những thiếu sót không đáng có, em rất mong nhận được sự góp ý quý báu
của tất cả các Thầy Cô cũng như tất cả các bạn để đồ án cơ sở của em được hoàn thiện
hơn.
C là một ngôn ngữ nền tảng giúp bạn làm quen với việc lập trình. Khi đã học
vững được ngôn ngữ này bạn sẽ rất dễ dàng tiếp cận với các loại ngôn ngữ khác như
JAVA, PYTHON, C#… Vì vậy việc học C trở nên rất cấp thiết và quan trọng nếu bạn
là người yêu lập trình và muốn nó trở thành người bạn với nó. Nói nền tảng nhưng
không phải C là một ngôn ngữ dễ tiếp cận, điển hình như các phần như danh sách liên
kết, FILE,… cũng đang làm khó các bạn lập trình viên của chúng ta nếu chưa hiểu bản
chất của chúng. Ngoài ra việc sử dụng chúng để giải quyết các bài toán cũng trở nên
nan giải với chúng ta. Vì vậy trong khuôn khổ của đồ án cơ sở B này em xin sử dụng
các kiến thức mà thấy cô đã trang bị và sự tìm tòi từ sách vở và bạn bè để có thể làm
rõ một phần những khó khăn của các bạn sinh viên trong quá trình học tập. Cụ thể em
sẽ dùng kiến thức về danh sách liên kết kiểu stack và file để giải phương trình bậc cao
bằng phương pháp dây cung.
Em xin cam đoan rằng chuyên đề này là do chính em thực hiện, các số liệu thu
thập và kết quả phân tích trong đề án là trung thực, đề án không trùng với bất kỳ đề án
nào.
Một lần nữa em xin chân thành cảm ơn và kính chúc quý Thầy Cô dồi dào sức
khỏe và thành công trong cuộc sống.

Đà Nẵng, ngày 20 tháng 7 năm 2020


Sinh viên thực hiện

Huỳnh Viết Triều Trang 2


Đồ án Cơ sở

MỤC LỤC
.............................................................................................................................. 1
LỜI MỞ ĐẦU.......................................................................................................2
MỤC LỤC............................................................................................................. 3
DANH MỤC HÌNH VẼ........................................................................................4
1. GIỚI THIỆU ĐỀ TÀI....................................................................................5
2. CƠ SỞ LÝ THUYẾT.....................................................................................5
2.1. Ý tưởng................................................................................................5
2.3. Cơ sở lý thuyết.....................................................................................5
3. TỔ CHỨC CẤU TRÚC DỮ LIỆU VÀ THUẬT TOÁN.............................15
3.1. Phát biểu bài toán...............................................................................15
3.2. Cấu trúc dữ liệu..................................................................................15
3.3. Thuật toán...........................................................................................16
4. CHƯƠNG TRÌNH VÀ KẾT QUẢ..............................................................16
4.1. Tổ chức chương trình.........................................................................16
4.2. Kết quả...............................................................................................17
4.2.1. Giao diện chính của chương trình...................................................17
4.2.2. Kết quả thực thi của chương trình...................................................19
4.2.3. Nhận xét..........................................................................................19
KẾT LUẬN VÀ HƯỚNG PHÁT TRIỂN...........................................................19
a. Kết luận..................................................................................................19
b. Hướng phát triển....................................................................................20
TÀI LIỆU THAM KHẢO...................................................................................21
PHỤ LỤC ...........................................................................................................22

Huỳnh Viết Triều Trang 3


Đồ án Cơ sở

DANH MỤC HÌNH VẼ

Hình 1: Mô phỏng cấu trúc mảng một chiều.

Hình 2: Một mô phỏng về mảng hai chiều có kích thước 3x5.

Hình 3: Biểu diễn cấu trúc ngăn xếp (Stack).

Hình 4: Giao diện của chương trình khi khởi động chương trình.

Hình 5: Giao diện của chương trình sau khi nhập một phím bất kì.

Hình 6: Giao diện của toàn bộ chương trình.

Huỳnh Viết Triều Trang 4


Đồ án Cơ sở

1. GIỚI THIỆU ĐỀ TÀI


Viết chương trình bằng ngôn ngữ C thực hiện các công việc sau:

a) Đọc N ( ) phần tử số của danh sách liên kết từ file DAYSO.IN


b) Thực hiện xóa một phần tử trong danh sách này, hiển thị kết quả và lưu kết quả ra
file. RESULT1.OUT.
c) Sau khi thực hiện câu b), chúng ta nhận được một danh sách có M (M=N-1)phần tử

Biết rằng các phần tử này là hệ số của đa thức sau:

Hãy tìm các nghiệm của phương trình bằng phương pháp dây cung

(với sai số ), hiển thị kết quả và lưu kết quả ra file RESULT2.OUT.
Yêu cầu: Sử dụng danh sách liên kết kiểu ngắn xếp để thực hiện các công việc trên.
Dữ liệu đầu vào: file DAYSO.IN
Dữ liệu đầu ra: Kết quả thực hiện được lưu ở 2 file RESULT1.OUT, RESULT2.OUT.

2. CƠ SỞ LÝ THUYẾT

2.1. Ý tưởng
- Bắt đầu chương trình, một dãy số gồm N phần tử được đọc từ file DAYSO.IN.
- Sau khi đọc được được N phần tử số của danh sách liên kết từ file DAYSO.IN và in
ra màn hình, chương trình sẽ thực hiện xóa một phần tử trong danh sách này theo cơ
chế Last In- First Out, in kết quả sau khi xóa ra màn hình và lưu vào file
RESULT1.OUT.
- Tiếp theo, từ danh sách có được sau khi xóa một phần tử ( có M = N- 1 phần tử), các
phần tử này là hệ số của của đa thức G(x) = 0 bậc M-1, tìm nghiệm của đa thức này
bằng phương pháp dây cung, hiển thị kết quả và lưu vào file RESULT2.OUT.

2.2. Cơ sở lý thuyết

2.2.1 Kiểu cấu trúc struct

- Định nghĩa

Huỳnh Viết Triều Trang 5


Đồ án Cơ sở
Một cấu trúc trong ngôn ngữ lập trình C ( và nhiều dẫn xuất) là một khai báo kiểu
dữ liệu tổng hợp ( hoặc bản ghi) xác định danh sách các biến vật lý được nhóm
theo một tên trong một khối bộ nhớ, cho phép các biến khác nhau được truy cập
thông qua một con trỏ hoặc bằng tên khai báo struct trả về cùng một địa chỉ. Kiểu
dữ liệu cấu trúc có thể chứa các loại dữ liệu khác vì vậy được sử dụng cho các
bản ghi loại dữ liệu hỗn hợp, chẳng hạn như mục nhập thư mục ổ cứng ( chiều
dài tệp, tên, phần mở rộng, địa chỉ vật lý, v.v.) hoặc các bản ghi loại hỗn hợp
khác (tên, địa chỉ, điện thoại, số dư, v.v.)[1].

Cấu trúc C tham chiếu trực tiếp một khối bộ nhớ vật lý liền kề, thường được phân
định (kích thước) theo các ranh giới độ dài từ. Nó tương ứng với tính năng có tên
tương tự có sẵn trong một số bộ lắp ráp cho bộ xử lý Intel. Việc triển khai ngôn
ngữ có thể sử dụng các ranh giới nửa từ hoặc byte ( cho việc đóng gói dày hơn,
sử dụng ít bộ nhớ hơn) được coi là tiến bộ vào giữa những năm 1980. Là một
khối bộ nhớ liền kề, mỗi trường trong một cấu trúc được đặt ở một độ lệch cố
định nhất định từ đầu[1].

Do nội dung của một cấu trúc được lưu trữ trong bộ nhớ liền kề, nên toán tử
sizeof phải được sử dụng để lấy số byte cần thiết để lưu trữ một loại cấu trúc cụ
thể, giống như nó có thể được sử dụng cho các nguyên hàm . Căn chỉnh của các
trường cụ thể trong cấu trúc (liên quan đến ranh giới từ ) là dành riêng cho việc
triển khai và có thể bao gồm phần đệm, mặc dù các trình biên dịch hiện đại
thường hỗ trợ lệnh #pragma pack, thay đổi kích thước theo byte được sử dụng để
căn chỉnh[1].

- Cú pháp khai báo

Cú pháp chung cho khai báo struct trong C là:

Struct <tên cấu trúc>

<tên kiểu dữ liệu><tên thành phần 1 >;

<tên kiểu dữ liệu<>tên thành phần 2 >;

- Từ khóa typedef

Một kiểu dữ liệu có thể được định nghĩa bằng cách sử dụng từ khóa typedef.

Huỳnh Viết Triều Trang 6


Đồ án Cơ sở
Nó không tạo ra một kiểu dữ liệu mới, mà định nghĩa một tên mới cho một kiểu

Cú pháp: typedef type name;

Ví dụ: typedef float deci;

typedef không thể sử dụng với storage classes

- Gán sử dụng cấu trúc

Có thể sử dụng câu lệnh gán đơn giản để gán giá trị của một biến cấu trúc cho
một biến khác có cùng kiểu

Chẳng hạn, nếu books1 và books2 là các biến cấu trúc có cùng kiểu.

books2 = books1;

- Truy cập phần tử của cấu trúc

Các phần tử của cấu trúc được truy cập thông qua việc sử dụng toán tử
chấm(.),toán tử này còn được gọi là toán tử thành viên – membership.

Cú pháp: structure_name.element_name

Ví dụ: scanf(“%s”, books1.bk_name);

2.2.2. FILE

- Các kiểu file

· File văn bản – text files: File văn bản là file thường có đuôi là .txt. Những file
này bạn có thể dễ dàng tạo ra bằng cách dùng các text editer thông dụng như
Notepad, Notepad++, Sublime Text, …

· File nhị phân – binary file: File nhị phân thường có đuôi mở rộng là .bin.

- Thao tác với file trong ngôn ngữ C

· Thao tác mở file

· Để đọc ghi file trong C cũng như trong mọi ngôn ngữ lập trình, việc đầu tiên bạn
cần làm là mở file mà bạn muốn làm việc. Trong ngôn ngữ lập trình C, chúng ta
có thể mở file bằng cách sử dụng hàm fopen() trong thư viện stdio.h như sau: fptr
= fopen("fileopen", "mode");

Huỳnh Viết Triều Trang 7


Đồ án Cơ sở
· Trong đó mode là một tham số chúng ta cần chỉ định.

· Các tham số của mode được miêu tả trong bảng 1.

Bảng 1: Tham số mode trong file

Mode Ý nghĩa Nếu file không tồn tại

r Mở file chỉ cho phép đọc Nếu file không tồn tại,
fopen() trả về NULL.
rb Mở file chỉ cho phép đọc Nếu file không tồn tại,
dưới dạng nhị phân fopen() trả về NULL.
w Mở file chỉ cho phép ghi. Nếu file đã tồn tại, nội
dung sẽ bị ghi đè. Nếu
file không tồn tại, nó sẽ
được tạo tự động.
wb Mở file chỉ cho phép ghi Nếu file đã tồn tại, nội
dưới dạng nhị phân dung sẽ bị ghi đè. Nếu
file không tồn tại, nó sẽ
được tạo tự động.
a Mở file ở chế độ ghi Nếu file không tồn tại,
“append”. Tức là sẽ ghi nó sẽ được tạo tự động.
vào cuối của nội dung đã
có.
ab Mở file ở chế độ ghi nhị Nếu file không tồn tại,
phân “append”. Tức là sẽ nó sẽ được tạo tự động.
ghi vào cuối của nội
dung đã có.
r+ Mở file cho phép cả đọc Nếu file không tồn tại,
và ghi. fopen() trả về NULL.
rb+ Mở file cho phép cả đọc Nếu file không tồn tại,
và ghi ở dạng nhị phân. fopen() trả về NULL.
w+ Mở file cho phép cả đọc Nếu file đã tồn tại, nội
và ghi. dung sẽ bị ghi đè. Nếu
file không tồn tại, nó sẽ
được tạo tự động.
wb+ Mở file cho phép cả đọc Nếu file đã tồn tại, nội
và ghi ở dạng nhị phân. dung sẽ bị ghi đè. Nếu

Huỳnh Viết Triều Trang 8


Đồ án Cơ sở

file không tồn tại, nó sẽ


được tạo tự động.
a+ Mở file cho phép đọc và Nếu file không tồn tại,
ghi “append”. nó sẽ được tạo tự động.
ab+ Mở file cho phép đọc và Nếu file không tồn tại,
ghi “append” ở dạng nhị nó sẽ được tạo tự động.
phân.

2.2.3. Mảng một chiều

- Định nghĩa

Mảng là một tập hợp tuần tự các phần tử có cùng kiểu dữ liệu và các phần tử được
lưu trữ trong một dãy các ô nhớ liên tục trên bộ nhớ. Các phần tử của mảng được truy
cập bằng cách sử dụng “chỉ số”. Mảng có kích thước N sẽ có chỉ số từ 0 tới n-1. Hình
1 mô phỏng cho cấu trúc mảng một chiều [1,3].

Hình 1: Mô phỏng cấu trúc mảng một chiều.

- Khai báo mảng 1 chiều

Cú pháp khai báo mảng 1 chiều khác nhau với từng ngôn ngữ lập trình.

Chẳng hạn, trong C/C++, việc khai báo mảng cần 2 tham số sau:

Kích thước của mảng: Việc này xác định số lượng phần tử có thể được

lưu trữ trong mảng

Kiểu dữ liệu của mảng: Việc này chỉ định kiểu dữ liệu của các phần tử trong mảng; là
số nguyên, số thực, ký tự hay là kiểu dữ liệu nào đó.

Một ví dụ khai báo mảng trong C/C++: int arr[5];

Huỳnh Viết Triều Trang 9


Đồ án Cơ sở
Đây là cách khai báo mảng tĩnh; cách khác là khai báo động kích thước vừa đủ dùng.
Đối với mảng động, kích thước mảng sẽ tăng lên khi số lượng phần tử mảng tăng lên
vượt qua kích thước cũ.

- Khởi tạo mảng 1 chiều

Mảng có thể được khởi tạo ngay tại thời điểm khai báo mảng hoặc khởi

tạo sau khi khai báo

Cú pháp để khởi tạo mảng trong khi khai báo là:

type arr[size] = {elements};

Một ví dụ khai báo kèm khởi tạo mảng trong C

int arr[5] = {4, 12, 7, 15, 9};

Mảng cũng có thể được khởi tạo sau khi khai báo xong, bằng cách gán

giá trị cho từng phần tử của mảng sử dụng chỉ số

type arr[size]

arr[index] = 12

Ví dụ trên C

int arr[5];

arr[0] = 4;

arr[1] = 12;

2.2.4. Mảng hai chiều

- Định nghĩa:

Mảng hai chiều là một bảng các phần tử cùng kiểu, mảng cũng được đặt tên như mảng
một chiều, các phần tử cũng được đánh số thứ tự để quản lí. Tuy nhiên, mỗi phần tử
của mảng hai chiều được bằng hai chỉ số, chúng ta tạm gọi chúng là chỉ số dòng và chỉ
số cột. Hình 2 mô phỏng cho cấu trúc mảng hai chiều [1,4].

Huỳnh Viết Triều Trang 10


Đồ án Cơ sở

Hình 2: Một mô phỏng về mảng hai chiều có kích thước 3x5.

-Khai báo mảng 2 chiều :

Để khai báo mảng 2 chiều, bạn phải chỉ định các tham số sau:

+Row-size: Khai báo số hàng của mảng 2 chiều

+Column-size: Khai báo số cột của mảng 2 chiều

+Type of array: Kiểu dữ liệu của mảng 2 chiều. Việc này chỉ định kiểu dữ liệu của các
phần tử trong mảng; là số nguyên, số thực, ký tự hay là kiểu dữ liệu nào đó

Cú pháp khai báo mảng 2 chiều có dạng:

Type arr[row_size][column_size]

Ví dụ: int arr[3][5];

-Khởi tạo mảng 2 chiều:

Giống như mảng 1 chiều , mảng 2 chiều cũng có thể khởi tạo trong quá trình khai báo
hoặc khởi tạo sau khi khai báo.

Cú pháp khởi tạo của mảng 2 chiều trong khi khai báo như sau:

Type arr[row_size][column_size]={{elements},{elements}…}

Ví dụ: arr[3][5]={{1,2,3,3,4},{1,2,3,4,5,},{5,4,2,5,4,2}};

Huỳnh Viết Triều Trang 11


Đồ án Cơ sở
2.2.5.1 Danh sách liên kết

Định nghĩa :

Danh sách liên kết là một tập hợp tuyến tính các phần tử dữ liệu, với thứ tự không
được đưa ra bởi vị trí vật lí của chúng trong bộ nhớ. Thay vào đó, mỗi phần tử chỉ đến
phần tử tiếp theo. Nó là một cấu trúc dữ liệu bao gồm một tập hợp các nút cùng thể
hiện một dãy. Ở dạng cơ bản nhất, mỗi nút chứa: dữ liệu, và một tham chiếu (hay nói
cách khác là liên kết) tới nút kế tiếp trong dãy. Cấu trúc này cho phép chèn hay loại bỏ
bất kì phần tử nào trong chuỗi một cách hiệu quả. Các biến thể phức tạp hơn như thêm
các liên kết bổ sung, cho phép chèn hay loại bỏ các nút hiệu quả hơn tại vị trí bất kì.
Một nhược điểm của danh sách liên kết là thời gian truy cập là tuyết tính ( và khó thực
thi ống dẫn). Truy cập nhanh hơn, ví dụ như truy cập ngẫu nhiên, là không khả thi.
Mảng có vùng đệm ( cache locality) tốt hơn so sánh với liên kết.

Danh sách liên kết là một trong những cấu trúc dữ liệu đơn giản và phổ biến nhất. Nó
có thể được hiện thực một số kiểu dữ liệu trừu tượng phổ biến khác, bao gồm danh
sách ( LIST), ngăn xếp ( STACK), hàng đợi, mảng liên kết và S-expression, mặc dù
không có gì lạ khi thực hiện các cấu trúc đó mà không dựa trên nền tảng của danh sách
liên kết.

So sánh sự tương quan giữa danh sách liên kết và mảng:

Danh sách liên kết Mảng


Vùng nhớ của các phần từ trong danh Vùng nhớ của các phần tử trong mảng
sách liên kết được sắp xếp tùy ý (do hệ được sắp xếp liên tục nhau
điều hành ). Các phần tử lưu 1 con trỏ tới
phần tử tiếp theo.
Cần phải duyệt tuần tự khi muốn truy Truy cập tới phần tử trong mảng là truy
cập tới phần tử trong danh sách liên kết. cập trực tiếp dựa vào địa chỉ số ( ví dụ :
a[0],a[1],a[2],…a[n])
Kích thước của danh sách liên kết có thể Kích thược của mảng là hằng số, không
thay đổi khi chạy chương trình. thay đổi khi chạy chương trình .
Sử dụng danh sách liên kết tối ưu được Sử dụng mảng không tối ưu được bộ nhớ
bộ nhớ . Vùng nhớ được cấp phát thêm . Có thể thừa hoặc thiếu bộ nhớ khi xóa
khi cần chèn thêm phần tử mới, vùng hoặc chèn phần tử vào mảng.
nhớ được free khi xóa phần tử .

2.2.5.2 Danh sách liên kết kiểu ngăn xếp (STACK)

Định nghĩa ngăn xếp:

Huỳnh Viết Triều Trang 12


Đồ án Cơ sở
Ngăn xếp (Stack) là một danh sách mà người ta giới hạn việc thêm vào hoặc loại bỏ
một phần tử chỉ thực hiện tại một đầu của danh sách, đầu này gọi là đỉnh(TOP) của
ngăn xếp. Cách biểu diễn cấu trúc ngăn xếp được minh họa ở hình 1. [1,3]

Hình 3: Biểu diễn cấu trúc ngăn xếp (Stack)

Ví dụ: Ta có thể xem hình ảnh trực quan của ngăn xếp bằng một chồng đĩa đặt trên
bàn . Muốn thêm vào chồng đó 1 đĩa ta để đĩa mới trên đỉnh chồng , muốn lấy các đĩa
ra khỏi chồng ta cũng phải lấy đĩa trên trước. Như vậy ngăn xếp là cấu trúc có tính
chất “ vào sau – ra trước” hay “ vào trước ra sau”(LAST IN – FIRST OUT (LIFO))
hay (FIRST IN – LAST OUT (FILO)).

Các phép toán trên ngăn xếp [3]:

INIT(L): tạo một ngăn xếp rỗng.

TOP(L): xem như một hàm trả về phần tử tại đỉnh của ngăn xếp. Nếu ngăn xếp rỗng
thì hàm không xác định.

POP(L) : Chương trình con xóa một phần tử tại đỉnh ngăn xếp.

PUSH (L) chương trình thêm một phần tử vào đỉnh ngăn xếp.

ISEMPTY(L) Kiểm tra ngăn xếp rỗng. Hàm cho kết quả 1 (true) nếu ngăn xếp rỗng thì
trả về kết quả 0 (false) trong trường hợp ngược lại.

Cài đặt ngăn xếp bằng danh sách :

Huỳnh Viết Triều Trang 13


Đồ án Cơ sở
Do ngăn xếp là một danh sách đặc biệt nên ta có thể sử dụng kiểu dữ liệu trừu tượng
danh sách để biểu diễn cách cài đặt của nó. Như vậy, ta có thể khai báo ngăn xếp như
sau:

Khi chúng ta đã dùng danh sách để biểu diễn cho ngăn xếp thì ta nên sử dụng các phép
toán trên danh sách để cài đặt các phép toán trên ngăn xếp. Sau đây là phần cài đặt
ngăn xếp bằng danh sách mà tôi sử dụng trong đồ án:

+Tạo ngăn xếp rỗng:


void Init(struct List *s) {

s->head = s->tail = NULL;

+Kiểm tra xem ngăn xếp có rỗng không:

int isEmpty(struct List *s) {

if (s->head == NULL) return 1;

else return 0;

+Hàm tạo node:

struct Node *creat_Node(float x)

struct Node *p = (struct Node*) malloc( sizeof(struct Node) );

p->data = x;

p->next = NULL;

return p;

Hàm thêm một phần tử vào đỉnh của ngăn xếp:

void push(struct List *s, float x)

Huỳnh Viết Triều Trang 14


Đồ án Cơ sở
{

struct Node *p = creat_Node(x);

if (isEmpty(s))

s->head = s->tail = p; // neu stack rong thi ta gan p la phan tu dau va cuoi

else

p->next = s->head; // cho phan tu ke tiep bang phan tu dau

s->head = p; // cap nhat phan tu dau la phan tu moi them vao

Xóa phần tử ra khỏi ngăn xếp:

void pop(struct List *s)

struct Node *p = s->head;

if (!isEmpty(s))

s->head = p->next;

free(p);

else

Huỳnh Viết Triều Trang 15


Đồ án Cơ sở
printf("danh sach dang rong\n");

3. TỔ CHỨC CẤU TRÚC DỮ LIỆU VÀ THUẬT TOÁN

3.1. Phát biểu bài toán


Viết chương trình bằng ngôn ngữ C thực hiện các công việc sau:

a) Đọc N ( ) phần tử số của danh sách liên kết từ file DAYSO.IN


b) Thực hiện xóa một phần tử trong danh sách này, hiển thị kết quả và lưu kết quả ra
file. RESULT1.OUT.
c) Sau khi thực hiện câu b), chúng ta nhận được một danh sách có M (M=N-1)phần tử

Biết rằng các phần tử này là hệ số của đa thức sau:

Hãy tìm các nghiệm của phương trình bằng phương pháp dây cung

(với sai số ), hiển thị kết quả và lưu kết quả ra file RESULT2.OUT.
Yêu cầu: Sử dụng danh sách liên kết kiểu ngắn xếp để thực hiện các công việc trên.
Dữ liệu đầu vào: file DAYSO.IN
Dữ liệu đầu ra: Kết quả thực hiện được lưu ở 2 file RESULT1.OUT,
RESULT2.OUT.

3.2. Cấu trúc dữ liệu


struct Node
{
float data;
struct Node *next;
};
struct List
{
struct Node *head;

Huỳnh Viết Triều Trang 16


Đồ án Cơ sở
struct Node *tail;
};

3.3. Thuật toán


Thuật toán giải phương trình bậc cao bằng phương pháp dây cung [2]:
a. Ý tưởng Giả sử [a, b] là khoảng nghiệm phương trình f(x)=0. Gọi A, B là 2
điểm trên đồ thị f(x) có hoành độ tương ứng là a, b. Phương trình đường thẳng
qua 2 điểm A(a, f(a)), B(b, f(b)) có dạng:

Dây cung AB cắt trục x tại điểm có toạ độ (x1, 0)


Do đó:

Nếu f(a)*f(x1) < 0, thay b=x1 ta có khoảng nghiệm mới là (a,x1)


Nếu f(b)*f(x1) < 0, thay a=x1 ta có khoảng nghiệm mới là (x1,b)
Tiếp tục áp dụng phương pháp dây cung vào khoảng nghiệm mới ta được giá trị
x2. Lại tiêp tục như thế ta nhận được các giá trị x 3, x4,… càng tiến càng gần với
giá trị nghiệm phương trình.
b) Thuật toán
- Khai báo hàm f(x)
- Nhập a, b
- Tính x = a – (b-a)f(a) / (f(b)-f(a))
- Nếu f(x)*f(a) <0
Lặp b = x
x = a – (b-a)f(a) / (f(b)-f(a))
trong khi |x – b|> ε
Ngược lại
Lặp a = x
x = a – (b-a)f(a) / (f(b)-f(a))
trong khi |x – a|> ε

Huỳnh Viết Triều Trang 17


Đồ án Cơ sở
- Xuất nghiệm: x

4. CHƯƠNG TRÌNH VÀ KẾT QUẢ

4.1. Tổ chức chương trình


#include<stdio.h>
#include<stdlib.h>
#include <math.h>
struct Node{}
struct List{}
void Init(struct List *s)
int isEmpty(struct List *s)
void push(struct List *s, float x)
void pop(struct List *s)
struct Node *search_Node(struct List s, int x)
void xuat(struct List s)
void Doc_file(struct List s[],FILE *f,int n,int m)
void xoaphantu(struct List s[])
void xuat_file(struct List s[],FILE *f )
float pt(struct List s[],FILE *f, float x)
float print_pt(struct List s[],FILE *f)
int giai_pt(struct List s[],FILE *f)

4.2. Kết quả

4.2.1. Giao diện chính của chương trình


Các hình ảnh về giao diện chương trình sau khi chạy. Hình 4 là giao diện của
chương trình khi khởi động chương trình. Hình 5 là giao diện của chương trình
sau khi nhập một phím bất kì. Hình 6 là giao diện của toàn bộ chương trình.

Huỳnh Viết Triều Trang 18


Đồ án Cơ sở

Hình 4: Giao diện của chương trình khi khởi động chương trình.

Hình 5: Giao diện của chương trình sau khi nhập một phím bất kì.

Huỳnh Viết Triều Trang 19


Đồ án Cơ sở

Hình 6: Giao diện của toàn bộ chương trình.

4.2.2. Kết quả thực thi của chương trình

a) Đọc N ( ) phần tử số của danh sách liên kết từ file DAYSO.IN


b) Xóa một phần tử trong danh sách này, hiển thị kết quả và lưu kết quả ra file.
RESULT1.OUT.

c) Tìm các nghiệm của phương trình bằng phương pháp dây cung

(với sai số ), hiển thị kết quả và lưu kết quả ra file RESULT2.OUT.

4.2.3. Nhận xét


4.2.3.1. Về kiến thức:
Đồ án cơ sở đã giúp em hiểu rõ hơn về cách xây dựng một chương trình đọc
dữ liệu từ file, áp dụng các thuật toán được học trước đó, hiểu hơn về các

Huỳnh Viết Triều Trang 20


Đồ án Cơ sở
phương pháp tính toán cho hệ phương trình; đồng thời rèn luyện được sự cẩn
thận tỉ mỉ cũng như sắp xếp ngăn nắp. Mặc dù gặp nhiều khó khăn nhưng nhờ
sự giúp đỡ tận tình, chu đáo của thầy Phạm Công Thắng đã giúp em hoàn
thành đồ án được giao.
4.2.3.1. Về chương trình:
- Ưu điểm:
+ Chương trình có chức năng xóa, tìm kiếm, ... trong danh sách liên kết kiểu
Stack.
+ Sử sụng thuật toán phương pháp dây cung giúp giải phương trình bậc cao
đỡ phức tạp hơn.
- Nhược điểm:
+ Giao diện chính của chương trình chưa đẹp, bắt mắt.
+ Cấu trúc dữ liệu chưa tối ưu.

KẾT LUẬN VÀ HƯỚNG PHÁT TRIỂN

a. Kết luận
- Về kiến thức:
+ Nâng cao tinh thần tự học, tự nghiên cứu.
+ Hiểu hơn về danh sách liên kết kiểu Stack, đọc ghi File.
+ Có thể giải phương trình bậc cao bằng phương pháp dây cung.
- Về chương trình:
+ Sử dụng danh sách liên kết kiểu ngăn xếp để thực hiện các công việc: đọc,
ghi dữ liệu từ file, tìm kiếm, xóa một phần tử trong danh sách.
+ Giao diện chương trình chưa đẹp và bắt mắt.

b. Hướng phát triển


- Khắc phục những nhược điểm còn tồn tại.
- Tiếp tục hoàn thiện chương trình, chỉnh giao diện đẹp hơn.
- Nghiên cứu và phát triển thuật toán có thể tối ưu nhất cho chương trình.

Huỳnh Viết Triều Trang 21


Đồ án Cơ sở

TÀI LIỆU THAM KHẢO

[1] Phan Chí Tùng, Bài giảng Cấu trúc dữ liệu, Khoa CNTT, ĐHBK-ĐHĐN, lưu
hành nội bộ.
[2] Đỗ Thị Tuyết Hoa, Bài giảng Phương pháp tính, Khoa CNTT, ĐHBK-
ĐHĐN, lưu hành nội bộ
[3] Nguyenvanhieu, URL: https://nguyenvanhieu.vn/ngan-xep-stack/, ngày truy
cập: 20/7/2020.
[4] Nguyenvanhieu, URL: https://nguyenvanhieu.vn/mang-2-chieu-trong-c/, ngày
truy cập: 20/7/2020

Huỳnh Viết Triều Trang 22


Đồ án Cơ sở

PHỤ LỤC
Code đồ án:
#include<stdio.h>
#include<stdlib.h>
#include <math.h>

struct Node
{
float data;
struct Node *next;
};

struct List
{
struct Node *head;
struct Node *tail;
};

// khoi tao stack


void Init(struct List *s)
{
s->head = s->tail = NULL;
}

// kiem tra stack co rong khong


int isEmpty(struct List *s)
{
if (s->head == NULL)
return 1;
else

Huỳnh Viết Triều Trang 23


Đồ án Cơ sở
return 0;
}

// tao Node
struct Node *creat_Node(float x)
{
struct Node *p = (struct Node*) malloc( sizeof(struct Node) );

p->data = x;
p->next = NULL;

return p;
}

// Push vao stack


void push(struct List *s, float x)
{
struct Node *p = creat_Node(x);
if (isEmpty(s))
{
s->head = s->tail = p; // neu stack rong thi ta gan p la phan tu dau va cuoi
}
else
{
p->next = s->head; // cho phan tu ke tiep bang phan tu dau
s->head = p; // cap nhat phan tu dau la phan tu moi them vao
}
}

// Pop phan tu ra khoi stack


void pop(struct List *s)

Huỳnh Viết Triều Trang 24


Đồ án Cơ sở
{
struct Node *p = s->head;
if (!isEmpty(s))
{
s->head = p->next;
free(p);
}
else
{
printf("\n danh sach dang rong");
}
}

// tim kiem phan tu trong stack


struct Node *search_Node(struct List s, int x)
{
struct Node *q = s.head;
while (q != NULL)
{
if (q->data == x)
{
return q;
}
else
{
q = q->next;
}
}
return NULL;
}

Huỳnh Viết Triều Trang 25


Đồ án Cơ sở
// Nhap du lieu cho Stack
void xuat(struct List s)
{
struct Node *p = s.head;
if (p==NULL)
{
printf("\n danh sach rong");
return ;
}

while (p != NULL)
{

printf("\t%.2f",p->data);
p = p->next;
}
}

void Doc_file(struct List s[],FILE *f,int n,int m)


{
f=fopen("DAYSO.IN","r");
fscanf(f,"\n%d",&n);
fscanf(f,"\n%d",&m);

int i,j;

for(i=1;i<=n;i++)
{
printf("\t-------------------------------------- Danh sach thu %2d
--------------------------------------\n\n\t",i);
Init(&s[i]);// khoi tao stack

Huỳnh Viết Triều Trang 26


Đồ án Cơ sở
for(j=1;j<=m;j++)
{
struct Node *p;
float x;
fscanf(f,"%f ",&x);
push(&s[i], x);
}
xuat(s[i]);
printf("\n");
}
fclose(f);
}

void xoaphantu(struct List s[])


{
pop(&s[1]);
printf("\n\n\t------------------------------ Danh sach sau khi xoa mot phan tu
-----------------------------\n\n\t");
xuat (s[1]);
printf("\n");
}

void xuat_file(struct List s[],FILE *f )


{
f=fopen("RESULT1.OUT","w");

int i,j;
int n;
for (i=1;i<=1;++i)
{
struct Node *p = s[i].head;

Huỳnh Viết Triều Trang 27


Đồ án Cơ sở
while (p != NULL)
{
fprintf(f,"\t %.2f ",p->data);
p = p->next;
}
fprintf(f,"\t");
printf("\n");
}
fclose(f);
}

float pt(struct List s[],FILE *f, float x)


{
int i=0,j=0;
float pt = 0;
float a[100][100]={{0}};
struct Node* p =s[1].head;
int k,l=0;

while (p!=NULL){
a[i][j]=p->data;
p=p->next;
j++;
}

for (i=0;i<1;++i)
{
for (k=0;k<j;k++)
{
pt += a[i][k]*pow(x,k);

Huỳnh Viết Triều Trang 28


Đồ án Cơ sở

}
}
return pt;

float print_pt(struct List s[],FILE *f)


{
int i=0,j=0;
float a[100][100]={{0}};
struct Node* p =s[1].head;

while (p!=NULL){
a[i][j]=p->data;
p=p->next;
j++;
}
int k,l=0;
printf("\n\t------------------------------------------- Giai pt
------------------------------------------\n\n\t\t");
for (i=0;i<1;++i)
{
printf("%0.1f ", a[0][0]);
printf("+ %.0fx ", a[0][1]);
for (k=2;k<j;k++)
{

printf("+ %.0fx^%d ",a[i][k],k);


}
printf(" = 0");

Huỳnh Viết Triều Trang 29


Đồ án Cơ sở
}
}

int giai_pt(struct List s[],FILE *f)


{
float a,b,ga,gb,dx,x;
float epsi = 0.00001;

printf("\n\t------------------------ Nhap mot phim bat ki de tiep tuc chuong trinh


-----------------------\n");
getch();
pt(s,f,x);
print_pt(s,f);
printf("\n\n\n\t---------------------------- Tim nghiem bang phuong phap day cung
----------------------------");

int k=1,h;
int nghiem;
do
{
printf("\n\n\t\tPhuong trinh co bao nghiem : ");
scanf("%d", &nghiem);

if (nghiem == 0)
{

printf("\n\t\tPhuong trinh vo nghiem\n");


printf("\n\n\t----------------------------------- Ket thuc chuong trinh
------------------------------------\n\n");
}

Huỳnh Viết Triều Trang 30


Đồ án Cơ sở
else
if (nghiem > 0 )
{
do
{
do
{
printf("\n\t\tBan muon tim bao nhieu nghiem : ");
scanf("%d",&h);
}
while(h<0);

if (h == 0)
printf("\n\n\t----------------------------------- Ket thuc chuong trinh
------------------------------------\n\n");
else
if(h<= nghiem)
{
f=fopen("RESULT2.OUT","w");
do
{
do
{
printf("\n\t\tCho gia tri cua a = ");
scanf("%f",&a);
printf("\t\tCho gia tri cua b = ");
scanf("%f",&b);
}
while (pt(s,f,a)*pt(s,f,b) > 0 );

ga=pt(s,f,a);

Huỳnh Viết Triều Trang 31


Đồ án Cơ sở
gb=pt(s,f,b);
dx = ga*(b-a)/(ga-gb);
while( fabs(dx) > epsi)
{
x=a+dx;
ga=pt(s,f,x);
if( (ga*gb) <= 0 )
a=x;
else
b=x;
ga=pt(s,f,a);
gb=pt(s,f,b);
dx = ga*(b-a)/(ga-gb);
}
printf("\t\tNghiem x = %.5f \n ",x);
fprintf(f,"\n %.5f \t ",x);
k=k+1;
}
while(k<=h);
}
}
while(h>nghiem);
}
}
while(nghiem < 0);

fclose(f);
printf("\n\n\t----------------------------------- Ket thuc chuong trinh
------------------------------------\n\n");
}

Huỳnh Viết Triều Trang 32


Đồ án Cơ sở
int main()
{
int n,m;

struct List s[10];

FILE*f;

Doc_file(s,f,n,m);

xoaphantu(s);

xuat_file(s,f);

giai_pt(s,f);
}

Huỳnh Viết Triều Trang 33

You might also like