此例程的输入是不存在问题的只要按规定输入,不过想要扩展规则也很容易。不过我们只是要此例程做练习,故我们并没有去完善功能。
首先我们会声明表头为空的链表,且给每个节点附加一个栈,并且我们会使用一个相同的结构体,完成两次不同但是类似的数据结构模型(ADT)
给出声明
//表
struct listNode;
typedef struct listNode* listPosition;
typedef listPosition list;
//栈
struct innNode;
typedef struct innNode* innPosition;
typedef innPosition Inn;
//链表
struct listNode {
char* value; //数值或是变量
Inn head;
listPosition nextList;
};
//栈,
struct innNode {
char symbol; //运算符
innPosition nextInn;
};
制造一个表头
list
Make() {
listPosition temp = (listPosition)malloc(sizeof(struct listNode));
temp->value = NULL;
temp->head = NULL;
temp->nextList = NULL;
return temp;
}
增加一个表节点
void
AddListNode(listPosition T)
{
listPosition temp = (listPosition)malloc(sizeof(struct listNode));
temp->value = NULL;
temp->head = NULL;
temp->nextList = NULL;
T->nextList = temp;
}
为表中的附加栈赋值,在其中可以进行多运算符的扩展
void
AddSymbol(listPosition T, char sym)
{
if (T->head == NULL)
{
innPosition tem = (innPosition)malloc(sizeof(struct innNode));
tem->nextInn = NULL;
tem->symbol = sym;
T->head = tem;
}
else
printf("错误输入!!!");
}
插入例程
void
Import(list Table) {
listPosition temp = Table;
printf("请输入表达式,以回车结束\n只支持加减乘除等运算符\n");
char* p = (char*)malloc(sizeof(char) * 10);
char input;
int i = 0;
do {
input = getchar();
if (input != '+' && input != '-' && input != '*' && input != '/')
{
p[i++] = input;
}
else
{
p[i] = '\0'; i = 0;
temp->value = p;
p = (char*)malloc(sizeof(char) * 10);
AddSymbol(temp, input);
AddListNode(temp);
temp = temp->nextList;
}
} while (input != 10);
p[i] = '\0';
temp->value = p;
AddListNode(temp);
}
下面是漏洞百出的输出例程
我们使用栈储存运算符
制造一个栈
Inn
makeInn() {
innPosition temp = (innPosition)malloc(sizeof(struct innNode));
temp->nextInn = NULL;
return temp;
}
入栈
innPosition
Push(Inn header, char c)
{
innPosition temp = (innPosition)malloc(sizeof(struct innNode));
temp->nextInn = header;
temp->symbol = c;
return temp;
}
出栈
innPosition
Pop(Inn header)
{
printf("%c", header->symbol);
header = header->nextInn;
return header;
}
输出例程逻辑
void
putPostfix(list table)
{
listPosition wang = table;
Inn header = makeInn();
char first, second;
printf("%s", wang->value);
first = wang->head->symbol;
header = Push(header, first);
wang = wang->nextList;
while (wang != NULL)
{
printf("%s", wang->value);
if (wang->head == NULL) break;
second = wang->head->symbol;
wang = wang->nextList;
if (first == '*' || first == '/')
{
if (second == '+' || second == '-')
{
header=Pop(header);
printf("%c", second);
}
}
else
{
header = Push(header, second);
first = second;
}
}
//while (header != NULL)
//{
// header = Pop(header);
//}
dao(header);
}
其中,注释的是用来输出的且之后的dao()何其作用相似,不过第一个输出样式是不符合“后缀”结果的,但我写的dao()例程是使用递归(练习),希望各位可以指出我的递归例程的错误
递归
void dao(Inn header) {
if (header != NULL)
{
dao(header->nextInn);
printf("%c", header->symbol);
}
}
此文中很多地方可以进行简化,但由于本人突发奇想,便就“一错再错”,终是可以勉强跑起来,照调试例程看来,数据结构并无错。
但我无法发现输出例程中的错误,例如当式子中包含‘*’时若再输入‘/’便会出错。
此处附上调试例程
while (temp != NULL)
{
printf("%s", temp->value);
if(temp->head!=NULL) printf("%c\n", temp->head->symbol);
temp = temp->nextList;
}
可以直接写在主函数中
```c
int main()
{
list l;
l = Make();
Import(l);
listPosition temp = l;
//putPostfix(l);
getchar();
}