浙江中医药大学-《数据结构》-栈和队列算法设计

ZCMU-Data Structure-Stack and Queue
1、从键盘上输入一个后缀表达式,试编写算法计算表达式的值。规定:逆波兰表达式的长度不超过一行,以$符作为输入结束,操作数之间用空格分隔,操作符只可能有+、-、*、/四种运算。例如:234 34+2*$。

思路:逆波兰表达式(即后缀表达式)求值规则如下:设立运算数栈OPND,对表达式从左到右扫描(读入),当表达式中扫描到数时,压入OPND栈。当扫描到运算符时,从OPND退出两个数,进行相应运算,结果再压入OPND栈。这个过程一直进行到读出表达式结束符$,这时OPND栈中只有一个数,就是结果。

float expr( )
//从键盘输入逆波兰表达式,以‘$’表示输入结束,本算法求逆波兰式表达式的值。
{float OPND[30];   // OPND是操作数栈。
init(OPND);       //两栈初始化。
float num=0.0;    //数字初始化。
cin>>x;//x是字符型变量。
while(x!=’$’)
 	{switch
      {case‘0’<=x<=’9’:
while((x>=’0’&&x<=’9’)||x==’.’)  //拼数
if(x!=’.’)   //处理整数
{num=num*10+(ord(x)-ord(‘0’)); cin>>x;}
else           //处理小数部分。
{scale=10.0; cin>>x;
while(x>=’0’&&x<=’9’)
{num=num+(ord(x)-ord(‘0’)/scale;
scale=scale*10;  cin>>x; }
}//else
push(OPND,num); num=0.0;//数压入栈,下个数初始化
       case x=‘ ’:break;  //遇空格,继续读下一个字符。
       case x=‘+’:push(OPND,pop(OPND)+pop(OPND));break;
       case x=‘-’:x1=pop(OPND);x2=pop(OPND);push(OPND,x2-x1);break;
       case x=‘*’:push(OPND,pop(OPND)*pop(OPND));break;
       case x=‘/’:x1=pop(OPND);x2=pop(OPND);push(OPND,x2/x1);break;
       default:       //其它符号不作处理。
     }//结束switch
     cin>>x;//读入表达式中下一个字符。
   }//结束while(x!=‘$’)
cout<<“后缀表达式的值为”<<pop(OPND);
}//算法结束。

2、已知f为单链表的表头指针, 链表中存储的都是整型数据,试写出实现下列运算的递归算法:     

① 求链表中的最大整数;

② 求链表的结点个数;

③ 求所有整数的平均值。

①
int GetMax(LinkList p)
{
	if(!p->next)	
		return p->data;
	else
	{
		int max=GetMax(p->next);
		return p->data>=max ? p->data:max;
	}
}
②
int GetLength(LinkList p)
{
	if(!p->next)
		return 1;
	else
	{
		return GetLength(p->next)+1;
	}
}
③
double GetAverage(LinkList p , int n)
{
	if(!p->next)
		return p->data;
	else
	{
		double ave=GetAverage(p->next,n-1);
		return (ave*(n-1)+p->data)/n;
	}
}
3、假设以带头结点的循环链表表示队列,并且只设一个指针指向队尾元素站点(注意不设头指针) ,试编写相应的置空队、判队空 、入队和出队等算法。

思路:置空队就是建立一个头节点,并把头尾指针都指向头节点,头节点是不存放数据的;判队空就是当头指针等于尾指针时,队空;入队时,将新的节点插入到链队列的尾部,同时将尾指针指向这个节点;出队时,删除的是队头节点,要注意队列的长度大于1还是等于1的情况,这个时候要注意尾指针的修改,如果等于1,则要删除尾指针指向的节点。

//先定义链队结构:
typedef struct queuenode
{Datatype data;
struct queuenode *next;
}QueueNode; //以上是结点类型的定义
typedef struct
{queuenode *rear;
}LinkQueue; //只设一个指向队尾元素的指针

(1)	置空队
void InitQueue( LinkQueue *Q)
{ //置空队:就是使头结点成为队尾元素
 QueueNode *s;
Q->rear = Q->rear->next;//将队尾指针指向头结点
while (Q->rear!=Q->rear->next)//当队列非空,将队中元素逐个出队
{s=Q->rear->next;
Q->rear->next=s->next;
delete s;
 }//回收结点空间
}

(2)	判队空 
int EmptyQueue( LinkQueue *Q)
{ //判队空。当头结点的next指针指向自己时为空队
 return Q->rear->next->next==Q->rear->next;
}

(3)	入队
void EnQueue( LinkQueue *Q, Datatype x)
{ //入队。也就是在尾结点处插入元素
QueueNode *p=new QueueNode;//申请新结点
p->data=x; p->next=Q->rear->next;//初始化新结点并链入
Q-rear->next=p; 
Q->rear=p;//将尾指针移至新结点
}

(4)	出队
Datatype DeQueue( LinkQueue *Q)
{//出队,把头结点之后的元素摘下
Datatype t;
QueueNode *p;
if(EmptyQueue( Q ))
Error("Queue underflow");
p=Q->rear->next->next; //p指向将要摘下的结点
x=p->data; //保存结点中数据
if (p==Q->rear)
{//当队列中只有一个结点时,p结点出队后,要将队尾指针指向头结点
 Q->rear = Q->rear->next; 
Q->rear->next=p->next;
}
else 
Q->rear->next->next=p->next;//摘下结点p
delete p;//释放被删结点
return x;
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值