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; ichild[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 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:
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
8Root -> 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
9Nhượ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ớ. – All the pointers are not required in all the cases. Hence, there is lot of memory wastage.
- 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.
- 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.
- 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
};
0struct 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 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]];
}
2struct 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 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]];
}
6Root -> 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 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
};
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
2struct
5Root -> 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
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
8Nhượ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
};
6Root -> 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
9Advantages:
struct
9struct 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 };
struct
2Root -> 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
struct
5Root -> 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
struct
8Root -> 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
Nhược điểm của đại diện trên là: & nbsp;
Generic tree – level order traversal