950 likes | 1.19k Views
Cây. Các khái niệm và thuật ngữ cơ bản. Các khái niệm và thuật ngữ cơ bản. Các khái niệm và thuật ngữ cơ bản. Định nghĩa cấu trúc cây. một cây T (Tree) là : Một tập các phần tử , gọi là các nút (Node): P 1 , P 2,…, P N Nếu N = 0, cây T gọi là cây rỗng (NULL) Nếu N > 0:
E N D
Cáckháiniệmvàthuậtngữcơbản Định nghĩa cấu trúc cây • mộtcây T (Tree) là: • Mộttậpcácphầntử, gọilàcácnút (Node): P1 , P2,…, PN • Nếu N = 0, cây T gọilàcâyrỗng (NULL) • Nếu N > 0: • TồntạiduynhấtmộtnútPkgọilàgốccủacây • Cácnútcònlạiđượcchiathành m tậpkhônggiaonhau: T1, T2, … , Tm • Mỗi Tilà 1 cây con củacây T
Cáckháiniệmvàthuậtngữcơbản Định nghĩa cấu trúc cây Cây T Nútgốc Cây con T3 a Cây con T4 d c k j g i h e f Cây T rỗng (NULL) b Cây con T2 Cây con T1
Cáckháiniệmvàthuậtngữcơbản Định nghĩa cấu trúc cây Cây T a d k j g i h e c f b Cây con T4 Cây con T1 Cây con T2 Cây con T3
Cáckháiniệmvàthuậtngữcơbản Định nghĩa cấu trúc cây • Cáctínhchấtcủacây: • Nútgốckhôngcónút cha • Mỗinútkhácchỉcómộtnút cha • Mỗinútcóthểcónhiềunút con • khôngcóchutrình
Cáckháiniệmvàthuậtngữcơbản Các thuật ngữ liên quan • Nút (Node) làmộtphầntửtrongcây. Mỗinútcóthểchứa 1 dữliệubấtkỳ. • Nhánh (Branch): làđoạnnốigiữa 2 nút • Nút cha (Parent Node) • Nút con (Child Node) • Nútanhem (Sibling Node): lànhữngnútcócùngnút cha • Bậccủamộtnútpilàsốnút con củanút pi
Cáckháiniệmvàthuậtngữcơbản Các thuật ngữ liên quan • Nútgốc (Root Node): lànútkhôngcónút cha • Nútlá (Leaf Node): lànútkhôngcónút con hay nútcóbậc = 0 • Nútnội (Internal Node): lànútcónút cha vàcónút con • Bậccủacây: làbậclớnnhấtcủacácnúttrongcây • Bậccủacây T = max { bậcpi / piЄ T} • đườngđi(path) giữanútpiđếnnútpj: làdảycácnútliêntiếptừ piđếnpjsaochogiữahainútkềnhauđềucónhánh.
Cáckháiniệmvàthuậtngữcơbản Các thuật ngữ liên quan • Mức (level) • Mức (p) = 1 nếu p = root • Mức (p) = 1 + mức ( cha (p)) nếu p != root • Chiềucaocủacây (height - hT): làđườngđidàinhấttừnútgốcđếnnútlá (hay làmứclớnnhấtcủanútlátrongcây) hT = max { Path(root, pi) / pilànútláЄ T}
Cáckháiniệmvàthuậtngữcơbản Các thuật ngữ liên quan h = 4
Cáckháiniệmvàthuậtngữcơbản Các thuật ngữ liên quan Level 1 -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- -- A Branch AF Level 2 --- --- --- --- --- --- --- --- --- B --- --- -- --- --- --- --- Branch FI E F Level 3 -- --- --- --- --- --- --- C D -- -- --- --- -- --- --- --- --- - G H I Parents: A, B, F Children: B, E, F, C, D, G, H, I Siblings: {B, E, F} ; {C, D} ; {G, H, I} Leaves: E, C, D, G, H, I Internal Nodes: B, F
Câynhịphân Lưu trữ cây • Có 2 cách tổ chức cây nhị phân: • Lưu trữ bằng mảng • Lưu trữ bằng con trỏ cấu trúc
Câynhịphân Cách lưu trữ cây, sử dụng mảng struct NODE { DataType Data; int left; // chỉ số nút con trái int right; // chỉ số nút con phải }; NODE TREE[n]; // cây nhị phân có n nút
Câynhịphân Cách lưu trữ cây, sử dụng con trỏ BIN_TREE pRoot Count Data Data Data pLeft pLeft pLeft pRight pRight pRight NODE . . . . . . . . . . . . . . . .
Câynhịphân Cách lưu trữ cây, sử dụng con trỏ struct NODE { DataType Data; NODE *pLeft; // con trỏ đến nút con trái NODE *pRight;// con trỏ đến nút con phải }; struct TREE { int Count; // số nút trong cây NODE *pRoot; //con trỏ đến nút gốc };
Duyệt gốc trước (NLR) (NLR) Duyệt gốc giữa(LNR) Duyệt gốc sau(LRN) (LRN)
phépduyệtcây Cài đặt A void NLR(const NODE * pCurr) { if(pCurr == NULL) return; xử lý nút gốc pCurr NLR(pCurr pLeft); NLR(pCurr pRight); } B E C D F A B E C D F Processing order A B E F C D
phépduyệtcây Cài đặt A void LNR(const NODE * pCurr) { if(pCurr == NULL) return; LNR(pCurr pLeft); xử lý nút gốc pCurr LNR(pCurr pRight); } B E C D F A B E C D F Processing order A B E F C D
phépduyệtcây Cài đặt A void LRN(const NODE * pCurr) { if(pCurr == NULL) return; LRN(pCurr pLeft); LRN(pCurr pRight); xử lý nút gốc pCurr } B E C D F A B E C D F Processing order A B E F C D
Bàitập BT1> Cho cây nhị phân các số nguyên. Hãy viết hàm đếm số lượng số chẵn có trong cây. Hãy viết hàm đếm số lượng nút lá trong cây bằng PP đệ quy và không đệ quy. Viết hàm đếm số lượng nút trong cây có khóa lớn hơn x. BT2> cho cây nhị phân các số thực. Hãy viết hàm tính tổng các giá trị dương có trong cây. Viết hàm đếm số lượng nút trong cây có giá trị nhỏ hơn x.
Bàitập BT3> Cho cây nhị phân các phân số. Viết hàm đếm số lượng nút có đúng 2 con. BT4>Cho cây nhị phân tọa độ các điểm trong mặt phẳng Oxy. Viết hàm tính chiều cao của cây.
Câynhịphântìmkiếm Ví dụ: cho biết hình nào thảo BST? Hình nào không thỏa BST? Tại sao? 17 17 17 (b) 6 19 22 19 (c) (a) 17 17 6 19 6 3 3 22 (d) (e)
Cácthaotáctrêncây BST • Tạo lập cây rỗng • Kiểm tra cây rỗng • Tìm kiếm phần tử • Thêm một phần tử • Xóa một phần tử • Sắp xếp dữ liệu • Quay cây
Tạolậpcâyrỗng • void BSTCreate(TREE &t) • { • t.Count = 0; // số nút trong cây • t.pRooot = NULL; // con trỏ đến nút gốc • }
kiểmtracâyrỗng • int BSTIsEmpty(TREE &t) • { • if(t.pRooot = = NULL) • return 1; • return 0; • }
Tìmkiếmphầntử Ví dụ tìm kiếm phần tử 25 40 pRoot 32 65 75 24 36 70 4 25 30 Tìmthấy, dừng
Tìmkiếmphầntử Ví dụ tìm kiếm phần tử 31 40 pRoot 32 65 75 24 36 70 4 25 30 NULL, khôngtìmthấy
Tìmkiếmphầntử • Cài đặt • NODE *BSTSearch(const NODE * pCurr, int Key) • { • if (pCurr == NULL) • return NULL; // không tìm thấy • if (pCurr Data == Key) • return pCurr; // Tìm thấy • else if (Key < pCurr Data) // tìm trong cây con trái • return BSTSearch(pCurrpLeft, Key); • else // tìm trong cây con phải • return BSTSearch(pCurr pRight,key); • }
Thêmphầntử Ví dụ thêm phần tử 26 40 pRoot 32 65 75 24 36 70 4 27 30 NULL, kếtthúctìm ở đây
Thêmphầntử Ví dụ thêm phần tử 26 40 pRoot 32 65 75 24 36 70 4 27 30 26
Thêmphầntử Ví dụ thêm phần tử 27 40 pRoot 32 65 75 24 36 70 4 27 30 Tìmthấy, khôngthêmnữa
Thêmphầntử • Cài đặt • int BSTInsert(NODE *&pCurr, int newKey) • { • if (pCurr == NULL) • { • pCurr = new NODE; // tạo nút mới • pCurr Data = newKey; • pCurrpLeft = pCurrpRight = NULL; • return 1;// thêm thành công • } • if ( newKey < pCurr Data) // thêm vào cây con trái • return BSTInsert(pCurrpLeft, newKey); • else if (newKey > pCurrData) // thêm vào cây con phải • return BSTInsert(pCurr pRight, newKey); • else return 0; // trùng khóa, không thêm nữa • }
Thêmphầntử • Có thể cài đặt cách khác như sau • int BSTInsert(TREE &t, int newKey) • { • if (t == NULL) • { • t = new NODE; // tạo nút mới • t Data = newKey; • tpLeft = tpRight = NULL; • return 1;// thêm thành công • } • if ( newKey < t Data) // thêm vào cây con trái • return BSTInsert(tpLeft, newKey); • else if (newKey > tData) // thêm vào cây con phải • return BSTInsert(t pRight, newKey); • else return 0; // trùng khóa, không thêm nữa • } • Với t được khai báo: typedef struct NODE *TREE;
Xóamộtđỉnhkhỏicâytìmkiếm Ví dụ xóa phần tử 25(chỉ có nút con phải là 30) 40 40 32 65 32 65 75 75 70 70 36 24 24 36 P 25 30 PCurr Liênkết = nút con phải 30 PpRight = pCurrpRight Delete pCurr