typedefint ElementType;//数据部分的数据类型/* P39 START:figure 3-6 */#ifndef __LIST_H__#define __LIST_H__struct Node;typedefstruct Node *PtrNode;//结点类型的指针typedef PtrNode List;//头结点typedef PtrNode Position;//中间某一节点
List MakeEmpty(List L);//把链表全部结点置空intIsEmpty(List L);//判断链表是否是空表intIsLast(Position P, List L);//判断P是否是最后一个结点
Position Find(ElementType X, List L);//返回关键字首次出现的位置voidDelete(ElementType X, List L);//从链表中删除某一元素
Position FindPrevious(ElementType X, List L);//返回关键字的上一个位置voidInsert(ElementType X, List L, Position P);//在某个位置,插入某个关键字voidDeleteList(List L);
Position Header(List L);//返回头结点
Position First(List L);//
Position Advance(Position P);
ElementType Retrieve(Position P);#endif/* END */
list.c
#include<stdlib.h>#include"list.h"#include"fatal.h"//节点的数据结构struct Node
{
ElementType Element;
Position Next;};//清空链表,保留头结点
List MakeEmpty(List L){if(L !=NULL)DeleteList(L);
L =malloc(sizeof(struct Node));//??????????????if(L ==NULL)FatalError("Out of memory! ");
L->Next =NULL;return L;}//图3-8 判断链表是否是空表intIsEmpty(List L){return(L->Next ==NULL);}//图3-9 若P是L的最后一个节点返回true//参数L在实现中没有用到intIsLast(Position P, List L){return(P->Next ==NULL);}//图3-10 返回关键字首次出现的位置 // 成功:X的位置,失败:NULL
Position Find(ElementType X, List L){
Position P;
P = L->Next;while(P !=NULL&& P->Element != X){
P = P->Next;}return P;}//图3-11 删除链表L中第一次出现的X,//如果不存在就什么也不做(假设X存在于L)voidDelete(ElementType X, List L){
Position P, TmpCell;
P =FindPrevious(X, L);if(!IsLast(P, L)){
TmpCell = P->Next;//此时TmpCell为待删除的节点
P->Next = TmpCell->Next;//free(TmpCell);}}//图3-12 返回关键字的上一个位置//成功:X的上一个位置,失败:NULL//提供给Delete使用
Position FindPrevious(ElementType X, List L){
Position P;
P = L;while(P->Next !=NULL&& P->Next->Element != X){
P = P->Next;}return P;}//figure3-13 在某个位置,插入某个关键字voidInsert(ElementType X, List L, Position P){if(P ==NULL){return;}
Position TmpCell;
TmpCell =malloc(sizeof(struct Node));if(TmpCell ==NULL){FatalError("malloc space error!");}
TmpCell->Element = X;
TmpCell->Next = P->Next;
P->Next = TmpCell;}//figure3-15 删除整张表voidDeleteList(List L){
Position P, TmpCell;
P = L->Next;
L->Next =NULL;while(P !=NULL){
TmpCell = P->Next;free(P);
P = TmpCell;}}
Position Header(List L)//返回头结点{return L;}
Position First(List L)//{return L->Next;}
Position Advance(Position P){return P->Next;}
ElementType Retrieve(Position P){return P->Element;}
testlist.c
#include<stdio.h>#include"list.h"voidPrintList(const List L){
Position P =Header(L);if(IsEmpty(L))printf("Empty List\n");else{do{
P =Advance(P);printf("%d ",Retrieve(P));}while(!IsLast(P, L));printf("\n");}}intmain(){
List L =NULL;
Position P =NULL;int i=0;
L =MakeEmpty(L);
P =Header(L);PrintList(L);for(i =0; i <10; i++){Insert(i, L, P);PrintList(L);
P =Advance(P);}for(i =0; i <10; i +=2){Delete(i, L);//删除偶数}for(i =0; i <10; i++){if((i %2==0)==(Find(i, L)!=NULL)){//若是find到偶数,说明删除错误printf("Find fails\n");}}printf("Finish deletions\n");PrintList(L);DeleteList(L);system("pause");return0;}
#include<stdio.h>#include"stacklist.h"intmain(){
Stack S =NULL;int i =0;
S =CreateStack();for(i =0; i <10; i++){Push(i, S);}while(!IsEmpty(S)){printf("%d\n",Top(S));Pop(S);}DisposeStack(S);system("pause");return0;}
#include<stdio.h>#include<stdlib.h>#include"stackArray.h"intmain(){
Stack S =NULL;int i =0;
S =CreateStack(12);for(i =0; i <10; i++)Push(i, S);while(!IsEmpty(S)){printf("%d\n",Top(S));Pop(S);}DisposeStack(S);system("pause");return0;}
用栈将一个标准形式的表达式(或者叫中缀式(infix)转换成后缀式)
注意:假设这些操作符是从左到右结合的
例子:
a+b*c+(d*e+f)*g
a b c *+ d e * f + g *+
本例子中我们只使用+*()
优先级从高到低为:(*+
解法:
基本原则:
1.当读到一个数的时候,立即把它放到输出中。
2.当读到一个操作符时,进栈而不是放到输出中,当遇到"("(右括号、开括号)时我们也要将其推入栈中。
3.如果遇到一个右括号"(",就将栈元素弹出,直到遇到左括号")",但是左括号只被弹出,并不输出。
## 标题4.如果遇到符号("+"、"*"、"("),我们就从栈中弹出直到发现优先级更低的元素为止(即:弹出优先级高的符号);
当从栈弹出元素的工作完成后,我们再将这个操作符压入栈中。
5.有一个例外,除非是在处理一个")"的时候,否则绝对不从栈中移走"("。
6.最后,如果读到输入的末尾,我们将栈元素弹出直到该栈变成空栈,将符号写到输出中。
时间:只需要O(N)时间并经过一趟输入后运算即可完成
改进:可以通过指定减法和加法有相同的优先级以及乘法和除法有相同的优先级,而将减法和除法添加到指令集中
一种巧妙的想法是将表达式“a-b-c”转换成“a b - c -”而不是转换成“a b c --”