栈和队列是在软件设计中常用的两种数据结构,它们的逻辑结构和线性表相同。
其特点在于运算受到了限制:栈按“后进先出”的规则进行操作,队按“先进先出”的规则进行操作,故称运算受限制的线性表。
从数据类型的角度看: 它们和线性表不同
插入 删除
线性表 Insert(L, i, x) Delete(L, i)
(1<=i<=n+1) (1<=i<=n)
栈 Insert(S, n+1, x) Delete(S, n)
队列 Insert(Q, n+1, x) Delete(Q, 1)
栈【定义】是限定仅在表尾进行插入或删除操作的线性表
允许插入、删除的这一端称为栈顶top
另一个固定端称为栈底bottom。
#define STACK_INIT_SIZE 100
#define STACKINCREAMENT 10
typedef int SElemType;
typedef int Status;
typedef struct
{
SElemType *base;
SElemType *top;
int stacksize;
}SqStack;
说明
top指向栈顶元素的下一个位置,即待接收数据的位置
top= base 空栈
top=base+stacksize 栈满 补添存储
//顺序栈的初始化
Status InitStack(SqStack &s)
{
s.base = (SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType));
if(!s.base)
exit(OVERFLOW);
s.top = s.base;
s.stacksize = STACK_INIT_SIZE;
return OK;
}
//取栈顶元素
Status GetTop(SqStack s,SElemType &e ) {
if (s.top==s.base) return ERROR;
e=*(s.top-1);
return OK;
} // GetTop
出栈和取栈顶元,先判栈是否为空
为空时不能操作,否则产生错误。
通常栈空作为一种控制转移的条件
//顺序栈入栈
Status Push(SqStack &s,SElemType e)
{
if(s.top - s.base >= s.stacksize)
{
s.base = (SElemType *)realloc(s.base,(s.stacksize + STACKINCREAMENT)*sizeof(SElemType));
if(!s.base) exit(OVERFLOW);
s.top = s.base + s.stacksize;
s.stacksize += STACKINCREAMENT;
}
*s.top++=e;
return OK;
}
对于顺序栈,入栈时先判栈是否满了,栈满时不能入栈; 否则出现空间溢出,引起错误,这种现象称为上溢。
//顺序栈出栈
Status Pop(SqStack &s,SElemType &e)
{
if(s.top == s.base) return ERROR;
e = *--s.top;
return OK;
}
//顺序栈判空
Status StackEmpty(SqStack s)
{
if(s.top == s.base) return TRUE;
else
{
return FALSE;
}
}
算法思想 当N>0时重复1)、2)
1)若 N≠0,则将N%d 压入栈s中,执行2);
若N=0,将栈s的内容依次出栈,算法结束。
2)用N/d 代替 N
//进制转换
void Converse(int N,int d)
{
char z = 'A';
SqStack s;
int e;
InitStack(s);
if(N==0)
cout<<N;
else{
while(N)
{
Push(s,N%d);
N = N/d;
}
while(!StackEmpty(s))
{
Pop(s,e);
if((e>=10)&&e<=15)
printf("%c",z+e-10);
else
printf("%d",e);
}
}
}
//主函数
int main()
{
SqStack s;
InitStack(s);
int N,d;
printf("请输入一个非负十进制数及想要转换为多少进制?\n");
scanf("%d",&N);
scanf("%d",&d);
Converse(N,d);
return 0;
}