栈
携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第3天,点击查看活动详情
栈的基本概念
栈的定义
栈(Stack)是只允许在一端进行插入或删除操作的线性表。首先栈是一种线性表,但限定这种线性表只能在某一端进行插入和删除操作。 栈顶(Top)。线性表允许进行插入删除的那一端。 栈底(Bottom)。固定的,不允许进行插入和删除的另一端。 空栈。不含任何元素的空表。
栈的基本操作
InitStack(&S)//初始化一个空栈s。
StackEmpty(S)//判断一个栈是否为空,若栈s为空则返回true,否则返回fa1se
Push(&S,x)//进栈,若栈s未满,则将x加入使之成为新栈顶。
Pop(&S,&x)//出栈,若栈s非空,则弹出栈顶元素,并用x返回。
GetTop(S,&x)//读栈顶元素,若栈s非空,则用x返回栈顶元素。
Destroystack(&S)//销毁栈,并释放栈s占用的存储空间(“&”表示引用调用)
- 初始化
void InitStack(SqStack &S){
S.top=-1;//初始化栈顶指针
}
- 判栈空
bool StackEmpty(SqStack S){
if(S.top==-1)//栈空
return true;
else//不空
return false;
}
- 进栈
bool Push(SqStack &S,Elemrype x){
if(S.top==MaxSize-1)//栈满,报错
return false;
s.data[++S.top]=x;//指针先加1,再入栈
return true;
}
- 出栈
bool Pop(SqStack &S,ElemType &x){
if(S.top==-1)//栈空,报错
return false;
x=S.data[S.top--];//先出栈,指针再减1
return true;
- 出栈
bool Pop(SqStack &S,ElemType &x){
if(S.top==-1)//栈空,报错
return false;
x=S.data[S.top--];//先出栈,指针再减1
return true;
栈的链式存储结构同理,不再赘述。
应用题
设单链表的表头指针为L,结点结构由 data和next两个域构成,其中data域为字符型。试设计算法判断该链表的全部n个字符是否中心对称。例如xyx、xyyx都是中心对称。
- 算法思想:使用栈来判断链表中的数据是否中心对称站链表的前一半元素依次进栈。在处理链表的后一半元素时,当访问到链表的一个元素后,就从栈中弹出一个元素;两个元素比较,若相等,则将链表中的下一个元素与栈中再弹出的元素比较,直至链表到尾。这时若栈是空栈,则得出链表中心对称的结论;否则,当链表中的一个元素与栈中弹出元素不等时,结论为链表非中心对称,结束算法的执行。
int dc(LinkList L,int n){
//L是带头结点的n个元素单链表,本算法判断链表是否是中心对称
int i;
char s[n/2];//s字符栈
p=L->next;//p是链表的工作指针,指向待处理的当前元素
for(i=0;i<n/2;i++){//链表前一半元素进栈
s[i]=p->data;
p=p->next;
}
i--;//恢复最后的i值
if(n%2==1)//若n是奇数,后移过中心结点
p=p->next;
while(p!=NULL&&s[i]==p->data){//检测是否中心对称
i--;//i充当栈顶指针
p=p->next;
}
if(i==-1)//栈为空栈
return 1;//链表中心对称
else
return 0;//链表不中心对称
}
算法先将“链表的前一半”元素(字符)进栈。当n为偶数时,前一半和后一半的个数相同;当n为奇数时,链表中心结点字符不必比较,移动链表指针到下一字符开始比较。比较过程中遇到不相等时,立即退出while循环,不再进行比较。