要计算后缀表达式:应从右向左“扫描”,逐个处理运算符和运算符号。可使用堆栈储存运算数,在需要时“倒序”输出。 堆栈(Stack):具有一定操作约束的线性表,只在一端(栈顶,Top)做插入、删除。 数据对象集:一个由0个或多个元素的有穷线性表; (1)入栈 (2)出栈 eg:用一个数组实现两个堆栈,要求最大的利用数组空间,使数组只要有空间入栈操作就可以成功。 (1)堆栈初始化(建立空栈) (3)将元素item压入堆栈S (4)删除并返回堆栈S的栈顶元素 可将中缀表达式转换为后缀表达式: 下面是一个将中缀表达式转换为后缀表达式的栗子: 队列(Queue):具有一定操作约束的线性表 数据对象集:一个有0个或多个元素的有穷线性表。 在循环队列中只存放MaxSize-1个元素(此时认为队列已满) (2)出队列 (1)不带头结点的链式队列的出队操作
一、后缀表达式
二、堆栈
操作集:长度为MaxSize的堆栈S和堆栈元素item。
栈的顺序存储结构通常是由一个一维数组和一个记录栈顶元素位置的变量组成。如下:#define MaxSize //储存数据元素的最大个数 typedef struct SNode *Stack;//结构指针 struct SNode { ElementType Data[MaxSize]; int Top; }
void Push(Stack PtrS,ElementType item) { if(PtrS->Top == MaxSize-1) { printf("堆栈满"); return; } else { ptrS->Data[++(PtrS->Top)] = item; //等于执行(PtrS->Top)++; //PtrS->Data[PtrS->Top] = item; return; } }
ElementType Pop(Stack PtrS) { if(PtrS->Top == -1) { printf("堆栈空"); return ERROR; //ERROR是ElementType的特殊值,标志错误 } else { return (PtrS->Data[(PtrS->Top)--]); } }
我们就可以让这两个栈分别从数组的两头开始向中间生长;当两个栈的栈顶指针相遇时,表示这两个栈都满了。#define MaxSize //存储数据元素的最大个数 struct DStack { ElementType Data[MaxSize]; int Top1; //堆栈1的栈顶指针 int Top2; //堆栈2的栈顶指针 }S; S.Top1 = -1; S.Top2 = MaxSize;
void Push(struct DStack *PtrS, ElementType item, int Tag)//Tag作为区分两个堆栈的标志,取值为1,2 { if(PtrS->Top2 - PtrS->Top1 == 1)//堆栈满 { printf("堆栈满"); return; } if(Tag == 1) //对第一个栈操作 { PtrS->Data[++(PtrS->Top1)] = item; } else //对第二个栈操作 { PtrS->Data[--(PrtS->Top2)] = item; } }
ElementType Pop(struct DStack * PtrS, int Tag) { if(Tag == 1) //对第一个堆栈操作 { if(PtrS->Top1 == -1) { printf("堆栈1空"); return; } else { return PtrS->Data[(PtrS->Top1)--]; } } else //对第二个堆栈操作 { if(PtrS->Top2 == MaxSize) { printf("堆栈2空"); } else { return PtrS->Data[(PtrS->Top2)++]; } } }
栈的链式存储结构实际上就是一个单链表,叫做链栈。插入和删除操作只能在链栈的栈顶进行。栈顶的指针Top应该为链表的头。typedef struct SNode *Stack; struct SNode { ElementType Data; struct SNode * Next; };
(2)判断堆栈s是否为空Stack CreateStack()//构建一个堆栈的头结点,返回指针 { Stack S; S = (Stack)malloc(sizeof(struct SNode)); S->Next = NULL; return S; } int IsEmpty(Stack S)//判断堆栈S是否为空,若为空,函数返回整数1,否则返回0 { return (S->Next == NULL); }
void Push(ElementType item, Stack S) { struct SNode *TmpCell; TmpCell = (struct SNode *)malloc(sizeof(struct SNode)); TmpCell->ElementType = item; TmpCell->Next = S->Next; S->Next = TmpCell; }
ElementType Pop(Stack S) { struct SNode *FirstCell; ElementType TopElem; if(IsEmpty(S)) { printf("堆栈空"); return NULL; } else { FirstCell = S->Next; S->Next = FirstCell->Next; TopElem = FirstCell->Element; free(FirstCell); return TopElem; } }
三、应用于中缀表达式求值
从头到尾读取中缀表达式的每个对象,对不同对象按不同的情况处理。
堆栈的其他应用:
四、队列
插入和删除操作:只能在一端插入,在另一端删除。
操作集:长度为MaxSize的队列Q,队列元素item。
队列的顺序存储结构通常是由一个一维数组和一个记录队列头元素的位置变量front以及一个记录队列尾元素位置的rear组成。#define MaxSize //储存数据元素的最大个数 struct QNode { ElementType Data[MaxSize]; int rear; int front; }; typedef struct QNode *Queue;
(1)入队列void AddQ(Queue PtrQ, ElementType item) { if((PtrQ->rear + 1) % MaxSize == PtrQ->front) { printf("队列满"); return; } PtrQ->rear = (PtrQ->rear + 1) % MaxSize; ptrQ->Data[PtrQ->rear] = item; }
ElemnetType DeleteQ(Queue PtrQ) { if(PtrQ->front == PtrQ->rear) { printf("队列空"); return ERROR; } else { PtrQ->front = (PtrQ->front + 1) % MaxSize; return PtrQ->Data[PtrQ->front]; } }
队列的链式存储结构也可以用一个单链表实现。插入和删除操作分别在链表的两头进行;队列指针front应该指向链表的头部,rear应该指向链表的尾部。struct Node { ElementType Data; struct Node * Next; }; struct QNode //链队列结构 { struct Node *front; //指向队头结点 struct Node *rear; //指向队尾结点 }; typedef struct QNode *Queue; Queue PtrQ;
ElementType DeleteQ(Queue PtrQ) { struct Node *FrontCell; ElementType FrontElem; if(PtrQ->front == NULL) { printf("队列空"); return ERROR; } FrontCell = PtrQ->front; if(PtrQ->front == PtrQ->rear) //若队列中只有一个元素 { PtrQ->front = PtrQ->rear = NULL;//删除后队列置为空 } else { PtrQ->front = PtrQ->front->Next; } FrontElem = FrontCell->Data; free(FrontCell); //释放被删除结点空间 return FrontElem; }
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算