利用栈实现的经典案例

来源:互联网 发布:园林效果图设计软件 编辑:程序博客网 时间:2024/06/02 04:09

1.用栈来实现任意进制进制转换

//linklist.h

#ifndef __LINKLIST_H__#define __LINKLIST_H__typedef struct linklistnode         {    struct linklistnode *next;          int item;}LinkListNode;             //数据节点 typedef struct linklist         {    LinkListNode header;            int length;}LinkList;               //头节点   LinkList *LinkList_Create();void LinkList_Destroy(LinkList *list);void LinkList_Clear(LinkList *list);int LinkList_Length(LinkList *list);int LinkList_Insert(LinkList *list, LinkListNode *node, int pos);LinkListNode *LinkList_Get(LinkList *list,int pos);LinkListNode *LinkList_Delete(LinkList *list,int pos);#endif  //__LINKLIST_H__

//linklist.c

#include <stdlib.h>#include "linklist.h"LinkList *LinkList_Create(){    LinkList *ret = NULL;    ret = malloc(sizeof(LinkList));    if(ret!=NULL)    {        ret->length = 0;        ret->header.next = NULL;    }    return ret;}void LinkList_Destroy(LinkList *list){    free(list);}void LinkList_Clear(LinkList *list){    if(list!=NULL)    {        list->length =0;        list->header.next = NULL;    }}int LinkList_Length(LinkList *list){    int ret = -1;    if( list!=NULL )    {        ret = list->length;     }    return ret;}int LinkList_Insert(LinkList *list, LinkListNode *node, int pos){    int ret = list!=NULL && node!=NULL && pos>=0;    if( ret )    {        int i;        LinkListNode *cur = (LinkListNode *)list;        for(i=0;i<pos && cur->next!=NULL;i++)        {            cur = cur->next;         }        node->next = cur->next;        cur->next = node;        list->length++;    }    return ret;}LinkListNode *LinkList_Get(LinkList *list,int pos){    LinkListNode *ret = NULL;    if( list!=NULL && (0<=pos && pos<list->length) )    {        int i;        LinkListNode *cur = (LinkListNode *)list;        for(i=0; i<pos; i++)            cur = cur->next;        ret = cur->next;        //因为从0开始计数的,要第三个数,那么就是第二个数的next    }    return ret;}LinkListNode *LinkList_Delete(LinkList *list,int pos){    LinkListNode *ret = NULL;    if(list!=NULL && (0<=pos&&pos<list->length) )    {        int i;        LinkListNode *cur = (LinkListNode *)list;        for(i=0; i<pos; i++)            cur = cur->next;        ret = cur->next;    //单项链表是从0开始排的。        cur->next = ret->next;        list->length--;    }    return ret;}

//linkstack.h

#ifndef __LINKSTACK_H__#define __LINKSTACK_H__typedef struct linkstacknode{    struct linkstacknode *node;    void *item;}LinkStackNode;typedef void LinkStack;LinkStack *LinkStack_Create();void LinkStack_Destroy(LinkStack *stack);void LinkStack_Clear(LinkStack *stack);int LinkStack_Push(LinkStack *stack,void *item);void *LinkStack_Pop(LinkStack *stack);void *LinkStack_Top(LinkStack *stack);int LinkStack_Size(LinkStack *stack);#endif //__LINKSTACK_H__

//linkstack.c

#include <stdio.h>#include <stdlib.h>#include <string.h>#include "linklist.h"#include "linkstack.h"LinkStack *LinkStack_Create(){    return LinkList_Create();}void LinkStack_Destroy(LinkStack *stack){    LinkStack_Clear(stack);    LinkList_Destroy(stack);}void LinkStack_Clear(LinkStack *stack){    while ( LinkStack_Size(stack) > 0 )        LinkStack_Pop(stack);}int LinkStack_Push(LinkStack *stack,void *item){    LinkStackNode *node = malloc(sizeof(LinkStackNode));    int ret = stack!=NULL && item!=NULL && node!=NULL;    if( ret )    {        memset(node,0x00,sizeof(*node)); //??         node->item = item;        ret = LinkList_Insert(stack, (LinkListNode *)node, 0);    }    if(!ret)    {        free(node);    }    return ret;}void *LinkStack_Pop(LinkStack *stack){    LinkStackNode *node = NULL;    void *ret = NULL;    node = (LinkStackNode *)LinkList_Delete(stack,0);    if ( node != NULL)    {        ret = node->item;        free(node);    }    return ret;}void *LinkStack_Top(LinkStack *stack){    LinkStackNode *node = NULL;    void *ret = NULL;    node = (LinkStackNode *)LinkList_Get(stack,0);    if( node!=NULL)    {        ret = node->item;     }    return ret;}int LinkStack_Size(LinkStack *stack){    return LinkList_Length(stack);}

//main.c

#include <stdio.h>#include <stdlib.h>#include "linkstack.h"void convert(int digit,int base){    static char num[]= {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};    LinkStack *stack = LinkStack_Create();    do    {        LinkStack_Push(stack,&num[digit%base]); //进栈        digit /= base;    }while( digit!= 0 );    while ( LinkStack_Size(stack) > 0 )    {        char *c = (char *)LinkStack_Pop(stack); //出栈        printf("%c", *c);    }    printf("\n");    LinkStack_Destroy(stack);}int main( void ){    convert(10,2);  //十进制的10转换为2进制    convert(32,16);  //十进制的转换为16进制     return 0;}

Makefile

cc :=gccmain : main.o linklist.o linkstack.o    gcc $^ -o $@.PHONY : main cleanclean:    rm -rf *.o main

2.用栈来实现加、减、乘、除的计算

中缀转后缀

对于数字,直接输出    对于符号:        左括号:进栈        符号:于栈顶符号进行优先级比较        栈顶优先级低:进栈        栈顶优先级不低,将栈顶符号弹出并输出,之后进栈        右括号:将栈顶符号弹出并输出,知道匹配左括号    遍历结束:将栈中所有符号弹出并输出

后缀表达式计算:

对于数字:进栈对于符号:    从栈中弹出右右操作数    从栈中弹出左操作数    根据运算符进行运算    将运算结果入栈遍历结束:栈中唯一数字就是运算结果

有时候代码不重用,重要的是我们的思路,当我们有思路,那么我们剩下的就是把我们向的变为代码就ok了

//linklist.h

#ifndef __LINKLIST_H__#define __LINKLIST_H__typedef struct linklistnode         {    struct linklistnode *next;          int item;}LinkListNode;             //数据节点 typedef struct linklist         {    LinkListNode header;            int length;}LinkList;               //头节点   LinkList *LinkList_Create();void LinkList_Destroy(LinkList *list);void LinkList_Clear(LinkList *list);int LinkList_Length(LinkList *list);int LinkList_Insert(LinkList *list, LinkListNode *node, int pos);LinkListNode *LinkList_Get(LinkList *list,int pos);LinkListNode *LinkList_Delete(LinkList *list,int pos);#endif  //__LINKLIST_H__

//linklist.c

#include <stdlib.h>#include "linklist.h"LinkList *LinkList_Create(){    LinkList *ret = NULL;    ret = malloc(sizeof(LinkList));    if(ret!=NULL)    {        ret->length = 0;        ret->header.next = NULL;    }    return ret;}void LinkList_Destroy(LinkList *list){    free(list);}void LinkList_Clear(LinkList *list){    if(list!=NULL)    {        list->length =0;        list->header.next = NULL;    }}int LinkList_Length(LinkList *list){    int ret = -1;    if( list!=NULL )    {        ret = list->length;     }    return ret;}int LinkList_Insert(LinkList *list, LinkListNode *node, int pos){    int ret = list!=NULL && node!=NULL && pos>=0;    if( ret )    {        int i;        LinkListNode *cur = (LinkListNode *)list;        for(i=0;i<pos && cur->next!=NULL;i++)        {            cur = cur->next;         }        node->next = cur->next;        cur->next = node;        list->length++;    }    return ret;}LinkListNode *LinkList_Get(LinkList *list,int pos){    LinkListNode *ret = NULL;    if( list!=NULL && (0<=pos && pos<list->length) )    {        int i;        LinkListNode *cur = (LinkListNode *)list;        for(i=0; i<pos; i++)            cur = cur->next;        ret = cur->next;        //因为从0开始计数的,要第三个数,那么就是第二个数的next    }    return ret;}LinkListNode *LinkList_Delete(LinkList *list,int pos){    LinkListNode *ret = NULL;    if(list!=NULL && (0<=pos&&pos<list->length) )    {        int i;        LinkListNode *cur = (LinkListNode *)list;        for(i=0; i<pos; i++)            cur = cur->next;        ret = cur->next;    //单项链表是从0开始排的。        cur->next = ret->next;        list->length--;    }    return ret;}

//linkstack.h

#ifndef __LINKSTACK_H__#define __LINKSTACK_H__typedef struct linkstacknode{    struct linkstacknode *node;    void *item;}LinkStackNode;typedef void LinkStack;LinkStack *LinkStack_Create();void LinkStack_Destroy(LinkStack *stack);void LinkStack_Clear(LinkStack *stack);int LinkStack_Push(LinkStack *stack,void *item);void *LinkStack_Pop(LinkStack *stack);void *LinkStack_Top(LinkStack *stack);int LinkStack_Size(LinkStack *stack);#endif //__LINKSTACK_H__

//linkstack.c

#include <stdio.h>#include <stdlib.h>#include <string.h>#include "linklist.h"#include "linkstack.h"LinkStack *LinkStack_Create(){    return LinkList_Create();}void LinkStack_Destroy(LinkStack *stack){    LinkStack_Clear(stack);    LinkList_Destroy(stack);}void LinkStack_Clear(LinkStack *stack){    while ( LinkStack_Size(stack) > 0 )        LinkStack_Pop(stack);}int LinkStack_Push(LinkStack *stack,void *item){    LinkStackNode *node = malloc(sizeof(LinkStackNode));    int ret = stack!=NULL && item!=NULL && node!=NULL;    if( ret )    {        memset(node,0x00,sizeof(*node)); //??         node->item = item;        ret = LinkList_Insert(stack, (LinkListNode *)node, 0);    }    if(!ret)    {        free(node);    }    return ret;}void *LinkStack_Pop(LinkStack *stack){    LinkStackNode *node = NULL;    void *ret = NULL;    node = (LinkStackNode *)LinkList_Delete(stack,0);    if ( node != NULL)    {        ret = node->item;        free(node);    }    return ret;}void *LinkStack_Top(LinkStack *stack){    LinkStackNode *node = NULL;    void *ret = NULL;    node = (LinkStackNode *)LinkList_Get(stack,0);    if( node!=NULL)    {        ret = node->item;     }    return ret;}int LinkStack_Size(LinkStack *stack){    return LinkList_Length(stack);}

//main.c

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <assert.h>#include "linkstack.h"int isNum(char c){    return c>='0' && c<='9';}int isLeft(char c){    return c=='(';}int isRight(char c){    return c==')';}int isOperator(char c){    return c=='+' || c=='-' || c=='*' || c=='/';}int priority(char c){    int ret=0;    if( c=='+' || c=='-' )        ret = 1;    if( c=='*' || c=='/' )        ret = 2;    return ret;}//前缀表达式:void transfrom( const char *exp, char *buf){    int i = 0;    int idx = 0;    LinkStackNode *stack = LinkStack_Create();    while ( exp[i] != 0 )    {        if( isNum(exp[i]))     //是数字,直接输出        {            //putchar(exp[i]);            buf[idx++] = exp[i];         }        else if( isLeft(exp[i]) )   //是左(就进栈        {            LinkStack_Push(stack, ( void * )(int)exp[i]);         }        else if ( isOperator(exp[i]) )  //是运算符,就进行比较优先级        {            while(priority(exp[i]) <= priority((char)(int)LinkStack_Top(stack)))             {                //putchar((char)(int)LinkStack_Pop(stack)); //输出栈顶元素                buf[idx++] = ((char)(int)LinkStack_Pop(stack));            }            LinkStack_Push(stack, (void *)(int)exp[i]); //在把它进栈        }        else if( isRight(exp[i]) )  //是右) 并且栈顶的不是(,就让他一直输出栈顶元素        {            while ( !isLeft( (char)(int)LinkStack_Top(stack) ))             {                //putchar((char)(int)LinkStack_Pop(stack));                 buf[idx++] = ((char)(int)LinkStack_Pop(stack));             }            LinkStack_Pop(stack);   //栈顶是(,则弹出并没有输出        }        else        {            printf("invalid expresstiom!\n");             break;        }        i++;    }    while(exp[i]==0 && LinkStack_Size(stack) )  //没有了表达式,并且栈有操作符,就让他直接输入    {        //putchar((char)(int)LinkStack_Pop(stack));         buf[idx++] = ((char)(int)LinkStack_Pop(stack));     }    //putchar('\n');    buf[idx] = 0;       //加了一个‘\0'    LinkStack_Destroy(stack);}int value(char c){    return c-'0';}int operation(int left,int right, int op){    int ret = 0;    switch (op)    {        case '+':            ret = left + right;            break;        case '-':            ret = left - right;            break;        case '*':            ret = left * right;            break;        case '/':            assert(right);            ret = left / right;            break;        default:            printf("error!\n");            exit(1);            break;    }    return ret;}//后缀表达式:int compute(const char *exp){    int i = 0;    int res = 0;    LinkStack *stack = LinkStack_Create();    while ( exp[i]!= 0 )    {        if( isNum(exp[i]) )     //是数字,就进栈        {            LinkStack_Push(stack, (void *)value(exp[i]));         }        else if( isOperator(exp[i]) )   //是操作数,就让栈顶两个数出栈,进行运算        {            int r = (int)LinkStack_Pop(stack);            int l = (int)LinkStack_Pop(stack);            int ret = operation(l,r,exp[i]);            LinkStack_Push(stack, (void *)ret);        }        else        {            printf("invalid expression!\n");             break;        }        i++;    }    if( LinkStack_Size(stack)==1 && exp[i]==0 ) //只有输入一个数的时候,直接让他输出    {        res = (int)LinkStack_Pop(stack);     }    LinkStack_Destroy(stack);    return res;}int main( void ){    char buf[1024] = {};    char exp[1024] = {};//    transfrom("5+3*2");    while ( 1 )    {        printf("输入一个算式表达式:");         fgets(buf, 1024, stdin);    //标准输入放入buf中        buf[strlen(buf)-1] = 0;     //清掉最后一个换行符        transfrom(buf, exp);        //表达式通过buf传过去,在通过exp带回来结果,        printf("%s=", buf);        printf("%d\n",compute(exp));    }//    printf("9-3*2+(5-1)");//    printf("%d\n",compute("932*-51-+"));    return 0;}

//Makefile

cc :=gccmain : main.o linklist.o linkstack.o    gcc $^ -o $@.PHONY : main cleanclean:    rm -rf *.o main

3.用栈来实现符号的匹配

和上一个的其他函数都一样,就主函数变化为:

//main.c

#include <stdio.h>#include <stdlib.h>#include "linkstack.h"int isLeft(char c){    return c == '{' || c == '[' || c == '(' || c == '<';}int isRight(char c){    return c == '}' || c == ']' || c == ')' || c == '>';}//匹配int match(char left, char right){    int ret;    switch (left)    {        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 ){    int i = 0; //   int ret = 0;    LinkStackNode *stack = LinkStack_Create();    while ( code[i] !='\0' )    {        if( isLeft(code[i]) )        {            LinkStack_Push(stack, (void *)(int)code[i]);         }        if( isRight(code[i]))        {            char c = (char)(int)LinkStack_Pop(stack);            if( !match(c, code[i]) )            {                printf("%c no matched\n",code[i]);                 return -1;           //     break;            }        }        i++;    }    if( LinkStack_Size(stack)==0 && code[i]=='\0' )    {        printf("success!\n");     }    else    {        printf("invalid!\n");    }    LinkStack_Destroy(stack);    return 0;//    return ret;}*/int scanner( const char *code ){    int i = 0;    int ret = 0;    LinkStackNode *stack = LinkStack_Create();    while ( code[i] !='\0' )    {        if( isLeft(code[i]) )        {            LinkStack_Push(stack, (void *)(int)code[i]);         }        if( isRight(code[i]))        {            char c = (char)(int)LinkStack_Pop(stack);            if( !match(c, code[i]) )            {                printf("%c no matched\n",code[i]);                 ret = -1;                break;            }        }        i++;    }    if( LinkStack_Size(stack)==0 && code[i]=='\0' )    {        printf("success!\n");     }    else    {        printf("invalid!\n");    }    LinkStack_Destroy(stack);    return ret;}int main( void ){    const char *code = "#include <stdlib.h>"                        "int main( void )"                            "}";    scanner(code);    return 0;}
0 0
原创粉丝点击