美文网首页数据结构和算法分析算法
从零开始养成算法·篇五:栈和队列·栈

从零开始养成算法·篇五:栈和队列·栈

作者: 文竹_自然 | 来源:发表于2020-04-11 16:04 被阅读0次

    一、栈结构示意图


    二、栈的常规操作

    1.定义一个栈结构

    /* 顺序栈结构 */
    typedef struct
    {
        SElemType data[MAXSIZE];
        int top; /* 用于栈顶指针 */
    }SqStack
    

    2.构建一个空栈

    Status InitStack(SqStack *S){
       
        S->top = -1;
        return 1;
    }
    

    3.将栈置空

    Status ClearStack(SqStack *S){
        
        S->top = -1;
        return 1;
    }
    

    4.判断顺序栈是否为空

    Status StackEmpty(SqStack S){
        if (S.top == -1)
            return 1;
        else
            return 0;
    }
    

    5.求栈的长度

    int StackLength(SqStack S){
        return S.top + 1;
    }
    

    6.获取栈顶

    Status GetTop(SqStack S,SElemType *e){
        if (S.top == -1)
            return 0;
        else
            *e = S.data[S.top];
        return 1;
    }
    

    7.插入元素e为新栈顶元素

    Status PushData(SqStack *S, SElemType e){
    
        if (S->top == MAXSIZE -1) {
            return 0;
        }
        S->top ++;
        S->data[S->top] = e;
        return 1;
    }
    

    8.删除S栈顶元素,并且打印删除的元素值

    Status Pop(SqStack *S,SElemType *e){
       
        if (S->top == -1) {
            return 0;
        }
        
        *e = S->data[S->top];
        printf("%d ",*e);
        S->top--;
        
        return 1;
    }
    

    9.遍历栈

    Status StackTraverse(SqStack S){
        int i = 0;
        printf("此栈中所有元素");
        while (i<=S.top) {
            printf("%d ",S.data[i++]);
        }
        printf("\n");
        return 1;
    }
    

    三、链栈结构示意图

    1.链栈结构图


    链栈结构.png

    2.进栈操作


    进栈.png
    3.出栈操作
    出栈.png

    四、链栈的常规操作

    1.定义一个链栈结构

    /*链栈结构 */
    typedef struct StackNode
    {
        SElemType data;
        struct StackNode *next;
    }StackNode,*LinkStackPtr;
    
    typedef struct
    {
        LinkStackPtr top;
        int count;
    }LinkStack;
    

    2.构建一个空链栈

    Status InitStack(LinkStack *S)
    {
        S->top=NULL;
        S->count=0;
        return 1;
    }
    

    3.将链栈置空

    Status ClearStack(LinkStack *S){
        LinkStackPtr p,q;
        p = S->top;
        while (p) {
            q = p;
            p = p->next;
            free(q);
        }
        S->count = 0;
        return OK;
        
    }
    

    4.判断链栈是否为空

    Status StackEmpty(LinkStack S){
        if (S.count == 0)
            return 1;
        else
            return 0;
    }
    

    5.求链栈的长度

    int StackLength(LinkStack S){
        return S.count;
    }
    

    6.获取栈顶元素

    Status GetTop(LinkStack S,SElemType *e){
        if(S.top == NULL)
            return 0;
        else
            *e = S.top->data;
        return 1;
    }
    

    7.插入元素e为新栈顶元素

    Status Push(LinkStack *S, SElemType e){
        
        LinkStackPtr temp = (LinkStackPtr)malloc(sizeof(StackNode));
        temp->data = e;
        temp->next = S->top;
        S->top = temp;
        S->count++;
        return 1;
    }
    

    8.删除S栈顶元素,并且打印删除的元素值

    Status Pop(LinkStack *S,SElemType *e){
        LinkStackPtr p;
        if (StackEmpty(*S)) {
            return 0;
        }
        
        *e = S->top->data;
        printf("%d ",*e);
        p = S->top;
        S->top= S->top->next;
        free(p);
        S->count--;
        
        return 1;
    }
    

    9.遍历栈

    Status StackTraverse(LinkStack S){
        LinkStackPtr p;
        p = S.top;
        while (p) {
            printf("%d ",p->data);
            p = p->next;
        }
        printf("\n");
        return OK;
    }
    

    五、栈与递归的关系

    1.什么时候使用递归

    • 定义是递归的
    • 数据结构是递归的
    • 问题的解法是递归的

    2.递归函数调用分析


    递归函数调用.png

    3.递归过程与递归工作栈


    1.png 2.png

    3.斐波拉契数列

    int Fbi(int i){
        if(i<2)
            return i == 0?0:1;
        return Fbi(i-1)+Fbi(i-2);
    }
    
    int main(int argc, const char * argv[]) {
        // insert code here...
        printf("斐波拉契数列!\n");
        // 1 1 2 3 5 8 13 21 34 55 89 144
        for (int i =0; i < 10; i++) {
             printf("%d  ",Fbi(i));
        }
        printf("\n");
       
        return 0;
    }
    

    4.Hanoi 塔问题

    int m = 0;
    void moves(char X,int n,char Y){
        m++;
        printf("%d: from %c ——> %c \n",n,X,Y);
    }
    
    //n为当前盘子编号. ABC为塔盘
    void Hanoi(int n ,char A,char B,char C){
        //目标: 将塔盘A上的圆盘按规则移动到塔盘C上,B作为辅助塔盘;
        //将编号为1的圆盘从A移动到C上
        if(n==1) moves(A, 1, C);
        else
        {
            //将塔盘A上的编号为1至n-1的圆盘移动到塔盘B上,C作为辅助塔;
            Hanoi(n-1, A, C, B);
            //将编号为n的圆盘从A移动到C上;
            moves(A, n, C);
            //将塔盘B上的编号为1至n-1的圆盘移动到塔盘C上,A作为辅助塔;
            Hanoi(n-1, B, A, C);
        }
    }
    
    int main(int argc, const char * argv[]) {
        Hanoi(3, 'A', 'B', 'C');
        printf("盘子数量为3:一共实现搬到次数:%d\n",m);
        return 0;
    }
    

    相关文章

      网友评论

        本文标题:从零开始养成算法·篇五:栈和队列·栈

        本文链接:https://www.haomeiwen.com/subject/sjtumhtx.html