1. 栈的定义:
栈:只允许从一端进行数据的插入和删除,具有一对一线性的存储结构(先进后出,后进先出,FILO)
栈的插入操作:叫做进栈,也称压栈、入栈
栈的删除操作:叫做出栈,也有的叫作弹栈
2. 线性存储结构:
1. 顺序栈:
满栈:栈顶所在位置有元素,插入时,先移动栈顶,到下一个入栈位置,再插入数据,空栈相反
2. 链式栈:
1. 栈的定义:
#ifndef _STACK_H_
#define _STACK_H_
#if 0
typedef struct data
{
int id;
char name[32];
int score;
}DATA_TYPE;
#endif
typedef int DATA_TYPE;
typedef struct node
{
DATA_TYPE data;
struct node *pnext;
}STACK_NODE;
typedef struct list
{
STACK_NODE *ptop;
int curlen;
}STACK_LIST;
#endif
2. 栈的句柄的创建:
STACK_LIST *Create_Stack_List(void)
{
STACK_LIST *plist = malloc(sizeof(STACK_LIST));
if(plist == NULL)
{
perror("fail to malloc");
return NULL;
}
plist->ptop = NULL;
plist->curlen = 0;
return plist;
}
3. 入栈操作(头插):
int Into_Stack(STACK_LIST *plist, DATA_TYPE data)
{
STACK_NODE *pnode = malloc(sizeof(STACK_NODE));
if(pnode == NULL)
{
perror("fail to malloc");
return -1;
}
//memcpy(&pnode->data, &data, sizeof(DATA_TYPE));
pnode->data = data;
pnode->pnext = NULL;
pnode->pnext = plist->ptop;
plist->ptop = pnode;
plist->curlen++;
return 0;
}
4. 出栈操作(头删):
int Out_of_Stack(STACK_LIST *plist, DATA_TYPE *data)
{
STACK_NODE *ptmp = plist->ptop;
if(Is_Empty_Stack(plist))
{
return 0;
}
else
{
plist->ptop = ptmp->pnext;
if(data != NULL)
{
//memcpy(data, &ptmp->data, sizeof(DATA_TYPE));
*data = ptmp->data;
}
free(ptmp);
}
plist->curlen--;
return 0;
}
5. 获得栈顶数据:
int Get_Top_Stack(STACK_LIST *plist, DATA_TYPE *data)
{
if(Is_Empty_Stack(plist))
{
return 0;
}
else
{
//memcpy(data, &plist->ptop->data, sizeof(DATA_TYPE));
*data = plist->ptop->data;
return 0;
}
return -1;
}
6. 清空栈:
void Empty_Stack(STACK_LIST *plist)
{
STACK_NODE *pfree = plist->ptop;
while(plist->ptop != NULL)
{
plist->ptop = pfree->pnext;
free(pfree);
plist->curlen--;
pfree = plist->ptop;
}
return;
}
7. 销毁栈:
void Destroy_Stack(STACK_LIST *plist)
{
Empty_Stack(plist);
free(plist);
return;
}
练习:栈的四则运算:
int Is_Num_Str(char str)
{
if(str >= '0' && str <= '9')
{
return 1;
}
return 0;
}
int Priority_Option(char opt)
{
switch(opt)
{
case '+':
case '-': return 1;
case '*':
case '/': return 2;
}
}
int Get_Value(int opt, int num1, int num2)
{
switch(opt)
{
case '+': return num1 + num2;
case '-': return num1 - num2;
case '*': return num1 * num2;
case '/': return num1 / num2;
}
}
int main(void)
{
int sum = 0;
int res = 0;
char *pstr = NULL;
char formula[256] = {0};
fgets(formula, sizeof(formula), stdin);
formula[strlen(formula) - 1] = '\0';
pstr = formula;
STACK_LIST *pStackNum = Create_Stack_List();
STACK_LIST *pStackOpt = Create_Stack_List();
DATA_TYPE popOpt;
DATA_TYPE opt, num1, num2;
while(1)
{
if(*pstr == '\0' && Is_Empty_Stack(pStackOpt))
{
break;
}
while(Is_Num_Str(*pstr))
{
sum = sum * 10 + (*pstr - '0');
pstr++;
if(!Is_Num_Str(*pstr))
{
Into_Stack(pStackNum, sum);
sum = 0;
}
}
if(Is_Empty_Stack(pStackOpt))
{
Into_Stack(pStackOpt, *pstr);
pstr++;
continue;
}
Get_Top_Stack(pStackOpt, &popOpt);
if(*pstr != '\0' && Priority_Option(*pstr) > Priority_Option(popOpt))
{
Into_Stack(pStackOpt, *pstr);
pstr++;
}
else
{
Out_of_Stack(pStackOpt, &opt);
Out_of_Stack(pStackNum, &num2);
Out_of_Stack(pStackNum, &num1);
res = Get_Value(opt, num1, num2);
Into_Stack(pStackNum, res);
}
}
Out_of_Stack(pStackNum, &res);
printf("res = %d\n", res);
Destroy_Stack(pStackNum);
Destroy_Stack(pStackOpt);
return 0;
}