Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 69 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
69
Dung lượng
0,96 MB
Nội dung
ĐẠI HỌC ĐÀ NẴNG TRƯỜNG ĐẠI HỌC SƯ PHẠM KHOA TIN HỌC KHÓA LUẬN TỐT NGHIỆP Đề tài: CẤU TRÚC DỮ LIỆU CÂY ĐỎ ĐEN VÀ MÔ PHỎNG Giáo viên hướng dẫn Sinh viên thực Lớp : PGS.TSKH Trần Quốc Chiến : Phan Thị Như Ngọc : 08SPT Đà Nẵng - 5/ 2012 LỜI CẢM ƠN Trước trình bày đề tài, em xin bày tỏ lòng biết ơn chân thành đến tất thầy cô khoa Tin học, đặc biệt PGS TSKH Trần Quốc Chiến thời gian qua tận tâm giảng dạy, hướng dẫn tạo điều kiện thuận lợi để em hoàn thành đề tài Em xin thành thật cảm ơn người thân, bạn bè động viên, giúp đỡ thời gian xây dựng đề tài Chân thành cảm ơn!! Sinh viên thực Phan Thị Như Ngọc Ý KIẾN ĐÁNH GIÁ CỦA GIÁO VIÊN HƯỚNG DẪN Đà Nẵng, ngày tháng năm 2012 Giáo viên hướng dẫn PGS-TSKH Trần Quốc Chiến MỤC LỤC LỜI CẢM ƠN Ý KIẾN ĐÁNH GIÁ CỦA GIÁO VIÊN HƯỚNG DẪN MỤC LỤC LỜI MỞ ĐẦU I LÍ DO CHỌN ĐỀ TÀI: II MỤC TIÊU NHIỆM VỤ: III PHƯƠNG PHÁP NGHIÊN CỨU: IV BỐ CỤC CỦA ĐỀ TÀI: CHƯƠNG I: TỔNG QUAN VỀ CẤU TRÚC CÂY 10 I CẤU TRÚC CÂY: 10 ĐỊNH NGHĨA VÀ CÁC KHÁI NIỆM VỀ CÂY: 10 SƠ ĐỒ CẤU TRÚC CÂY: 11 ỨNG DỤNG CẤU TRÚC CÂY: 12 MỘT SỐ VÍ DỤ VỀ ĐỐI TƯỢNG CÁC CẤU TRÚC DẠNG CÂY: 12 4.1 Sơ đồ tổ chức công ty: 12 4.2 Mục lục sách: 13 4.3 Biểu diễn biểu thức số học dạng cây: x + y * (z - t) + u / v 13 NHẬN XÉT: 14 II TÌM HIỂU CÂY NHỊ PHÂN : 14 ĐỊNH NGHĨA : 14 MỘT SỐ DẠNG ĐẶC BIỆT CỦA CÂY NHỊ PHÂN : 14 TÍNH CHẤT : 16 CHƯƠNG II: CÂY NHỊ PHÂN TÌM KIẾM 17 I MỘT SỐ KHÁI NIỆM: 17 II SƠ ĐỒ CÂY NHỊ PHÂN TÌM KIẾM: 17 III CẤU TRÚC DỮ LIỆU: 18 IV CÁC THAO TÁC TRÊN CÂY NHỊ PHÂN TÌM KIẾM: 18 Khởi tạo Binary Search Tree: 18 1.1 Khởi tạo Binary Search Tree: 18 1.2 Tạo Node: 18 1.3 Tạo nhị phân tìm kiếm: 19 Duyệt nhị phân tìm kiếm: 20 2.1 Duyệt theo thứ tự trước (Node - Left - Right): 20 2.2 Duyệt theo thứ tự (Left - Node - Right): 21 2.3 Duyệt theo thứ tự sau (Left - Right - Node): 21 Tìm phần tử x cây: 22 Giải thuật tìm kiếm: 22 Nhận xét: 22 3.1 Tìm theo đệ quy: 24 3.2 Tìm theo khơng đệ quy: 25 3.3 Thêm nút vào Binary Search Tree: 25 3.4 Nhận xét: 27 Hủy phần tử có khóa X: 27 4.1 Trường hợp 1: X nút 27 4.2 Trường hợp 2: X có (bên trái bên phải) 28 4.3 Trường hợp 3: X có đủ hai 29 Hủy toàn nhị phân tìm kiếm: 32 V NHẬN XÉT: 33 CHƯƠNG III: CÂY ĐỎ ĐEN 34 I GIỚI THIỆU: 34 II ĐỊNH NGHĨA: 34 III TÍNH CHẤT: 35 IV THUẬN LỢI KHI SỬ DỤNG: 36 V CẤU TRÚC CÂY ĐỎ ĐEN: 38 Cấu trúc lưu trữ: 38 Khai báo đỏ đen: 38 VI CÁC THUẬT TOÁN CƠ BẢN CỦA BLACK AND RED TREE: 39 Phép quay: 39 Thêm node mới: 39 2.1 Các phép lật màu đường xuống: 41 2.2 Các phép quay chèn node: 42 2.3 Các thao tác khôi phục cây: 49 2.4 Các trường hợp vi phạm chính: 50 2.4.1 Trường hợp 1: 50 2.4.2 Trường hợp 2: 51 2.4.3 Trường hợp 3: 52 2.5 Nhận xét chèn: 53 2.6 Code: 54 Xóa node: 57 3.1 Trường hợp 1: 58 3.2 Trường hợp 2: 58 3.3 Trường hợp 3: 59 3.4 Trường hợp 4: 59 Tìm kiếm: 61 I GIỚI THIỆU NGƠN NGỮ LẬP TRÌNH: 64 Vài nét ngôn ngữ Java: 64 Một số đặc điểm ngôn ngữ Java: 64 Giới thiệu ứng dụng Java vào chương trình đỏ đen: 65 II DEMO CHƯƠNG TRÌNH: 66 KẾT LUẬN 68 TÀI LIỆU THAM KHẢO 69 LỜI MỞ ĐẦU I LÍ DO CHỌN ĐỀ TÀI: Trong khoa học máy tính, cấu trúc liệu cách lưu liệu máy tính cho sử dụng cách hiệu Một cấu trúc liệu thiết kế tốt cho phép thực nhiều phép toán, sử dụng tài nguyên, thời gian xử lý không gian nhớ tốt Chúng ta biết việc tìm kiếm địi hỏi thường xun đời sống ngày xử lý Tin học Vấn đề tìm kiếm xét cách tổng quát, hiểu tìm đối tượng thỏa mãn số địi hỏi đó, tập rộng lớn đối tượng Khi không liên quan đến mục đích xử lý cụ thể khác, tốn tìm kiếm phát biểu độc lập tổng quát sau: “Cho bảng gồm n ghi R1, R2,…, Rn Mỗi ghi Ri (1≤i≤n) tương ứng với khóa ki Hãy tìm ghi có giá trị khóa tương ứng X cho trước” X gọi khóa tìm kiếm Cơng việc tìm kiếm hồn thành có hai tình sau xảy ra: Tìm ghi có giá trị khóa tương ứng X, lúc ta nói phép tìm kiếm thành cơng (successfull) Khơng tìm thấy ghi có giá trị khóa X Phép tìm kiếm khơng thành cơng (unsuccessfull) Sau phép tìm kiếm khơng thỏa có xuất u cầu bổ sung thêm ghi có khóa X vào bảng Giải thuật thể yêu cầu gọi giải thuật “tìm kiếm có bổ sung” Có nhiều phương pháp tìm kiếm thông dụng, liệu nhớ tìm kiếm trong, liệu nhớ ngồi tìm kiếm ngồi Đối với tìm kiếm trong, tìm kiếm nhị phân phương pháp tìm kiếm thơng dụng, chi phí ít, đạt kết tốt Tuy nhiên sử dụng tìm kiếm nhị phân dãy khoá phải xếp rồi, nghĩa thời gian chi phí cho xếp phải kể đến Nếu dãy khố ln biến động lúc chi phí cho xếp lại lên rõ điều bộc lộ nhược điểm phương pháp Để khắc phục nhược điểm vừa nêu tìm kiếm nhị phân đáp ứng yêu cầu tìm kiếm bảng biến động, phương pháp hình thành dựa sở bảng tổ chức dạng nhị phân mà ta gọi nhị phân tìm kiếm Trong đó, đỏ đen cấu trúc liệu hay, với tìm kiếm nhị phân cấu trúc liệu có điểm mạnh việc lưu trữ tìm kiếm liệu Song đỏ đen có đặc tính riêng mà nhờ làm bật điểm mạnh Thuật tốn quan trọng cân Trên sở với định hướng thầy giáo hướng dẫn PGS-TSKH Trần Quốc Chiến em chọn đề tài “Cấu trúc liệu đỏ đen mô ” II MỤC TIÊU NHIỆM VỤ: - Đề tài nhằm nghiên cứu lý thuyết đỏ đen, dạng nhị phân tìm kiếm tự cân để thấy điểm mạnh kiểu cấu trúc liệu - Đề tài nhằm khẳng định làm rõ khái niệm, tính chất việc sử dụng cấu trúc liệu đỏ đen vào việc lưu trữ liệu thực tìm kiếm tốn tìm kiếm - Thực nghiên cứu mơ phép tốn chèn, xóa, tìm kiếm đỏ đen, đánh giá chúng so với nhị phân tìm kiếm III PHƯƠNG PHÁP NGHIÊN CỨU: - Tham khảo tài liệu, viết, giáo trình có liên quan đến cấu trúc cây, nhị phân tìm kiếm, đỏ đen, tài liệu mạng - Sử dụng ngôn ngữ lập trình hướng đối tượng…để xây dựng bước mơ thuật toán đỏ đen IV BỐ CỤC CỦA ĐỀ TÀI: LỜI MỞ ĐẦU Báo cáo chia thành chương: Chương I: Tổng quan cấu trúc Chương giới thiệu tổng quan cấu trúc cây, khái niệm tính chất cây, nhị phân Chương II: Cây nhị phân tìm kiếm Chương trình bày tìm kiếm nhị phân bao gồm: định nghĩa, giải thuật tìm kiếm, thao tác chèn xóa nhị phân tìm kiếm, đánh giá thời gian, độ phức tạp thao tác Chương III: Cây đỏ đen Chương trình bày khái niệm, tính chất đỏ đen, phép tốn chèn, xóa, tìm kiếm đỏ đen, đánh giá thời gian, độ phức tạp phép toán này, thuận lợi sử dụng cấu trúc đỏ đen Chương IV: Cài đặt chương trình KẾT LUẬN TÀI LIỆU THAM KHẢO CHƯƠNG I: TỔNG QUAN VỀ CẤU TRÚC CÂY I CẤU TRÚC CÂY: ĐỊNH NGHĨA VÀ CÁC KHÁI NIỆM VỀ CÂY: - Cây đồ thị liên thơng khơng có chu trình đơn - Cây dùng từ năm 1857, nhà toán học Anh tên Arthur Cayley dùng để xác định dạng khác hợp chất hóa học Từ đó, dùng để giải nhiều tốn nhiều lĩnh vực khác hay sử dụng Tin học - Cây tập hợp T phần tử (gọi nút cây) có nút đặc biệt gọi nút gốc (root), nút lại chia thành tập rời T1, T2, …, Tn theo quan hệ phân cấp Ti gọi Mỗi nút cấp i quản lý số nút cấp i +1 Quan hệ người ta gọi quan hệ cha - - Gốc đỉnh đặc biệt, thông thường đỉnh Mức đỉnh độ dài đường từ gốc đến đỉnh Chiều cao số mức lớn nút có - Mức (gốc (T))=0 * Ví dụ : Đồ thị sau V V V V V V V + Ta chọn V1 gốc có mức V2, V3 đỉnh mức 1, đỉnhV4, V5, V6, V7 có mức 2, chiều cao - Rừng đồ thị mà thành phần liên thông Return; Else insertCase(n); } //TH3: Cả node cha P node bác U đỏ Void insertCase3(Node* n) //Node bác U khác rỗng đỏ { If (Uncle(n) !=NULL && Uncle(n)→color = =RED) { n→parent→color=BLACK; Uncle(n)→color = BLACK; Grandparent (n)→color = RED; InsertCase1 (Grandparent (n)); } Else InsertCase4 (n); } //TH4: Node cha P đỏ, node bác U đen Void InsertCase4 (Node* n) //node N phải P, P trái node ông G { If (n = = n→father→right && n→father= = Grandparent (n)→left) { RotateLeft (n→father); n= n→left; } //node N trái P, P phải node ông G Else if(n= =n→father→left && n→father= =Grandfather(n) →right) { RotateRight (n→father); n = n→right; } InsertCase5(n); } //TH5: node cha P đỏ, node bác U đen, Void insertCase5 (Node* n) { n→father→color = BLACK; Grandparent (n)→color = RED; If (n = = n→father→left && n→father = = Grandparent (n) →left) // node N trái P, P trái node ông G RotateRight (Grandparent (n)); Else //node N phải P, P phải node ơng G RotateLeft (Grandparent (n)); } Xóa node: - Ta tìm vị trí nút cần xóa nhị phân - Nếu nút cần xóa có ta tìm phần tử mạng (có thể nút lớn bên trái nút nhỏ bên phải) Phần tử mạng khơng có có - Do ta cần xét chung trường hợp nút bị xóa khơng có có Gọi nút y Nếu nút bị xóa y màu đỏ chắn cha nút phải nút đen Việc xóa y thực bình thường Trường hợp phức tạp xảy nút bị xóa y màu đen Ta thực thay nó nút NIL (nếu khơng có con) Việc làm giảm chiều cao đen nhánh chứa y Nếu y gốc ta phải thực khơi phục lại thuộc tính đỏ đen - Gọi nút thay cho y N - Nếu N màu đỏ cần đổi màu N thành đen thuộc tính đỏ đen phục hồi - Nếu N màu đen khơng thể đổi màu N Phải thực cách khác Có trường hợp xảy ra: 1) Nút anh em với N màu đỏ 2) Nút anh em với N màu đen nút có đen 3) Nút anh em với N màu đen có màu đỏ cháu nội P, màu đen 4) Nút anh em với N màu đen có màu đỏ cháu ngoại P 3.1 Trường hợp 1: Nút anh em với N màu đỏ - Ta thực đổi màu nút S P, xoay nút cha N để chuyển trường hợp khác với SL anh em N Đổi màu S P SR SL N Đổi màu S Xoay P SL SR SL SR N 3.2 Trường hợp 2: Nút anh em với N màu đen nút có đen - Ta thực đổi màu nút S, chiều cao đen nhánh bên phải P bên trái P Nhưng P chiều cao đen lại giảm Coi P N xét lại từ đầu Đổi màu P N S S L P N S SR S L SR 3.3 Trường hợp 3: Nút anh em với N màu đen có màu đỏ cháu nội P, màu đen - Ta thực đổi màu quay nút S để chuyển trường hợp P P Xoay SL N SR S SL N S SR SR SL 3.4 Trường hợp 4: Nút anh em với N màu đen có màu đỏ cháu ngoại P - Đổi màu S thành màu P, màu P thành đen, màu S đỏ thành đen xoay P sang trái Xoay S SR P N S SL SL SR SL P S R R N Nhận xét: Trong tìm kiếm nhị phân thấy phép loại bỏ phức tạp so với phép thêm vào Trong đỏ đen phép loại bỏ phức tạp nhiều so với phép thêm vào yêu cầu đảm bảo qui tắc đỏ đen + Nếu xóa nút đỏ chiều cao đen khơng đổi + Nếu xóa nút đen phải cân lại Code: void Delete(RBTree &t, int k) { //Tìm nút z cần xố if (isEmpty(t)) return; pNode z = t.root; while (z!=Null && z→key !=k){ if (z→key > k) z= z→left; else z= z→right; } if (z= =Null) return ; //Khơng tìm thấy Xác định nút y nút cần thực xoá If (z→left = = Null !! z→right = = Null) y = z; //z khơng đủ => xố else //y có y = SearchStandFor(z); //Tiến hành xoá y pNode x; // x nút y if (y→left != Null) x = y→left; else x = y→right; //cha x cha y //Nếu x Null không báo lỗi x→parent = y→parent; if (y→parent = = Null) //y gốc t.root = x; else if (y→parent→left= =y) y→parent→left = x; else y→parent→right = x; //Kiểm tra cân if (y != z) // y phần tử mạng z→key = y→key; if (y→color = =BLACK) FIXUP(t,x); // cân lại //Xoá y y→left = y→right = y→parent = Null; Delete y; } Tìm kiếm: - Khi xây dựng cấu trúc đỏ đen thao tác tìm kiếm cấu trúc liệu thực nhị phân tìm kiếm - Khi tìm kiếm khóa X có hay khơng ta thực sau: So sánh X với khóa gốc bốn tình sau xuất hiện: 1) Khơng có gốc (cây rỗng): X khơng có cây, phép tìm kiếm khơng thỏa 2) X trùng với khóa gốc: Phép tìm kiếm thỏa 3) X nhỏ khóa gốc: Tìm kiếm thực tiếp tục cách xét trái gốc với cách làm tương tự 4) X lớn khóa gốc: Tìm kiếm thực tiếp tục cách xét phải gốc với cách làm tương tự Ví dụ: Với cấu trúc đỏ đen xây dựng từ hình bên dưới, ta cần tìm xem giá trị khóa có hay khơng 1 5 Quá trình tìm kiếm sau: + So sánh với giá trị nút gốc: < 11, chuyển sang trái + Thực so sánh > 2, chuyển sang phải + Thực so sánh < 7, chuyển sang trái + Cuối = 5, tìm kiếm thỏa Như vậy, thời gian tìm kiếm sử dụng cấu trúc đỏ đen O(log2n) Code: Int searchNode(NodeRB *root,int x) //Trả 0: khơng tìm thấy; 1: tìm thấy { if (root= =NULL) return 0; if (root→key= =x) return 1; if (root→key>x) return searchNode (root→left, x); else return searchNode (root→right, x); } CHƯƠNG IV: CÀI ĐẶT CHƯƠNG TRÌNH I GIỚI THIỆU NGƠN NGỮ LẬP TRÌNH: Vài nét ngôn ngữ Java: - Java ngơn ngữ lập trình Sun Microsystems giới thiệu vào tháng năm 1995 Từ trở thành cơng cụ lập trình lập trình viên chuyên nghiệp Java xây dựng tảng C C++ Do đó, sử dụng cú pháp C đặt trưng hướng đối tượng C++ - Ban đầu Java thiết kế để làm ngơn ngữ viết chương trình cho sản phẩm điện tử dân dụng đầu video, tivi, điện thoại,….Tuy nhiên với mạnh mẽ Java khiến tiếng đến mức vượt tưởng tượng nhà thiết kế - Java đặt biệt hướng đối tượng mạnh Internet - Ban đầu ngôn ngữ gọi Oak sồi mọc phía sau văn phịng nhà thiết kế ơng Jame Gosling, sau ơng thấy có ngơn ngữ lập trình Oak rồi, nhóm thiết kế đổi tên, “Java” tên chọn, Java tên quán cafe mà nhóm thiết kế Java hay đến uống - Java ngơn ngữ lập trình hướng đối tượng, khơng thể dùng Java để viết chương trình hướng chức Java giải hầu hết cơng việc mà ngơn ngữ khác làm - Java ngôn ngữ vừa biên dịch vừa thông dịch Nó ngơn ngữ lập trình hướng đối tượng độc lập thiết bị, không phụ thuộc vào hệ điều hành Một số đặc điểm ngôn ngữ Java: - Đơn giản: + Quen thuộc với lập trình viên C + Loại bỏ đặc điểm phức tạp, dễ gây nhầm lẫn C++ nạp chồng toán tử, thao tác trỏ, đa kế thừa… - Độc lập với môi trường: Java thiết kế để hỗ trợ ứng dụng mạng chạy máy ảo Java - Hướng đối tượng: + Bao bọc liệu + Đa hình + Kế thừa + Liên kết động - Phân tán: Java hỗ trợ đầy đủ mơ hình tính tốn phân tán: mơ hình Client/server, gọi thủ tục từ xa… - Mạnh mẽ: + Java ngôn ngữ yêu cầu chặt chẽ kiểu liệu, việc ép kiểu tự động bừa bãi C, C++ hạn chế Java, điều làm chương trình rõ ràng, sáng sủa, lỗi + Java kiểm tra lúc biên dịch thời gian biên dịch Java loại bỏ số loại lỗi lập trình định - An tồn: + Java cung cấp mơi trường thực thi có kiếm tra chặt chẽ + Cơ chế kiểm tra an ninh hệ thống đa tầng - Khả chuyển: Khả triển khai ứng dụng Java nhiều môi trường khác - Biên dịch - Thông dịch: + Mã nguồn Java biên dịch thành mã ByteCode trước chạy máy ảo Java trình thơng dịch + The Virtual Machine (Java interpreter) cung cấp tập hợp hàm chức chuẩn hóa cho mơi trường - Đa luồng: Tạo khả đáp ứng tương tác kịp thời ứng dụng Giới thiệu ứng dụng Java vào chương trình đỏ đen: Ứng dụng Applets: Applet chương trình Java tạo để sử dụng Internet thơng qua trình duyệt hỗ trợ Java IE Applet nhúng bên trang web Khi trang web hiển thị trình duyệt, Applet tải thực thi trình duyệt II DEMO CHƯƠNG TRÌNH: - Giao diện đỏ đen gồm có: + Textbox : Điền liệu cho nút + Insert: Chèn nút + Delete: Xóa nút + Search: Tìm kiếm + Nextstep: Nút thực bước để có đỏ đen + Reset: Thiết lập lại Đây giao diện chương trình đỏ đen Đây ví dụ đỏ đen KẾT LUẬN Giống nhị phân tìm kiếm thơng thường, đỏ đen cho phép việc tìm kiếm, chèn xóa thời gian O(log2n) Thời gian tìm kiếm gần hai loại cây, đặc điểm đỏ đen khơng sử dụng q trình tìm kiếm Điều bất lợi việc lưu trữ cần cho node tăng chút để điều tiết màu đỏ - đen (một biến boolean) Thời gian chèn xóa tăng dần số việc phải thực thi phép lật màu quay đường xuống điểm chèn Trung bình phép chèn cần khoảng chừng phép quay Do đó, chèn hày cịn chiếm O(log2n) thời gian, lại chậm phép chèn nhị phân thơng thường Bởi hầu hết ứng dụng, có nhiều thao tác tìm kiếm chèn xóa, có lẽ khơng có nhiều bất lợi thời gian dùng đỏ đen thay nhị phân thơng thuờng Dĩ nhiên, điều thuận lợi đỏ đen, liệu xếp không làm giảm hiệu suất O(n) Một trợ ngại đỏ đen việc cài đặt phép toán phức tạp so với nhị phân tìm kiếm TÀI LIỆU THAM KHẢO [1] Trần Quốc Chiến: Giáo trình Lý thuyết đồ thị [2] Đỗ Xuân Lôi: Cấu trúc liệu giải thuật - NXB ĐHQG Hà Nội [3] R.Sedgevick - Algorithms, Addison - Wesley, 1990 [4] Đinh Mạnh Tường: Cấu trúc liệu giải thuật [5] Chu Đức Khánh: Lý thuyết đồ thị, Nxb ĐHQG Tp Hồ Chí Minh, 2002 [6] Các trang web tham khảo: - http://www.cs.auckland.ac.nz/software/AlgAnim/red_black.html - http://www.cs.waikato.ac.nz/Teaching/COMP317B/Week_3/Redblack_tree.html http://vi.wikipedia.org/wiki/C%C3%A2y_%C4%91%E1%BB%8F_%C4%9 1en - http://projectviet.com/Project/Details/17 ... CHƯƠNG I: TỔNG QUAN VỀ CẤU TRÚC CÂY 10 I CẤU TRÚC CÂY: 10 ĐỊNH NGHĨA VÀ CÁC KHÁI NIỆM VỀ CÂY: 10 SƠ ĐỒ CẤU TRÚC CÂY: 11 ỨNG DỤNG CẤU TRÚC CÂY: 12 MỘT... trị ? ?đỏ? ?? ? ?đen? ?? Ngoài ra: Một nút đỏ đen Gốc đen Tất đen Cả hai nút đỏ đen (và suy nút đỏ có nút cha đen) Tất đường từ nút chứa số nút đen - Tính chất cịn gọi tính chất “cân đen? ?? Số nút đen đường... Chiến em chọn đề tài ? ?Cấu trúc liệu đỏ đen mô ” II MỤC TIÊU NHIỆM VỤ: - Đề tài nhằm nghiên cứu lý thuyết đỏ đen, dạng nhị phân tìm kiếm tự cân để thấy điểm mạnh kiểu cấu trúc liệu - Đề tài nhằm