数据结构—栈的实现及实战应用

今天主要学习了下栈,下面对所学习到关于栈的知识进行下汇总:
首先,栈是一种特殊的线性表,相对于线性表,栈仅能在一端进行操作,所以在我们的栈的实现过程中,完全可以复用线性表的程序,对其进行封装下,达到能满足我们要求的栈的程序。
下面介绍下栈中的两个概念:
栈顶(Top):允许操作的一端
栈底(Bottom):不允许操作的一端
对于栈的性质,我想接触过计算机基础的同学都知道,先进后出嘛。(LIFO:last in first out)

通常栈有两种实现方式:顺序结构和链式结构
首先来顺序结构栈的一些常用操作(借用顺序线性表的代码直接实现出来):
创建栈

SeqStack* SeqStack_Create(int capacity)
{
  return SeqList_Create(capacity);
}

销毁栈

void SeqStack_Destroy(SeqStack* stack)
{
  SeqList_Destroy(stack);
}

清空栈

void SeqStack_Clear(SeqStack* Stack)
{
  SeqList_Clear(Stack);
}

进栈

int SeqStack_Push(SeqStack* stack,void* item)
{
  return SeqList_Insert(stack,item,SeqList_Length(stack));
}

出栈

void* SeqStack_Pop(SeqStack* stack)
{
 return SeqList_Delete(stack,SeqList_Length(stack) - 1);    
}

获取栈顶元素

void* SeqStack_Top(SeqStack* stack)
{
 return SeqList_Get(stack,SeqList_Length(stack) - 1);   
}

获取栈的大小

int SeqStack_Size(SeqStack* stack)
{
 return SeqList_Length(stack);
}

再来借用链式结构表对链式结构栈的常用操作进行实现:
链式结构表的实现:https://code.csdn.net/snippets/2438351.git

#include <malloc.h>
#include "LinkStack.h"
#include "LinkList.h"

typedef struct _tag_LinkStack
{
 LinkListNode header;
 void* item;
}TLinkStackNode;
LinkStack* LinkStack_Create()
{
 return LinkList_Create();
}

void LinkStack_Destroy(LinkStack* stack)
{   
    LinkStack_Clear();
    LinkList_Destroy(stack);
}

void LinkStack_Clear(LinkStack* stack)
{
 while( LinkStack_Size(stack) > 0)
 {
  LinkStack_Pop(stack);     
 }
}

int LinkStack_Push(LinkStack* stack,void* item)
{
 TLinkStackNode* node = (TLinkStackNode*)malloc(sizeof(TLinkStackNode));
 int ret = (node != NULL) && (item != NULL);
 if( ret )
 {
  node->item = item;

  ret = LinkList_Insert(stack,(LinkListNode*)node,0);       
 }
 if( !ret )
 {
  free(node);        
 }  

 return ret;
}

void* LinkStack_Pop(LinkStack* stack)
{
 TLinkStackNode* node = (TLinkStackNode*)LinkList_Delete(stack,0);
 void* ret = NULL; 
 if( node != NULL)
 {
  ret = node->item;
  free(node);       
 }
 return ret;
}

void* LinkStack_Top(LinkStack* stack)
{
 TLinkStackNode* node = (TLinkStackNode*)LinkList_Get(stack,0);
 void* ret = NULL; 
 if( node != NULL)
 {
  ret = node->item;     
 }
 return ret;
}

int LinkStack_Size(LinkStack* stack)
{
  return LinkList_Length(stack);
}

实现方式都贴出来了,怎么能少了应用呢。
在我们的学习中,少不了编译器的使用,当然,几乎所有的编译器都具有检测括号是否匹配的功能。下面就用链式结构的栈来实现下编译器中的检测括号功能。
如何实现编译器中的符号成对检测功能,作为个编程人员,必要的算法必不可少,那么编译器检测括号的的算法是怎样的呢,我们来整理下思路:
算法思路:
从第一个字符开始扫描
当遇见普通字符时忽略,当遇见左符号时压入栈中
当遇见右符号时从栈中弹出栈顶符号
进行匹配
匹配成功:继续读入下一个字符
匹配失败:立即停止,并报错
结束:
成功:所有字符扫描完毕,且栈为空
失败:匹配失败或所有字符扫描完毕但栈非空
实现代码如下(链式栈与链式结构的实现都在在上面):

#include 
#include 
#include "LinkStack.h"

int isLeft(char c)
{
 int ret = 0;
 switch(c)
 {
  case '[': 
  case '(': 
  case '{': 
  case '\'':    
  case '\"':    
  case '<': 
    ret = 1;
    break;
  default:
    ret = 0;
    break;  
 }
 return ret;
}

int isRight(char c)
{
 int ret = 0;
 switch(c)
 {
  case ']': 
  case ')': 
  case '}': 
  case '\'':    
  case '\"':    
  case '>': 
    ret = 1;
    break;
  default:
    ret = 0;
    break;  
 }
 return ret;
}

int match(char left,char right)
{
 int ret = 0;   
 switch(left)
 {
  case '[': 
        ret = (right == ']');
        break;
  case '(':
        ret = (right == ')');
        break;  
  case '{':
        ret = (right == '}');
        break;  
  case '\'':
        ret = (right == '\'');
        break;  
  case '\"':
        ret = (right == '\"');
        break;  
  case '<': 
        ret = (right == '>');
        break;
  default:
    ret = 0;
    break;  
 }
 return ret;    
}

int scanner(const char* code)
{
  LinkStack* stack = LinkStack_Create();
  int ret = 0;
  int i = 0;
  while( code[i] != '\0')
  {
   if( isLeft(code[i])) 
   {
   LinkStack_Push(stack,(void*)(code + i));     
   }
   if( isRight(code[i]))    
   {
    char* c = (char*)LinkStack_Pop(stack);

    if((c == NULL) || !match(*c,code[i]))
    {
    printf("%c does not match\n",code[i]);
    ret = 0;
    break;      
    }       
   }
   i++;
  }

  if( (LinkStack_Size(stack) == 0) && (code[i] == '\0') )
  {
  printf("Succeed!\n"); 
  ret = 1;  
  }
  else 
  {
  printf("Invailed code!\n");
  ret = 0;          
  }
  LinkStack_Destroy(stack);

  return ret;
}
int main(int argc, char *argv[]) 
{
    const char* code = "int main()  {int (*p[5],p = NULL;return 0;}";
    scanner(code);
    return 0;
}    

你可能感兴趣的:(栈,栈的基本操作,c)