Khái niệm về cây Cây là một số tập hợp các phần tử gọi là nút nods trong đó có một nútđược phần biệt là nút gốc root.. Duyệt trung tự inorder,Duyệt hậu tự posrder Có thể định nghĩa cây p
Trang 1TRƯỜNG ĐẠI HỌC VINH
KHOA CÔNG NGHỆ THÔNG TIN
Trang 2TRƯỜNG ĐẠI HỌC VINH
KHOA CÔNG NGHỆ THÔNG TIN
-ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC
ĐỀ TÀI
TÌM HIỂU VÀ CÀI ĐẶT CÂY GIA PHẢ
Sinh viên thực hiện: Bouavan Phanthanit
Mã sinh viên: 0851073260 Lớp: 49K Công nghệ Thông Tin
Giáo viên hướng dẫn: TS Nguyễn Trung Hòa
Nghệ An, tháng 12 năm 2012
Trang 3MỤC LỤC
MỞ ĐẦU 2
CHƯƠNG 1 CÂY 4
1.1 Khái niệm về cây 4
1.2 Biểu diễn cây 6
1.2.1 Cài đặt bằng mảng 6
1.2.2 Cài bằng mảng các danh sách kế 7
1.2.3 Cài bằng danh sách liên kết 7
1.3 Các phép toán cơ bản trên cây 8
1.3.1 Phép tìm cha 8
1.3.2 Phép tìm con trưởng 8
1.3.3 Phép tìm em kế 8
1.4 Phép Duyệt cây 8
1.4.1 Duyệt tiền thứ tự 10
1.4.2 Duyệt trung thứ tự 10
1.4.3 Duyệt hâu thứ tự 10
2 CHƯƠNG 2 CÂY GIA PHẢ 12
2.1 Mô tả bài toán và chọn cấu trúc dữ liệu 12
2.1.1 Đặt bài toán 12
2.1.2 Cấu trúc của một phần tử 13
2.1.3 Cấu trúc của cây gồm 13
2.2 Tạo cây gia phả 13
2.2.1 Tạo cây 14
2.3 Các phép toán cơ bản 15
2.3.1 Việc tìm cha của nút i đơn giản chỉ là DataTr[i].Parent 15
2.3.2 Hàm xác định con trưởng của một nút 15
2.3.3 Hàm xác định em kề của một nút 16
2.4 Duyệt cây 16
2.4.1 Duyệt tiền thứ tự từ gốc cây con n 16
2.4.2 Duyệt trung thứ tự 16
2.4.3 Duyệt hậu thứ tự 17
2.5 Quản lý cây gia phả 18
2.5.1 Tìm kiếm 18
2.5.2 Bổ sung 18
2.5.3 Ghi vào tệp 19
2.6 Một ví dụ về cây gia phả đã được cài đặt 20
2.6.1 Cây gia phả của dòng họ Phathanit 20
2.6.2 Mảng/tệp lưu trữ cây gia phả của dòng họ Phanthanit 20
KẾT LUẬN 22
TÀI LIỆU THAM KHẢO 22
PHỤ LỤC: MÃ CỦA CHƯƠNG TRÌNH 23
Trang 5dữ liệu người ta tạo thành các khối, mỗi khối là một bản ghi gồm các thông tin
được chia thành hai phần: phần dữ liệu và phần quan hệ, trong đó
Phần dữ liệu có thể có một hay nhiều trường dữ liệu, Phần quan hệ có thể chứa một hay nhiều con trỏ trỏ đến các khối
khác có quan hệ với khối đó
Danh sách liên kết
Khi tìm hiểu về Cây, là một kiểu dữ liệu trừu tượng, một câu hỏi đặt ra là
sử dụng cấu trúc dữ liệu cụ thể nào để thể hiện nó
Một ví dụ điển hình về cây là Cây gia phả, tuy nhiên nó được cài đặt nhưthế nào? Dùng cấu trúc cụ thể gì là một vấn đề khó đối với em Vì vậy em chọn
đề tài Tìm hiểu và cài đặt cây gia phả
Đồ án được trình bày trong 2 chương
Chương 1 trình bày tóm tắt các kiến thức về cây, gồm khái niệm về cây,các phép toán cơ bản trên cây, các phép duyệt cây, các phương pháp biểu diễncây
Trang 6Chương 2 trình bày bài toán tạo cây gia phả, gồm yếu cầu của bài toán,các cấu trúc dữ liệu và các giải thuật tạo cây, duyệt cây, bổ sung và lưu trữ cây.
Có kèm theo một ví dụ minh họa
Đồ án đã được thực hiện tại Trường Đại học Vinh dưới sự hướng dẫn của
TS Nguyến Trung Hòa
Nhân dịp này em xin tỏ lòng biết ơn đến Thầy giáo Nguyến Trung Hòacùng các Thầy, Cô giáo trong Khoa CNTT và các bạn đã tận tình giúp đỡ emtrong suốt thời gian học tập tại Trường Đại học Vinh Nơi đây sẽ để lại trong emnhững kỷ niệm không bao giờ phai
Vì thời gian có hạn và nhiều khó khăn trong khi thơcj hiện đồ án nên đồ
án không tránh khỏi thiếu sót, mong được sự góp ý của các Thầy, Cô và các bạn
Em xin cám ơn
Nghệ An, tháng 12 năm 2012
Người thực hiện
Bouavan Phanthanit
Trang 7CHƯƠNG 1 CÂY
1.1 Khái niệm về cây
Cây là một số tập hợp các phần tử gọi là nút (nods) trong đó có một nútđược phần biệt là nút gốc (root) Trên tập hợp các nút này có một quan hệ, gọi làmối quan hệ cha-con (parenthood), xác định hệ thống cấu trúc trên các nút Mỗinút,trừ nút gốc,có duy nhất một nút cha Một nút có thế có nhiều nút con hoặckhông có nút con nao Mỗi nút biểu diễn một phần tử trong tập hợp đang xét và
nó có thể có một kiểu náo đó bất kỳ,thường ta biểu diễn nút bằng một kí mộtchuỗi hoặc một chuỗi hoặc một số ghi trong vòng tròn Mối quan hệ cha conđược biểu diễn theo qui ước nút cha ở dòng trên nút con ở dòng dưới và đượcnối bởi một đoạn thẳng
Có thế định nghĩa cây một cách đệ qui như sau
Một nút đơn độc là một cây Nút này cũng chính là nút gốc của cây
Giá sử ta có n là một nút đơn độc và k cây T1,…,Tk với các nút gốctượng ứng là n1,…,nk thì có thể xây dựng một cây mới bằng cách chonút n là cha của các nút n1,…nk Cây mới này có nút gốc là nút n vàcây T1,…,Tk được gọi các cây con
Tập rỗng cũng được coi là một cây và gọi là cây rỗng kí hiệu
2.1.2 2.1.1
Trang 8Nút gốc là sách, nó có ba cây con có gốc là c1,c2,c3 Cây con thứ 3 cógốc c3 là một nút đơn độc trong khi đó hai cây con kia (gốc c1 và c2) có các nútcon.
Số các con của một nút gọi là cấp (degree) của nút đo Ví dụ cấp của nútc1 là 2 và của nút c2 là 3
Nút có cấp bằng không gọi là nút Lá (leaf) hay nút đơn độc, nút tận cùng
Ví dụ đường đi từ nút Sách đến nút 2.1 là (sách, c2, 2.1) và độ dài đường
đi là 2
Nếu thứ tự các cây con (hay các nút con) của một nút được coi trong thìcây đang xét là cây có thứ tự (ordered tree), ngược lại là cây không có thứ tự(unordered tree) Thường là thứ tự được qui ước từ trái sang phải Như vậy, nếu
kế thứ tự thì hai cây sau là khác nhau:
Trang 91.2 Biểu diễn cây
1.2.1 Cài đặt bằng mảng
Cho cây T, ta có thế dùng một mảng A một chiều để lưu trữ cây bằngcách cho mỗi phần tử của mảng, ngoài việc chứa nội dung dữ liệu còn chứathêm thông tin (địa chỉ) về cha của nó Đặc biệt, nút gốc A[0] chứa thông tin vềcha của nó là -1
A
B C
Trang 101.2.3 Cài bằng danh sách liên kết
Mỗi Node trong cây gồm có n+1 trường trong đó n là bậc của cây, là sốtrường liên kết của cây, và 1 trường Info để chứa dữ liệu Ta có thể mô phỏngcây trên như sau: (* biểu diễn Null)
* * *
* *
*
*
* 4
* 1
* 2
*
*
*
1 0
* 3
5
*
*
* 6
*
*
* 9
*
*
*
Trang 111.3 Các phép toán cơ bản trên cây
1.3.1 Phép tìm cha
Phép tìm cha của mỗi đỉnh x là việc thực hiện hàm parent(x) trả về địa
chỉ là địa chỉ của đỉnh cha của x Trường hợp x là gốc hàm có thể trả về Null
1.3.2 Phép tìm con trưởng
Tìm con bên trái ngoài (con trưởng) của mỗi định Hàm EldestChild(x)
cho ta con trưởng của đỉnh x Trong trường hợp x là lá (x không có con) thìEldestChild (x) = Null
1.3.3 Phép tìm em kế
Hàm Nextsibling (x) xác định em liền kế của đỉnh x Trong trường hợp x
không có em liền kế tức x là con ngoài cùng bên phải của một đỉnh nào đó) thìNextsibling (x) = Null
Ví dụ: Giả sử T là cây đã cho trong hình bên:
Parent (A)= Null
B
Trang 12Danh sách liệt kê các nút (tên nút hoắc giá trị chứa bên trong nút) theo thứ
tự đi qua goi là danh sách duyệt cây
Có 3 cách duyệt cây quan trong
Duyệt tiền tự (preorder)
Duyệt trung tự (inorder),Duyệt hậu tự (posrder)
Có thể định nghĩa cây phép duyệt cây tổng quát (xem hình bên dưới) mộtcách đệ qui như sau:
Ngược lại: giả sử cây T có nút gốc là T và có các cây con là T1,…,Tn thì:
Kết quả duyệt tiền tự của cây T là liệt kê nút T, kế tiếp là kết quả duyệttiền tự của các cây T1,T2,…,Tn theo thứ tự đó
…
Trang 13 Kết quả duyệt trung tự của cây T là kết quả duyệt trung thứ tự của cây T1,
kế tiếp là nút T, đến kết quả duyệt trung tự của các cây T2,…,Tn theo thứ
Duyệt cây con thứ nhất theo tiền thứ tự
Duyệt các cây con còn lại theo tiền thứ tự
Trong cây bên, thứ tự các đỉnh được duyệt theo tiền thứ tự là
Duyệt các cây con còn lại theo trung thứ tự
Trong cây bên, thứ tự các đỉnh được duyệt theo trong thứ tư là
B
Trang 14 Duyệt cây con thứ nhất theo hậu thứ tự
Duyệt các cây con còn lại theo hậu thứ tự
Thăm gốc
Trong cây bên, thư tự các đỉnh được duyệt theo hậu thứ tự là
D,E,B,A,C,F,G,H
Trang 152 CHƯƠNG 2 CÂY GIA PHẢ
Gia phả của một họ tộc có thể hiểu như một cây, xuất phát từ gốc là ông
tổ của họ tộc Quản lý các thành viên trong họ tộc bẳng cây gia phả sẽ cho tathẫy được mối quan hệ giữa các thành viên trong họ tộc Việc duyệt cây theophép duyệt Tiền thứ tự cho ta thấy được vai trò của cha và con trưởng trong bộtộc Có nhiều cách để cài đặt cây như đã trình bày trong chương 1 Tuy nhiêntrong chương này em chọn phương án cài đặt bằng danh sách các phần tử trong
đó mỗi phần tử chứa thông tin về cha của nó
2.1 Mô tả bài toán và chọn cấu trúc dữ liệu
2.1.1 Đặt bài toán
Trong phương án cài đặt cây gia phả ở chương này ta sẽ chọn cách cài đặtcây bới cách biểu diễn nói trong mục 1.2.1, nghĩa là cây được cài đặt bẳng mảngsao cho mỗi phần tử của cây chứa thông tin về địa chỉ của cha của nó
Bài toán được đặt ra là tạo một cây gia phả trong đó mỗi phần tử chứathông tin về cha của nó Chương trình cần phải bao gồm các chức năng sau:
Ghi cây vào đĩa
Bổ sung phần tử mới vào cây;
Tìm kiếm
Theo tên của một phần tử trong cây,
Trang 16 Theo tên cha của một phần tử có tên cho trước.
2.1.2 Cấu trúc của một phần tử
Thông tin về dữ liệu:
Họ và tênNăm sinh
Thông tin về quan hệ
Mã địa chỉ (tường minh) của cha
Nguyễn Đức C 2005
Nguyễn Văn D 2010
Nguyễn Thị Hà 2012
Nguyễn Thị Hiền 2016
Nguyễn Thị Yền 2017
Nguyễn Thị Ngân 2019
Trang 17Tree *MakeNull_Tree (Tree *T)
scanf("%d",&(T->DataTr[i].Parent));}
printf("Nhap ten cua nut %d: ",i);
fflush(stdin); gets(T->DataTr[i].Name);printf("Nhap nam sinh cua nut %d: ",i);scanf("%d",&(T->DataTr[i].DateBirth));}
}
Nhập cây từ tệp
Trang 18Phần tử đầu tiên của tệp là một số nguyên, là số các phần tử của cây đượclưu trữ Tiếp theo đó là các phần tử của cây, có kiểu là kiểu DataType
2.3.1 Việc tìm cha của nút i đơn giản chỉ là DataTr[i].Parent
2.3.2 Hàm xác định con trưởng của một nút
Con trưởng của nút n là phần tử đầu tiên sau n, có cha là n Do đó ta sẽ
duyệt mảng từ phần tử thứ i=n+1 cho đến khi tìm được hoặc đến hết mảng (khôngcó)
int EldestChild(int n,Tree *T)
Trang 19else return NIL;
}
2.3.3 Hàm xác định em kề của một nút
Em kề của nút n là n+1 nếu n+1 có cùng cha với n, hoặc là không có
int NextSibling(int n,Tree *T)
2.4.1 Duyệt tiền thứ tự từ gốc cây con n
Thăm gốc n (in thông tin của n)
Tìm con trưởng i của n
Khi i khác NIL thực hiện
Duyệt tiền thứ tự cây con i
i=NextSibling(i,T);
}}
2.4.2 Duyệt trung thứ tự
Tìm con trưởng i của n
Trang 20 Nếu i khác NIL, duyệt trung thứ tự cây con i
Thăm gốc n (in thông tin của n)
i = em kề của i
Khi i khác NIL thực hiện
Duyệt trung thứ tự cây con i
i=NextSibling(i,T);
}}
2.4.3 Duyệt hậu thứ tự
Tìm con trưởng i của n
Khi i khác NIL thực hiện
Duyệt hậu thứ tự cây con i
i = em kề của i
Thăm gốc n (in thông tin của n)
void PostOrder(int n,Tree *T)
{ int i;
i=EldestChild(n,T);
while (i!=NIL){ PostOrder(i,T);
i=NextSibling(i,T);
Trang 21}printf("%25s ",Label_Node(n,T).Name);
}
Với các cách duyệt này, ta sẽ liệt kê được một danh các thành viên trong
họ tộc theo thứ tự ưu tiên từ “nhánh trưởng” đến các “nhánh thứ”, trong khi đóvai trò của gốc được thay đổi qua các kiểu phép duyệt
2.5 Quản lý cây gia phả
2.5.1 Tìm kiếm
Có hai bài toán tìm kiếm sẽ được quan tâm trong bài này
Thứ nhất, tìm tên cha của một phần tử có tên cho trước (biết (tên) con, tìm (tên) cha)
o Xác định chỉ số n của tên con
o Xác định chỉ số i của cha là Parent(n)
o Tên cha của n là họ tên của i
Thứ hai, tìm (tên) các con của một phần tử cha (có tên) cho trước (biết (tên) cha, tìm (tên) con)
o Xác định chỉ số n của tên cha
o i=n+1
o Khi chỉ số (ID) cha của i bé hơn n và i<Maxnode thực hiện tăng i
o Khi chỉ số cha của i=n thực hiện
Để bổ sung ta cần biết được vị trí (địa chỉ) của nút mới
Trang 22Vị trí của nút mới là ở sau con cuối cùng hiện thời (con út) của cctrong cây hiện thời (trong trường hợp cc có con) hoặc sẽ là con trưởng của
cc, do đó ta tìm vị trí này bằng cho biến chạy i từ cc+1 cho đến khi chacủa i > cc
Đề có chỗ bổ sung thêm nút vào vị trí thứ i cần chuyển dữ liệu (và thayđổi giá trị của trường Parent nếu cần) của các phần tử từ phần tử thứ i ra sau
Đưa phần tử dữ liệu pt vào nút i
void Bosung1(Tree* T, DataType pt, int cc)
if(>DataTr[j+1].Parent>=i)
T->DataTr[j+1].Parent++;
}T->MaxNode++;
T->DataTr[i]=pt;
T->DataTr[i].Parent=cc;
}
2.5.3 Ghi vào tệp
Tệp lưu trữ cây gia phả là tệp có cấu trúc
Phần tử đầu tiên là số nguyên không âm, chỉ số nút hiện có của cây
Các phần tử tiếp theo tạo thành một danh sách các cá nhân trong giaphả, mỗi phần tử có 3 thuộc tính: Họ tên, năm sinh, ID (chỉ số của cha)
void Writefile(Tree *T)
{ FILE *fp;
int i;
Trang 23DataType pt;
fp=fopen("buav.dat","wt");
if (fp == NULL){ printf("I couldn't open results.dat for appending.\n");
exit(0);
}fprintf(fp,"%d",T->MaxNode);
for(i=0; i<T->MaxNode; i++)
fwrite(&T->DataTr[i],sizeof(pt),1,fp);
fclose(fp);
}
2.6 Một ví dụ về cây gia phả đã được cài đặt
2.6.1 Cây gia phả của dòng họ Phathanit
2.6.2 M
ảng/tệp lưu trữ cây gia phả của dòng họ Phanthanit
0 0 Ông Somsai Phanthanit. 1910 -1
1 0.1 Ông Sompheng Phanthanit 1980 0
Somsai 1910
Saikham
2030 Soukthida2031 Vanpheng2030 Vongsai2032
Somsani t 2033
Vilayphone
2034 Soudjai2036
Trang 242 0.2 Ông Somphone phanthanit 1981 0
Trang 25KẾT LUẬN
Đồ án đã thực hiện được các nhiệm vụ sau
Tìm hiểu về cây và các phép toán cơ bản trên cây, các phương phápbiểu diễn cây, các phép duyệt cây
Sử dụng ngôn ngữ C để thực hiện việc cài đặt chương trình tạo cây giaphả, quản lý bổ sung các thành viên của một họ tộc được thể hiện dướidạng cây và thực hiện các phép duyệt cây
Việc cài đặt, tạo và ghi cây gia phả sẽ giúp cho quản lý gia phả được
rõ ràng, thuận lợi
Các dự kiến công việc sẽ tiếp tục bổ sung:
Trình bày dưới dạng đồ họa cây gia phà đã được quản lý
Thực hiện các công việc tìm kiến và truy xuất thông tin khi có một yêucầu liên quan đến tìm hiều về họ tộc
TÀI LIỆU THAM KHẢO
[1] Đỗ Xuân Lôi, Cấu trúc dữ liệu và giải thuật, NXB ĐH Quốc gia Hà
Nội, 2007
[2] Nguyễn Trung Hòa, Bài giảng cấu trúc dữ liệu và giải thuật, Đại học
Vinh, PPT, 2009
Trang 26int DateBirth; //Luu gia tri cua nut
int Parent; //ID cua Cha cua nut
DataType Label_Node(int n,Tree *T);
int EldestChild(int n,Tree *T);
int NextSibling(int n,Tree *T);
void PreOrder(int n,Tree* T);
void InOrder(int n,Tree* T);
void PostOrder(int n,Tree *T);
void ReadTree(Tree *T);
int Level(int n, Tree* T);
void Bosung(Tree* T, DataType pt, int cc);
void Bosung1(Tree* T, DataType pt, int cc);
//int AdrName(char name[], Tree *T);
//Chuong trinh chinh
Trang 27printf("\n\nCac chuc nang chinh cua chuong trinh: \ n");
printf("1: Tao cay\n");
printf("2: Bo sung them pt là con cua i vao cay\n"); printf("3: Duyet cay\n");
printf("4: Xem cay bang duyet mang\n");
printf("5: Ghi cay vao tep\n");
printf("6: Tim kiem\n");
printf("0: Ket thuc chuong trinh\n");
printf("Chon chuc nang: ");
scanf("%d", &chucnang);
switch(chucnang) { case 1:
{
ReadTree(T);
break;
} case 2:
break;
} case 2:
{ printf("\nNhap du lieu can bo sung");
printf("\nTen cua node: ");
{ printf("\nNhap ID cha cua nut moi: ");
scanf("%d",&i);
break;
} case 2:
Trang 28{ printf("\nNhap ten cha cua nut moi: ");
fflush(stdin); gets(name);
j=0; found=0;
1)&&(found==0))
break;
} }
//if(i>=0&&i<T->MaxNode) Bosung(T,pt,i); if(i>=0&&i<T->MaxNode) Bosung1(T,pt,i); break;
} case 3:
{ printf("\nChon phep duyet (1: PreOrder, 2: InOrder, 3: PosOrder) : ");
scanf("%d",&chon);
switch(chon) { case 1:
{ printf("\nDanh sach duyet tien thu tu cua cay vua nhap la\n");
PreOrder(0,T);
break;
} case 2:
{ printf("\nDanh sach duyet trung thu tu cua cay vua nhap la\n");
InOrder(0,T);
break;
} case 3:
{ printf("\nDanh sach duyet hau thu
tu cua cay vua nhap la\n");
PostOrder(0,T);
break;
} }
break;
} case 4:
{ ViewTree(T);
break;
} case 5:
{ Writefile(T);