标签:转换 个数 返回 大括号 post 记录 alt ges 删除
栈是一种只能在一端进行插入或者删除操作的线性表,其中允许进行插入或删除的一端称为栈顶。
typedef struct
{
int data[MaxSize];
int top;
}SqStack;
对于一个顺序栈st,一共有 4个要素,包括两个特殊的状态和两个操作:
st.top==-1;
st.top==MaxSize-1;
++(st.top); st.data[top]=x;
x=st.data[top]; --(st.top);
顺序栈的几个基本操作(详细版):
初始化栈
void initStack(SqStack &st)
{
st.top=-1;
}
判断栈空
bool isEmpty(SqStack st)
{
if(st.top==-1)
return true;
else
return false;
}
判断栈满
bool isFull(SqStack st)
{
if(st.top==MaxSize-1)
return true;
else
return false;
}
进栈算法
bool push(SqStack &st,int x)
{
if(isFull(st))
return false;
++st.top;
st.data[st.top]=x;
return true;
}
出栈算法
bool pop(SqStack &st,int &x)
{
if(isEmpty(st))
return false;
x=st.data[st.top];
--st.top;
return true;
}
在实际的题目中初始化栈、进栈以及出栈不必写的上述那么详细
初始化栈int stack[MaxSize]; int top==-1;
元素 x 进栈stack[++top]=x;
元素 x 出栈x=stack[top--];
typedef struct linkLode
{
int data;
struct linkLode*next;
}LiStack;
对于一个有带头节点的链栈 ls ,也包括 4 个要素,包括两个状态和两个操作:
ls->next==NULL;
两个操作
元素(指针ptr指向)进栈操作,即为头插法
ptr->next=ls->next;
ls->next=ptr;
出栈操作
ptr=ls->next;
x=ptr->data;
ls->next=ptr->next;
free(ptr);
ptr=NULL;
两个栈共享一个数组A[0..MaxSize-1]的空间,数组 A 两端都是栈底,栈顶向中间生长
左边栈的 4 要素为:
top1==-1
top1==top2-1
++top1; A[top1]=x;
x=A[top1]; --top1;
右边栈的 4 要素为:
top2==MaxSize
top2==top1+1
--top2; A[top2]=x;
x=A[top2]; ++top2;
如果要解决的问题出现了这样一个状态:单凭现有的条件不能判断当前的状态是否可以解决,此时需要记录一些东西,等待以后出现可以解决当前状态的条件后返回来再解决。这种问题往往可以使用栈来解决。
假设表达式中允许包括 3种括号:圆括号、方括号、和大括号。设计一个算法采用顺序栈判断表达式中括号是否正确匹配。
bool match(char exp[],int n)
{
char st[MaxSize];
int top=-1;
bool flag=true;
int i=0;
while(i<n && flag==true)
{
if(exp[i]==‘(‘|| exp[i]=‘[‘||exp[i]=‘{‘)
{
++top; st[top]=exp[i];
}
if(exp[i]==‘)‘)
{
if(st[top]==‘(‘) --top;
else flag=false;
}
if(exp[i]==‘]‘)
{
if(st[top]==‘[‘) --top;
else flag=false;
}
if(exp[i]==‘}‘)
{
if(st[top]==‘{‘) --top;
else flag=false;
}
i++;
}
if(top>=0) flag=false;
return flag;
}
有一个带头结点的单链表 L ,用于存放整数序列,设计一个算法判断该序列是否是对称的。
bool symtry(LinkList *L)
{
int st[MaxSize];
int top=-1;
LinkList *ptr=L->next;
while(ptr!=NULL)
{
++top;
st[top]=ptr->data;
ptr=ptr->next;
}
ptr=L->next;
while(ptr!=NULL)
{
if(ptr->data==st[top])
--top;
else
return flase;
ptr=ptr->next;
}
return true;
}
编写一个算法,将一个非负的十进制数 N 转换为一个二进制数。
int trans(int N)
{
int stack[MaxSize},top=-1;
int i,result=0;
while(N!=0)
{
i=N%2;
N=N/2;
stack[++top]=i;
}
while(top!=-1)//可以根据需求改变
{
i=stack[top];
--top;
result=result*10+i;
}
return result;
}
后缀表达式是没有了括号并考虑了运算符优先级的一种表达式。将算术表达式 exp 转换为后缀表达式 postexp 的基本思想是:采用运算符栈比较运算符的优先级,所有运算符必须进栈,只将大于栈顶优先级的运算符直接进栈,否则需要退栈栈顶运算符(先退栈的先计算,同优先级的运算符在栈中的先计算)
采用运算符栈:
while(从 exp 中循环读取字符 ch)
{
ch 为数字: 将后续的所有数字均依次存放到 postexp中。
ch 为左括号"(": 将其放入到运算符栈op中。
ch 为右括号$")"$: 将栈op中左括号"("以前的运算符依次出栈并存放到postexp中,然后将左括号"("出栈。
ch 的优先级大于栈op的栈顶运算符的优先级或栈顶为"(":将ch进栈,否则依次退掉栈顶优先级大于或同级运算符到postexp中,然后将ch进栈。
}
将栈op中的所以运算符出栈并存放到postexp中,最后得到后缀表达式。
手工方法:需要人工判断表达式的执行顺序(即加括号),所以无法用程序实现
以5+2*(1+6)-8/2
为例说明以中缀表达式变成后缀表达式:
?
对后缀表达式postexp求值
while(从postexp中循环读取所有的字符ch)
{
ch 为数字:进到数值栈st中;
ch 为"+":从数值栈st中退两个运算数,相加后进数值栈st中;
ch 为"-":从数值栈st中退两个运算数,相加后进数值栈st中;
ch 为"*":从数值栈st中退两个运算数,相加后进数值栈st中;
ch 为"/":从数值栈st中退两个运算数,相加后进数值栈st中(若除数为0,则提示错误信息);
}
队列是一种插入和删除操作受限的线性表,其插入和删除操作在不同端进行,插入元素的一端为队尾,删除元素的一端为队头。
队列中一般使用 font 和 rear 来指示队头和队尾,front 指向队列中队首元素的前一个位置,rear 指向队尾元素,因此:
rear++;
再将元素放到 rear 位置front++;
再取出队头元素typedef struct
{
int data[MaxSize];
int front,rear;
}SqQueue;
进队操作进队操作是先将
rear++;
再将元素放到 rear 位置;出队操作是先将队头front++;
再取出队头元素。这样导致队头和队尾指针只增加不减少,被出队的空间无法再使用。于是通过逻辑方法改为首尾相连的循环队列可以反复利用已经出队的空间。
qu.front==qu.rear
(rear+1)%MaxSize==qu.front
qu.rear=(qu.rear+1)%MaxSize; qu.data[rear]=x;
qu.front=(qu.front+1)%MaxSize; x=qu.data[front];
(qu.rear-qu.front+MaxSize)%MaxSize;
队列的基本运算(详细)
初始化队
void initQueue(SqQueue & qu)
{
qu.front=qu.rear=0;
}
判断队空
bool isEmpty(SqQueue qu)
{
if(qu.front==qu.rear)
return true;
else
return false;
}
进队
bool enQueue(SqQueue &qu,int x)
{
if((qu.rear+1)%MaxSize == qu.front)//是否队满
return false;
qu.rear = (qu.rear+1)%MaxSize;
qu.data[qu.rear] = x;
return true;
}
出队
bool deQueue(SqQueue &qu,int &x)
{
if(qu.rear == qu.front)//是否队空
return false;
qu.front = (qu.front+1)%MaxSize;
x = qu.data[qu.front];
return true;
}
struct qnode
{
int data;
struct qnode * next;
}QNode;
typedef struct
{
QNode *front; //队头指针
QNode *rear; //队尾指针
}LiQueue;
qu->font==NULL;或 qu->rear==NULL
bool isEmpty(LiQueue *lqu)
{
if(lqu->rear==NULL || lqu->front==NULL)
return true;
else
return false;
}
进队:要考虑原来队空操作
void enQueue(LiQueue *lqu,int x)
{
QNode *ptr;
ptr=(QNode*)malloc(sizeof(QNode));
ptr->data=x;
ptr->next=NULL;
if(lqu->rear==NULL)
lqu->front=lqu->rear=ptr;
else
{
lqu->rear->next=ptr;
lqu->rear=ptr;
}
}
出队:要考虑队空和只有一个节点
bool deQueue(LiQueue *lqu,int &x)
{
QNode *ptr;
if(lqu->rear==NULL) //队空
return false;
else
ptr=lqu->front;
if(lqu->rear==lqu->front) //只有一个元素
lqu->front=lqu->rear=NULL;
else
lqu->front=ptr->next;
x=ptr->data;
free(ptr);
ptr=NULL;
return true;
}
双端队列是指两端都可以进行进队和出队操作的的队列
?
标签:转换 个数 返回 大括号 post 记录 alt ges 删除
原文地址:http://www.cnblogs.com/halox/p/zhan.html