如何以兄弟孩子表示法写一份学生会组织人员管理系统
时间: 2023-08-07 16:07:44 浏览: 63
以下是使用兄弟孩子表示法(又称为双亲表示法)来写一份学生会组织人员管理系统的示例:
```c
#define MAX_TREE_SIZE 100 // 树的最大结点数
// 学生会组织人员结构体
typedef struct {
int id; // 学号
char name[20]; // 姓名
char position[20]; // 职位
} Student;
// 树的结点结构体
typedef struct {
Student data; // 数据域,存储学生会组织人员信息
int parent; // 双亲域,存储双亲结点在数组中的下标
int firstChild; // 长子域,存储长子结点在数组中的下标
int nextSibling; // 右兄弟域,存储右兄弟结点在数组中的下标
} TreeNode;
// 树结构体
typedef struct {
TreeNode nodes[MAX_TREE_SIZE]; // 结点数组
int root; // 根结点的下标
int size; // 树的结点数
} Tree;
// 初始化树
void initTree(Tree *tree) {
tree->root = -1;
tree->size = 0;
}
// 在树中插入一个结点
void insertNode(Tree *tree, Student data, int parentIndex) {
// 创建一个新结点
int newNodeIndex = tree->size;
tree->nodes[newNodeIndex].data = data;
tree->nodes[newNodeIndex].parent = parentIndex;
tree->nodes[newNodeIndex].firstChild = -1;
tree->nodes[newNodeIndex].nextSibling = -1;
// 将新结点插入到树中
if (parentIndex == -1) {
// 如果父结点下标为-1,则说明新结点为根结点
tree->root = newNodeIndex;
} else {
// 否则,将新结点作为父结点的长子或右兄弟
TreeNode *parentNode = &tree->nodes[parentIndex];
if (parentNode->firstChild == -1) {
// 如果父结点没有长子,则将新结点作为父结点的长子
parentNode->firstChild = newNodeIndex;
} else {
// 否则,找到父结点的最后一个子结点,将新结点作为它的右兄弟
TreeNode *lastChildNode = &tree->nodes[parentNode->firstChild];
while (lastChildNode->nextSibling != -1) {
lastChildNode = &tree->nodes[lastChildNode->nextSibling];
}
lastChildNode->nextSibling = newNodeIndex;
}
}
// 更新树的结点数
tree->size++;
}
// 根据学号查找结点在数组中的下标
int findNodeIndexById(Tree *tree, int id) {
for (int i = 0; i < tree->size; i++) {
if (tree->nodes[i].data.id == id) {
return i;
}
}
return -1;
}
// 根据姓名查找结点在数组中的下标
int findNodeIndexByName(Tree *tree, char *name) {
for (int i = 0; i < tree->size; i++) {
if (strcmp(tree->nodes[i].data.name, name) == 0) {
return i;
}
}
return -1;
}
// 根据职位查找结点在数组中的下标
int findNodeIndexByPosition(Tree *tree, char *position) {
for (int i = 0; i < tree->size; i++) {
if (strcmp(tree->nodes[i].data.position, position) == 0) {
return i;
}
}
return -1;
}
// 修改结点的信息
void modifyNode(Tree *tree, int index, Student data) {
tree->nodes[index].data = data;
}
// 删除结点
void deleteNode(Tree *tree, int index) {
TreeNode *node = &tree->nodes[index];
// 将该结点的长子及其所有子孙结点的双亲域设为该结点的双亲结点
if (node->firstChild != -1) {
TreeNode *firstChildNode = &tree->nodes[node->firstChild];
firstChildNode->parent = node->parent;
int nextSiblingIndex = firstChildNode->nextSibling;
while (nextSiblingIndex != -1) {
TreeNode *nextSiblingNode = &tree->nodes[nextSiblingIndex];
nextSiblingNode->parent = node->parent;
nextSiblingIndex = nextSiblingNode->nextSibling;
}
}
// 将该结点从双亲结点的子结点链表中删除
if (node->parent == -1) {
tree->root = -1;
} else {
TreeNode *parentNode = &tree->nodes[node->parent];
if (parentNode->firstChild == index) {
parentNode->firstChild = node->nextSibling;
} else {
TreeNode *prevSiblingNode = &tree->nodes[parentNode->firstChild];
while (prevSiblingNode->nextSibling != index) {
prevSiblingNode = &tree->nodes[prevSiblingNode->nextSibling];
}
prevSiblingNode->nextSibling = node->nextSibling;
}
}
// 将该结点的双亲、长子和右兄弟域设为-1
node->parent = -1;
node->firstChild = -1;
node->nextSibling = -1;
// 更新树的结点数
tree->size--;
}
```
以上代码使用了兄弟孩子表示法来实现学生会组织人员管理系统。可以通过 `insertNode` 函数向树中插入一个结点,通过 `findNodeIndexById`、`findNodeIndexByName` 和 `findNodeIndexByPosition` 函数查找结点在数组中的下标,通过 `modifyNode` 函数修改结点的信息,通过 `deleteNode` 函数删除结点。