Hướng dẫn n-ary tree implementation in c++ - triển khai cây n-ary trong c ++

Chỉ phân bổ bộ nhớ cho thành viên child trước khi sử dụng nó:

current_node->child = malloc(3 * sizeof(node *));

for (i=0; i<3; i++) {
    current_node->child[i] = createNode(array[i],(current_node->depth)+1);
    current_node->children++;
    printf("%s  has been inserted to the tree\n",current_node->word);
}

Cấu trúc bạn đã xác định có nghĩa là bạn phải quản lý từng cấp độ như một mảng các nút có số lượng phần tử có khả năng động. Một cấu trúc phổ biến hơn được sử dụng cho biểu diễn cây n-ary trong C sẽ là:

struct node {
    char *word;
    int depth, children;  // Reconsider if you need these
                          //   for maintenance effort versus benefit
    struct node *child;   // point to children of this node
    struct node *next;    // point to next node at same level
};

Vì vậy, cấu trúc trông như thế này:

Root -> NULL
 |
 V
Child-1.1 -> Child-1.2 -> ... -> Child-1.n -> NULL
 |              |                   |            
 |              V                   V
 |              ...              Child-1.n.1 -> ... -> NULL
 V
Child-1.1.1 -> Child-1.1.2 -> ... -> NULL
 |
 ... etc

Sau đó, bạn cần phải sửa đổi createNode của mình và viết các thói quen quản lý cây khác của bạn cho phù hợp. Một mẫu một phần và rất ngắn gọn về cách chúng có thể trông như thế nào (không nhất thiết phải chứa tất cả các kiểm tra hợp lệ phù hợp hoặc loại bỏ/giải quyết nút):

struct node {
    int data;
    struct node *next;
    struct node *child;
};

typedef struct node node;

node * new_node(int);
node * add_sibling(node *, int);
node * add_child(node *, int);

int main(int argc, char *argv[])
{
    int i;
    node *root = new_node(0);

    for ( i = 1; i <= 3; i++ )
        add_child(root, i);
}

node * new_node(int data)
{
    node *new_node = malloc(sizeof(node));

    if ( new_node ) {
        new_node->next = NULL;
        new_node->child = NULL;
        new_node->data = data;
    }

    return new_node;
}

node * add_sibling(node * n, int data)
{
    if ( n == NULL )
        return NULL;

    while (n->next)
        n = n->next;

    return (n->next = new_node(data));
}

node * add_child(node * n, int data)
{
    if ( n == NULL )
        return NULL;

    if ( n->child )
        return add_sibling(n->child, data);
    else
        return (n->child = new_node(data));
}

Cây chung là một tập hợp các nút trong đó mỗi nút là cấu trúc dữ liệu bao gồm các bản ghi và danh sách các tài liệu tham khảo cho trẻ em của nó (không được phép tham khảo trùng lặp). Không giống như danh sách được liên kết, mỗi nút lưu trữ địa chỉ của nhiều nút. Mỗi địa chỉ lưu trữ nút của trẻ em và địa chỉ nút đầu tiên sẽ được lưu trữ trong một con trỏ riêng gọi là Root.

Các cây chung là những cây n-ary có các thuộc tính sau: & nbsp;

& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; 1. Nhiều trẻ em ở mọi nút.

& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; 2. Số lượng nút cho mỗi nút không được biết trước.

Example:   
 

Hướng dẫn n-ary tree implementation in c++ - triển khai cây n-ary trong c ++

Cây chung

Để đại diện cho cây trên, chúng ta phải xem xét trường hợp xấu nhất, đó là nút có trẻ em tối đa (trong ví dụ trên, 6 trẻ em) và phân bổ nhiều gợi ý cho mỗi nút. Biểu diễn nút dựa trên phương pháp này có thể được viết là: & nbsp;
The node representation based on this method can be written as:
 

C

struct Node{

   int

struct node {
    char *word;
    int depth, children;  // Reconsider if you need these
                          //   for maintenance effort versus benefit
    struct node *child;   // point to children of this node
    struct node *next;    // point to next node at same level
};
0

   struct

struct node {
    char *word;
    int depth, children;  // Reconsider if you need these
                          //   for maintenance effort versus benefit
    struct node *child;   // point to children of this node
    struct node *next;    // point to next node at same level
};
3

   struct

struct node {
    char *word;
    int depth, children;  // Reconsider if you need these
                          //   for maintenance effort versus benefit
    struct node *child;   // point to children of this node
    struct node *next;    // point to next node at same level
};
6

   struct

struct node {
    char *word;
    int depth, children;  // Reconsider if you need these
                          //   for maintenance effort versus benefit
    struct node *child;   // point to children of this node
    struct node *next;    // point to next node at same level
};
9

   struct

Root -> NULL
 |
 V
Child-1.1 -> Child-1.2 -> ... -> Child-1.n -> NULL
 |              |                   |            
 |              V                   V
 |              ...              Child-1.n.1 -> ... -> NULL
 V
Child-1.1.1 -> Child-1.1.2 -> ... -> NULL
 |
 ... etc
2

   struct

Root -> NULL
 |
 V
Child-1.1 -> Child-1.2 -> ... -> Child-1.n -> NULL
 |              |                   |            
 |              V                   V
 |              ...              Child-1.n.1 -> ... -> NULL
 V
Child-1.1.1 -> Child-1.1.2 -> ... -> NULL
 |
 ... etc
5

   struct

Root -> NULL
 |
 V
Child-1.1 -> Child-1.2 -> ... -> Child-1.n -> NULL
 |              |                   |            
 |              V                   V
 |              ...              Child-1.n.1 -> ... -> NULL
 V
Child-1.1.1 -> Child-1.1.2 -> ... -> NULL
 |
 ... etc
8

Root -> NULL
 |
 V
Child-1.1 -> Child-1.2 -> ... -> Child-1.n -> NULL
 |              |                   |            
 |              V                   V
 |              ...              Child-1.n.1 -> ... -> NULL
 V
Child-1.1.1 -> Child-1.1.2 -> ... -> NULL
 |
 ... etc
9

Nhược điểm của đại diện trên là: & nbsp; 

  1. Sự lãng phí bộ nhớ - Tất cả các con trỏ không bắt buộc trong tất cả các trường hợp. Do đó, có rất nhiều lãng phí bộ nhớ. – All the pointers are not required in all the cases. Hence, there is lot of memory wastage.
  2. Số lượng trẻ em chưa biết - Số trẻ em cho mỗi nút không được biết trước. – The number of children for each node is not known in advance.

Cách tiếp cận đơn giản: & nbsp; 

Để lưu trữ địa chỉ của trẻ em trong một nút, chúng tôi có thể sử dụng một mảng hoặc danh sách được liên kết. Nhưng chúng tôi sẽ phải đối mặt với một số vấn đề với cả hai.

  1. Trong danh sách được liên kết, chúng tôi không thể truy cập ngẫu nhiên bất kỳ địa chỉ trẻ con nào. Vì vậy, nó sẽ đắt tiền.Linked list, we can not randomly access any child’s address. So it will be expensive.
  2. Trong Array, chúng tôi có thể truy cập ngẫu nhiên địa chỉ của bất kỳ đứa trẻ nào, nhưng chúng tôi chỉ có thể lưu trữ số lượng địa chỉ trẻ em cố định trong đó.array, we can randomly access the address of any child, but we can store only fixed number of children’s addresses in it.

Cách tiếp cận tốt hơn:

Chúng ta có thể sử dụng các mảng động để lưu trữ địa chỉ của địa chỉ trẻ em. Chúng tôi có thể truy cập ngẫu nhiên bất kỳ địa chỉ trẻ con nào và kích thước của vectơ cũng không được sửa.

C

struct Node{

   int

struct node {
    char *word;
    int depth, children;  // Reconsider if you need these
                          //   for maintenance effort versus benefit
    struct node *child;   // point to children of this node
    struct node *next;    // point to next node at same level
};
0

struct node {
    int data;
    struct node *next;
    struct node *child;
};

typedef struct node node;

node * new_node(int);
node * add_sibling(node *, int);
node * add_child(node *, int);

int main(int argc, char *argv[])
{
    int i;
    node *root = new_node(0);

    for ( i = 1; i <= 3; i++ )
        add_child(root, i);
}

node * new_node(int data)
{
    node *new_node = malloc(sizeof(node));

    if ( new_node ) {
        new_node->next = NULL;
        new_node->child = NULL;
        new_node->data = data;
    }

    return new_node;
}

node * add_sibling(node * n, int data)
{
    if ( n == NULL )
        return NULL;

    while (n->next)
        n = n->next;

    return (n->next = new_node(data));
}

node * add_child(node * n, int data)
{
    if ( n == NULL )
        return NULL;

    if ( n->child )
        return add_sibling(n->child, data);
    else
        return (n->child = new_node(data));
}
2
struct node {
    int data;
    struct node *next;
    struct node *child;
};

typedef struct node node;

node * new_node(int);
node * add_sibling(node *, int);
node * add_child(node *, int);

int main(int argc, char *argv[])
{
    int i;
    node *root = new_node(0);

    for ( i = 1; i <= 3; i++ )
        add_child(root, i);
}

node * new_node(int data)
{
    node *new_node = malloc(sizeof(node));

    if ( new_node ) {
        new_node->next = NULL;
        new_node->child = NULL;
        new_node->data = data;
    }

    return new_node;
}

node * add_sibling(node * n, int data)
{
    if ( n == NULL )
        return NULL;

    while (n->next)
        n = n->next;

    return (n->next = new_node(data));
}

node * add_child(node * n, int data)
{
    if ( n == NULL )
        return NULL;

    if ( n->child )
        return add_sibling(n->child, data);
    else
        return (n->child = new_node(data));
}
6

Root -> NULL
 |
 V
Child-1.1 -> Child-1.2 -> ... -> Child-1.n -> NULL
 |              |                   |            
 |              V                   V
 |              ...              Child-1.n.1 -> ... -> NULL
 V
Child-1.1.1 -> Child-1.1.2 -> ... -> NULL
 |
 ... etc
9

   struct
struct node {
    char *word;
    int depth, children;  // Reconsider if you need these
                          //   for maintenance effort versus benefit
    struct node *child;   // point to children of this node
    struct node *next;    // point to next node at same level
};
3

   struct

struct node {
    char *word;
    int depth, children;  // Reconsider if you need these
                          //   for maintenance effort versus benefit
    struct node *child;   // point to children of this node
    struct node *next;    // point to next node at same level
};
6

   struct

struct node {
    char *word;
    int depth, children;  // Reconsider if you need these
                          //   for maintenance effort versus benefit
    struct node *child;   // point to children of this node
    struct node *next;    // point to next node at same level
};
9

   struct

Root -> NULL
 |
 V
Child-1.1 -> Child-1.2 -> ... -> Child-1.n -> NULL
 |              |                   |            
 |              V                   V
 |              ...              Child-1.n.1 -> ... -> NULL
 V
Child-1.1.1 -> Child-1.1.2 -> ... -> NULL
 |
 ... etc
2

  •    struct
    Root -> NULL
     |
     V
    Child-1.1 -> Child-1.2 -> ... -> Child-1.n -> NULL
     |              |                   |            
     |              V                   V
     |              ...              Child-1.n.1 -> ... -> NULL
     V
    Child-1.1.1 -> Child-1.1.2 -> ... -> NULL
     |
     ... etc
    
    5

   struct

Root -> NULL
 |
 V
Child-1.1 -> Child-1.2 -> ... -> Child-1.n -> NULL
 |              |                   |            
 |              V                   V
 |              ...              Child-1.n.1 -> ... -> NULL
 V
Child-1.1.1 -> Child-1.1.2 -> ... -> NULL
 |
 ... etc
8
 

Hướng dẫn n-ary tree implementation in c++ - triển khai cây n-ary trong c ++

Nhược điểm của đại diện trên là: & nbsp;

Sự lãng phí bộ nhớ - Tất cả các con trỏ không bắt buộc trong tất cả các trường hợp. Do đó, có rất nhiều lãng phí bộ nhớ.
 

C

struct Node{

   int

struct node {
    char *word;
    int depth, children;  // Reconsider if you need these
                          //   for maintenance effort versus benefit
    struct node *child;   // point to children of this node
    struct node *next;    // point to next node at same level
};
0

   struct

struct node {
    char *word;
    int depth, children;  // Reconsider if you need these
                          //   for maintenance effort versus benefit
    struct node *child;   // point to children of this node
    struct node *next;    // point to next node at same level
};
3

   struct

struct node {
    char *word;
    int depth, children;  // Reconsider if you need these
                          //   for maintenance effort versus benefit
    struct node *child;   // point to children of this node
    struct node *next;    // point to next node at same level
};
6

Root -> NULL
 |
 V
Child-1.1 -> Child-1.2 -> ... -> Child-1.n -> NULL
 |              |                   |            
 |              V                   V
 |              ...              Child-1.n.1 -> ... -> NULL
 V
Child-1.1.1 -> Child-1.1.2 -> ... -> NULL
 |
 ... etc
9

Advantages:  

  •    struct
    struct node {
        char *word;
        int depth, children;  // Reconsider if you need these
                              //   for maintenance effort versus benefit
        struct node *child;   // point to children of this node
        struct node *next;    // point to next node at same level
    };
    
    9
  •    struct
    Root -> NULL
     |
     V
    Child-1.1 -> Child-1.2 -> ... -> Child-1.n -> NULL
     |              |                   |            
     |              V                   V
     |              ...              Child-1.n.1 -> ... -> NULL
     V
    Child-1.1.1 -> Child-1.1.2 -> ... -> NULL
     |
     ... etc
    
    2
  •    struct
    Root -> NULL
     |
     V
    Child-1.1 -> Child-1.2 -> ... -> Child-1.n -> NULL
     |              |                   |            
     |              V                   V
     |              ...              Child-1.n.1 -> ... -> NULL
     V
    Child-1.1.1 -> Child-1.1.2 -> ... -> NULL
     |
     ... etc
    
    5
  •    struct
    Root -> NULL
     |
     V
    Child-1.1 -> Child-1.2 -> ... -> Child-1.n -> NULL
     |              |                   |            
     |              V                   V
     |              ...              Child-1.n.1 -> ... -> NULL
     V
    Child-1.1.1 -> Child-1.1.2 -> ... -> NULL
     |
     ... etc
    
    8

Nhược điểm của đại diện trên là: & nbsp;
Generic tree – level order traversal


N

Cho một cây n-ary chứa, nhiệm vụ là in các đường truyền từ của cây ...
Thăm một đứa trẻ đầu tiên ..
Thăm một đứa trẻ thứ hai ..
Thăm đứa con cuối cùng đệ quy ..
In dữ liệu trong nút ..
Thăm một đứa trẻ cuối cùng ..
Lặp lại các bước trên cho đến khi tất cả các nút được truy cập ..

Làm thế nào để bạn làm một cây ary?

Cách tiếp cận hiệu quả: Ở đứa con đầu lòng/anh chị em tiếp theo, các bước được thực hiện là: tại mỗi nút liên kết các con của cùng một phụ huynh (anh chị em) từ trái sang phải. Chuyển các liên kết từ cha mẹ đến tất cả con ngoại trừ đứa con đầu lòng.At each node-link the children of the same parent(siblings) from left to right. Remove the links from parent to all children except the first child.

Hoàn thành n

Một cây n-ary hoàn chỉnh là một cây trong đó mỗi nút có n con hoặc không có con.a tree in which each node has n children or no children.

N trong cấu trúc dữ liệu cây là gì?

Giới thiệu.Cây n-ary là các cấu trúc dữ liệu cây cho phép chúng ta có tới N trẻ em cho mỗi nút, khác với các cây nhị phân tiêu chuẩn chỉ cho phép tối đa 2 nút trẻ em cho mỗi nút.Hình trên cho thấy một ví dụ về một cây n-ary.up to n children nodes for each of the nodes, differing from the standard binary trees which allow only up to 2 children nodes for each node. The above picture shows an example of an n-ary tree.