Cài đặt cây nhị phân tìm kiếm bằng C++

Tuesday, April 03, 2018
Edit this post


Đối với môn Cấu trúc dữ liệu (CTDL), cây là một trong những khái niệm đặc biệt quan trọng, đặc biệt là cây nhị phân tìm kiếm (binary search tree - BST). Để có thể hiểu được BST, bạn cần phải hiểu rõ các loại danh sách liên kết (như đơn, đôi v.v...), và tất nhiên, phải hiểu rất rõ con trỏ cũng như cách sử dụng con trỏ.

Cây đơn giản là một cấu trúc dữ liệu bao gồm các nút, mỗi nút có thể coi là một ô nhớ chứa ít nhất là một biến dữ liệu và các con trỏ lưu giữ địa chỉ của các nút kết tiếp.

Cây nhị phân là cây mà mỗi nút của nó chỉ có tối đa 2 nút con.

Cây nhị phân tìm kiếm là cây nhị phân có quy luật như sau:
▸Khóa (hay giá trị) của một nút bất kỳ bên nhánh trái phải nhỏ hơn khóa (hay giá trị) của nút cha trên nó.
▸Khóa (hay giá trị) của một nút bất kỳ bên nhánh phải phải lớn hơn khóa (hay giá trị) của nút cha trên nó.

Lý thuyết cơ bản nói chung là như vậy, bây giờ chúng ta cần phải cài đặt thử một cây nhị phân bằng C++ xem nó như thế nào nhé.

Tạo một mảng các số nguyên với thứ tự đầu vào các số như sau:


short a[] = {29, 5, 39, 19, 11, 10, 18, 25, 0, 1, 23, 34, 48, 6, 24, 26};


Dựa vào quy luật của BST, ta có được hình minh họa như sau:


Khai báo cấu trúc của một node trong cây nhị phân tìm kiếm:


struct node {
 short x;
 node *left;
 node *right;
};


Tạo node mới:


// create a new node
node* createNode(short x) {
 node *p = new node();
 p->x = x;
 p->left = NULL;
 p->right = NULL;
}


Chèn một node vào cây nhị phân tìm kiếm:


// find a good node to insert the next new node
node* findPosition(node* root, short x) {
 node *p = root;
 while (p != NULL) {
  // q points to the node which p is currently pointing to 
  // before p points to another node
  node *q = p;
  
  if (p->x > x) {
   p = p->left;
  } else {
   p = p->right;
  }
  
  if (p == NULL) { // no more nodes to point to
   return q;
  }
 }
}

void insertNode(node *&root, short x) {
 if (root == NULL) { // the tree has no nodes
  root = createNode(x);
  return;
 } else {
  node *q = findPosition(root, x);
  if (q->x > x) {
   q->left = createNode(x);
  } else {
   q->right = createNode(x);
  }
 }
}


Tính độ cao của cây nhị phân tìm kiếm:


/* Compute the "height" of a tree -- the number of
    nodes along the longest path from the root node
    down to the farthest leaf node.*/
int height(node *root) {
 if (root == NULL) {
  return 0;
 } else {
  /* compute the height of each subtree */
  int lHeight = height(root->left);
  int rHeight = height(root->right);
  
  /* use the larger one */
  if (lHeight > rHeight) {
   return (lHeight + 1);
  } else {
   return (rHeight + 1);
  }
 }
}


Tôi viết tiếp một hàm in ra cây nhị phân dưới dạng cây thư mục để chúng ta có thể quan sát trực quan nhất cây nhị phân. Về bản chất, đây chính là cách duyệt NLR (Node-Left-Right). Có 6 cách duyệt trên cây nhị phân: NLR , LNR, LRN, NRL, RNL, RLN.


// print out the binary search tree graphically
bool rec[10];
void printTree(node* root, int depth) {
 if (root == NULL) {
  return;
 }
 cout << "   ";

 for (int i = 0; i < depth; i++) {
  if (i == depth - 1) {
   if (rec[depth - 1]) {
    setColor(160);
    cout << "L";
    setColor(15);
   } else {
    setColor(48);
    cout << "R";
    setColor(15);
   }
   cout << "------->";
  } else {
   if (rec[i]) {
    cout << "|        ";
   } else {
    cout << "         ";
   }
  }
 }
 
 setColor(207);
 cout << " " << root->x << " " << endl;
 setColor(15);
 
 rec[depth] = true;
 printTree(root->left, depth + 1);

 rec[depth] = false;
 printTree(root->right, depth + 1);
}


Giờ chạy thử chương trình xem chúng ta được gì nhé (các nút được tô màu đỏ, L là nhánh trái, R là nhánh phải).

Yeah, đây là kết quả được in ra console, hơi màu mè xíu LOL.
Hãy thử so sánh với hình minh họa ở đầu bài để xem code của chúng ta hoạt động chính xác không nhé.

.
Xin vui lòng chờ đợi
Dữ liệu bài viết đang được tải về

💻Nhận dạy online 1 kèm 1 Automation Test từ cơ bản tới nâng cao (From Zero to Hero) 😁😁😁
Lộ trình gồm 3 phần:
1) Kỹ thuật lập trình và tư duy lập trình cơ bản
2) Nhập môn kiểm thử (Manual Test)
3) Kiểm thử tự động (Automation Test) + Chuẩn bị cho phỏng vấn
* Lộ trình chi tiết: Xem tại đây

🎓Đối tượng người học:
- Những bạn bị mất gốc căn bản môn lập trình.
- Những bạn muốn theo con đường kiểm thử (testing), đặc biệt là kiểm thử tự động (Automation Test).

🦘Người giảng dạy:
- Mình sẽ là người trực tiếp hướng dẫn.
- Nếu là các vấn đề ngoài chuyên môn hoặc sở trường, mình sẽ nhờ các anh chị em khác cũng làm trong ngành.

🤓Giới thiệu:
- Mình đã có hơn 10 năm kinh nghiệm làm IT ở cả trong và ngoài nước. Trong đó 3 năm đầu là làm lập trình viên Java, sau đó bén duyên với mảng Automation Test và theo nghề tới tận bây giờ. Mình được đào tạo chính quy về IT từ một trường Đại học danh tiếng ở TP.HCM (hệ kỹ sư 4 năm rưỡi), có chứng chỉ ISTQB, có thể giao tiếp tốt bằng tiếng Anh và có kinh nghiệm làm việc thực tế ở cả 2 mảng Outsource và Product. Title chính thức của mình là QA Automation Engineer, tuy nhiên, mình vẫn làm những dự án cá nhân chuyên về lập trình ứng dụng như Học Tiếng Anh StreamlineSách Nhạc. Mình là người có thái độ làm việc chuyên nghiệp, chăm chỉ và luôn nhiệt tình trong công việc.

💵Chi phí và hình thức thanh toán:
- Các bạn vui lòng liên hệ qua email songtoigianvn@gmail.com (email, chat, hoặc call) để book nội dung và khung giờ học (từ 8h tối trở đi).
- Mức phí: 150.000đ/buổi, mỗi buổi 60 phút.
- Lộ trình From Zero to Hero: 4.350.000đ (29 buổi).
- Bạn có thể học riêng và đóng tiền theo từng phần nếu muốn.
- Có thể học trước 1-2 buổi trước khi quyết định đi full lộ trình hoặc từng phần.
- Thanh toán qua Momo, chuyển khoản v.v...
BÌNH LUẬN
© Copyright by CUỘC SỐNG TỐI GIẢN
Loading...