设计算法,对以字符串形式表示的广义表,构造出其相应 的链表存储结构
时间: 2024-05-07 12:15:30 浏览: 123
c++语言算法讲稿(清华的严蔚敏)
1. 定义节点结构体
我们可以先定义节点结构体,包含一个数据域和两个指针域,一个指向子表,一个指向兄弟节点。
```c++
struct Node {
char data; // 数据域,存储字符
Node* child; // 指向子表的指针
Node* sibling; // 指向兄弟节点的指针
};
```
2. 构造算法
接下来我们可以设计算法,将字符串形式表示的广义表转换成链表存储结构。
```c++
Node* createList(string s) {
stack<Node*> st; // 用栈来存储节点
Node* root = nullptr; // 根节点指针初始化为空
Node* cur = nullptr; // 当前节点指针初始化为空
bool isChild = false; // 标记是否为子表
for (int i = 0; i < s.size(); i++) {
if (s[i] == '(') {
isChild = true; // 进入子表
} else if (s[i] == ')') {
st.pop(); // 子表结束,出栈
} else if (s[i] == ',') {
isChild = false; // 兄弟节点开始
} else {
cur = new Node(); // 新建一个节点
cur->data = s[i]; // 节点存储字符
cur->child = nullptr; // 子表指针初始化为空
cur->sibling = nullptr; // 兄弟节点指针初始化为空
if (st.empty()) { // 根节点为空,将当前节点作为根节点
root = cur;
} else if (isChild) { // 当前节点为子表
st.top()->child = cur; // 将当前节点作为父节点的子节点
} else { // 当前节点为兄弟节点
st.top()->sibling = cur; // 将当前节点作为上一个兄弟节点的下一个兄弟节点
}
st.push(cur); // 将当前节点入栈,以便后续节点的处理
}
}
return root; // 返回根节点指针
}
```
3. 测试
我们可以定义一个字符串表示广义表,然后调用函数将其转化为链表存储结构,并遍历输出。
```c++
int main() {
string s = "(a,(b,c,d),(e,f))";
Node* root = createList(s);
traverse(root);
return 0;
}
```
其中,`traverse`函数可以用来遍历链表,输出其中的每个节点。
```c++
void traverse(Node* root) {
if (root == nullptr) {
return;
}
cout << root->data << " ";
traverse(root->child);
traverse(root->sibling);
}
```
输出结果为:
```
a b c d e f
```
表示成功将广义表转化为链表存储结构,并正确输出其中的每个节点。
阅读全文