一、栈
1.定义:栈是限定仅在表尾进行插入和删除操作的线性表。先进后出、后进先出。
2.栈顶(top):允许操作的一端 栈底(bottom):不允许操作的一端
3.栈的插入操作叫做进栈,也叫压栈、入栈;栈的删除操作叫做出站,也叫弹栈。
注:链式结构只支持头删和头插
4.栈的一般操作
(1).创建 CreateSeqStack
LinkStack*CreateLinkStack()
{
LinkStack*ls = (LinkStack*)malloc(sizeof(LinkStack));
if(NULL == ls)
{
fprintf(stderr,"CreateLinkStack malloc\n");
return NULL;
}
ls->top =NULL;
ls->clen = 0;
return ls;
}
(2).销毁 DestroySeqStack
int DestoryLinkStack(LinkStack*ls)
{
int len = GetSizeLinkStack(ls);
int i = 0;
for(i = 0;i < len;++i)
{
PopLinkStack(ls);
}
free(ls);
ls->top = NULL;
return 0;
}
(3).判断是否为空栈 IsEmptySeqStack
int IsEmptyLinkStack(LinkStack*ls)
{
return 0 == ls->clen;
}
(4).获取栈顶元素
DATATYPE*GetTopLinkStack(LinkStack*ls)
{
if(IsEmptyLinkStack(ls))
{
return NULL;
}
return &ls->top->data;
}
(5).进栈 PushSeqStack
int PushLinkStack(LinkStack*ls,DATATYPE*data)
{
LinkStackNode *newnode = malloc(sizeof(LinkStackNode));
if(NULL == ls)
{
fprintf(stderr,"PushLinkStack malloc\n");
return 1;
}
memcpy(&newnode->data, data, sizeof(DATATYPE));
newnode->next =NULL;
newnode->next = ls->top;
ls->top = newnode;
ls->clen++;
return 0;
}
(6).出栈 PopSeqStack
int PopLinkStack(LinkStack*ls)
{
if(IsEmptyLinkStack(ls))
{
return 1;
}
LinkStackNode *tmp = ls->top;
ls->top = ls->top->next;
free(tmp);
ls->clen--;
return 0;
}
二、队列
1.定义:队列是只允许在一段进行插入,而在另一端进行删除操作的线性表。
2.允许插入的称谓队尾,允许删除的一端队头。
3.特性:先进先出
4.队列的一般操作
(1)满队和空队的判断
满队:(tail+1)%tlen=head;空对:tail = head;
(2)创建 CreateSeQue
SeqQueue* CreateSeqQue(int len)
{
SeqQueue*sq = (SeqQueue*)malloc(sizeof(SeqQueue));
if(NULL == sq)
{
fprintf(stderr, "CreateSeQueue malloc\n");
return NULL;
}
sq->array = (malloc(sizeof(DATATYPE)*len));
if(NULL == sq->array)
{
fprintf(stderr, "CreateSeQueue malloc\n");
return NULL;
}
sq->head = 0;
sq->tail = 0;
sq->tlen =len;
return sq;
}
(3)判空
int IsEmptySeqQue(SeqQueue*sq)
{
return sq->head==sq->tail;
}
(4)判满
int IsFullSeqQue(SeqQueue*sq)
{
return (sq->tail+1)%sq->tlen == sq->head;
}
(5)进队
int EnterSeqQue(SeqQueue*sq,DATATYPE*data)
{
if(IsFullSeqQue(sq))
{
fprintf(stderr,"EnterSeqQue,SeqQue full\n");
return 1;
}
memcpy(&sq->array[sq->tail], data, sizeof(DATATYPE));
sq->tail = (sq->tail+1)%sq->tlen;
return 0;;
}
(6)出队
int QuitSeqQue(SeqQueue*sq)
{
if(IsEmptySeqQue(sq))
{
fprintf(stderr,"QuitSeqQue SeqQue empty\n");
return 1;
}
sq->head =(sq->head+1)%sq->tlen;
return 0;
}
(7)获得队头元素
DATATYPE* GetHeadSeqQue(SeqQueue*sq)
{
if(IsEmptySeqQue(sq))
{
return NULL;
}
return &sq->array[sq->head];
}
(9)销毁
int DestroySeqQue(SeqQueue*sq)
{
free(sq->array);
free(sq);
return 0;
}
三、四则运算底层逻辑(运算及优先问题)
#include <stdio.h>
#include <string.h>
#include "linkstack.h"
int num = 0;
void getnum(char c) { num = num * 10 + c - '0'; }
int get_priority(char c)
{
switch (c)
{
case '+':
case '-':
return 1;
break;
case '*':
case '/':
return 2;
break;
default:
return 100;
}
return 100;
}
int get_result(int num1,int num2,char c)
{
switch (c)
{
case '+':
return num1+num2;
case '-':
return num1-num2;
case '*':
return num1*num2;
case '/':
return num1/num2;
}
return -1;
}
int main(int argc, char** argv)
{
char buf[] = "2*3+4";
LinkStack* ls_op = CreateLinkStack();
LinkStack* ls_num = CreateLinkStack();
char* tmp = buf;
DATATYPE data;
DATATYPE* top = NULL;
int flag = 0;
while (*tmp)
{
memset(&data, 0, sizeof(data));
if (*tmp >= '0' && *tmp <= '9')
{
getnum(*tmp);
tmp++;
continue;
}
if (0 == flag)
{
data.num = num;
PushLinkStack(ls_num, &data);
num = 0;
}
memset(&data, 0, sizeof(data));
top = GetTopLinkStack(ls_op);
if (IsEmptyLinkStack(ls_op) ||
get_priority(*tmp) >
get_priority(
top->c)) //栈顶为空 或 当前运算符优先级大于 栈顶运算符优先级
{
data.c = *tmp;
PushLinkStack(ls_op, &data);
flag = 0 ;
}
else
{
int num2 = GetTopLinkStack(ls_num)->num;
PopLinkStack(ls_num);
int num1 = GetTopLinkStack(ls_num)->num;
PopLinkStack(ls_num);
int c = GetTopLinkStack(ls_op)->c;
PopLinkStack(ls_op);
int result = get_result(num1, num2, c);
memset(&data, 0, sizeof(data));
data.num = result;
PushLinkStack(ls_num, &data);
flag = 1; // 当前符号需要继续判断优先级
continue;
}
tmp++;
}
data.num = num;
PushLinkStack(ls_num, &data);
while (!IsEmptyLinkStack(ls_op))
{
int num2 = GetTopLinkStack(ls_num)->num;
PopLinkStack(ls_num);
int num1 = GetTopLinkStack(ls_num)->num;
PopLinkStack(ls_num);
int c = GetTopLinkStack(ls_op)->c;
PopLinkStack(ls_op);
int result = get_result(num1, num2, c);
memset(&data, 0, sizeof(data));
data.num = result;
PushLinkStack(ls_num, &data);
}
int result = GetTopLinkStack(ls_num)->num;
printf("result is %d\n", result);
DestroyLinkStack(ls_num);
DestroyLinkStack(ls_op);
return 0;
}
四、判断括号匹配问题
检查文件有无括号匹配问题
#include <stdio.h>
#include <string.h>
#include "linkstack.h"
/**
* @brief 读取文件内容
*
* @param filename 文件名
* @param filecontext 接收文件内容的字符数组 char buf[1024]={0};
* @return int 0 表示成功 1 表示失败
*/
int readfile(char *filename, char *filecontext)
{
FILE *fp = fopen(filename, "r");
if (NULL == fp)
{
return 1;
}
fread(filecontext, 1024, 1, fp);
fclose(fp);
return 0;
}
int main(int argc, char **argv)
{
char buf[1024] = {0};
int ret = readfile("/home/linux/2.c", buf);
if (1 == ret)
{
return 1;
}
LinkStack *ls = CreateLinkStack();
char *tmp = buf;
DATATYPE data = {0};
int row = 1;
int col = 1;
DATATYPE *top;
while (*tmp) // ( [ {
{
memset(&data, 0, sizeof(DATATYPE));
switch (*tmp)
{
case '(':
case '[':
case '{':
data.c = *tmp;
data.col = col;
data.row = row;
PushLinkStack(ls, &data);
break;
case ')':
top = GetTopLinkStack(ls);
if ('(' == top->c && NULL != top)
{
PopLinkStack(ls);
}
else
{
if (NULL == top)
{
printf("sym:%c row:%d col%d\n", ')', row, col);
}
else
{
printf(
"top sym:%c row:%d col%d , or file sym:%c row:%d "
"col%d\n",
top->c, top->row, top->col, *tmp, row, col);
}
return 1;
}
break;
case ']':
top = GetTopLinkStack(ls);
if ('[' == top->c && NULL != top)
{
PopLinkStack(ls);
}
else
{
if (NULL == top)
{
printf("sym:%c row:%d col%d\n", ')', row, col);
}
else
{
printf(
"top sym:%c row:%d col%d , or file sym:%c row:%d "
"col%d\n",
top->c, top->row, top->col, *tmp, row, col);
}
return 1;
}
break;
case '}':
top = GetTopLinkStack(ls);
if ('{' == top->c && NULL != top)
{
PopLinkStack(ls);
}
else
{
if (NULL == top)
{
printf("sym:%c row:%d col%d\n", ')', row, col);
}
else
{
printf(
"top sym:%c row:%d col%d , or file sym:%c row:%d "
"col%d\n",
top->c, top->row, top->col, *tmp, row, col);
}
return 1;
}
break;
}
col++;
if ('\n' == *tmp)
{
col = 1;
row++;
}
tmp++;
}
if ('\0' == *tmp && IsEmptyLinkStack(ls))
{
printf("ok");
}
else
{
top = GetTopLinkStack(ls);
printf("top sym:%c row:%d col%d\n", top->c, top->row, top->col);
}
DestroyLinkStack(ls);
return 0;
}