zoukankan      html  css  js  c++  java
  • 栈与队列的算法总结

    栈与队列的算法总结

    • 栈与队列实现
    • 含有最小值的栈
    • 两个栈实现队列
    • 一个栈排序另一个栈

    含有最小值的栈

    思路:用一个辅助栈来记录主栈的最小值,对于主栈来说有两种操作:插入,弹出。

    插入:当向主栈插入元素时,有三种情况:

    • 1.当向主栈插入元素后,如果辅助栈为空,则直接将此元素插入辅助栈顶。
    • 2.当向主栈插入元素后,辅助栈不为空,需要判断辅助栈栈顶元素与插入元素大小,如果辅助栈栈顶元素大于插入元素,则将插入元素插入到辅助栈栈顶。
    • 3.如果辅助栈栈顶元素小于或者等于插入元素,则把辅助栈栈顶元素插入到辅助栈的栈顶。

    如图,stockData为主栈,stackMin为辅助栈,当向主栈插入元素时:

    弹出:当弹出主栈元素时,辅助栈也需要弹出元素。

    #include <stdio.h>
    #include<malloc.h>
    
    //声明链表节点类型
    typedef struct LISTtag LISTtagNode;
    struct    LISTtag{
        int value;
        LISTtagNode *next;
    };
    int size=0;
    int sizeminor = 0;
    
    //创建链表
    LISTtagNode * create(){
        LISTtagNode *head;
        head = (LISTtagNode*)malloc(sizeof(LISTtagNode));
        head->next =  NULL;
        return head;
    }
    
    
    //在链表头新增节点
    int push(LISTtagNode *head,int value){
        if(head == NULL){
            return -1;
        }
        //新建节点
        LISTtagNode *node;
        node = (LISTtagNode*)malloc(sizeof(LISTtagNode));
        //节点赋值,此节点跟在头节点后
        node->value = value;
        node->next = head->next;
        head->next = node;
        size++;
        return 1;
    }
    
    
    //打印链表
    int PrindLinKList(LISTtagNode *head){
         if(head == NULL){
            return -1;
        }
        printf("
     ");
        LISTtagNode *t = head;
        while (t->next != NULL) {
            t = t->next;
            printf("%d ", t->value);
        }
        return 1;
    }
    
    
    int pop(LISTtagNode *head){
        if(head ==NULL){
            return -1;
        }
        LISTtagNode *node;
        int index = 0;
        while(head->next!=NULL&&index<1){
            node = head->next;
            index++;
        }
        if(index == 1){
             printf("
    主栈弹出元素:%d 
    ",node->value);
            if(head->next->next != NULL){
                head->next = head->next->next;  
            }else{
                head->next =NULL;
            }
            free(node);
            size--;
            return 1;
        }  
        return -1;
    }
    
    //打印栈顶元素
    int top(LISTtagNode *head){
        if(head ==NULL){
            return -1;
        }
        LISTtagNode *node;
        int index = 0;
        while(head->next!=NULL&&index<1){
            node = head->next;
            index++;
        }
        if(index == 1){
            printf("
    栈顶元素:%d
    ",node->value);
            return 1;
        }
        return -1;
    }
    
    int empty(LISTtagNode *head){
        if(head ==NULL){
            return -1;
         }
        if(head->next!=NULL){
            return 0;
        }
        return 1;
    }
    
    //链表长度
    int length(LISTtagNode *head){
        if(head ==NULL){
            return -1;
         }
        return size;
    }
    
    
    //在链表头新增节点
    int pushminor(LISTtagNode *head,int value){
        if(head == NULL){
            return -1;
        }
        if(head->next ==NULL){
              //新建节点
            LISTtagNode *node;
            node = (LISTtagNode*)malloc(sizeof(LISTtagNode));
            //节点赋值,此节点跟在头节点后
            node->value = value;
            node->next = head->next;
            head->next = node;
            sizeminor++;
            return 1;
        }else{
            if(head->next->value >= value){
                //新建节点
                LISTtagNode *node;
                node = (LISTtagNode*)malloc(sizeof(LISTtagNode));
                //节点赋值,此节点跟在头节点后
                node->value = value;
                node->next = head->next;
                head->next = node;
                sizeminor++;
                return 1;
            }else{
                  //新建节点
                LISTtagNode *node;
                node = (LISTtagNode*)malloc(sizeof(LISTtagNode));
                //节点赋值,此节点跟在头节点后
                node->value = head->next->value;
                node->next = head->next;
                head->next = node;
                sizeminor++;
                return 1;
            }
            
            
        }
      
    }
    
    
    int popminor(LISTtagNode *head){
        if(head ==NULL){
            return -1;
        }
        LISTtagNode *node;
        int index = 0;
        while(head->next!=NULL&&index<1){
            node = head->next;
            index++;
        }
        if(index == 1){
             printf("辅助栈弹出元素:%d
    ",node->value);
            if(head->next->next != NULL){
                head->next = head->next->next;  
            }else{
                head->next =NULL;
            }
            free(node);
            sizeminor--;
            return 1;
        }
        return -1;
    }
    
    int main () {
        //主栈
        LISTtagNode *head = create();
        //辅助栈
        LISTtagNode *headminor = create();
        
        //向链表插入元素
        push(head,7);
        pushminor(headminor,7);
        //PrindLinKList(headminor);
        top(headminor);
        
         //向主栈插入元素
        push(head,9);
         //向辅助栈插入元素
        pushminor(headminor,9);
        //打印辅助栈的栈顶元素,就是最小值
        top(headminor);
        
         //向链表插入元素
        push(head,23);
        pushminor(headminor,23);
        top(headminor);
        
         //向链表插入元素
        push(head,2);
        pushminor(headminor,2);
        top(headminor);
        
        //弹出链表元素
        pop(head);
        popminor(headminor);
        top(headminor);
        
        
        return 0;
    }
    实现代码

     

    一个栈排序另一个栈

    思路:需要排序的栈称为主栈,记录排序结果的栈为辅助栈。

    每次从主栈弹出一个元素,与辅助栈栈顶元素比较,这里有一个特殊情况,就是辅助栈为空,如果辅助栈为空,则将主栈弹出的元素压入辅助栈。

    如果辅助栈不为空,则比较:

    • 如果主栈弹出的元素小于或者等于辅助栈栈顶元素,则将主栈元素压入辅助栈。
    • 如果主栈弹出的元素大于辅助栈的元素,则将辅助栈的元素逐一弹出并压入到主栈,直到刚开始主栈弹出来的元素小于或者等于辅助栈栈顶元素时,再将主栈弹出来的元素压入辅助栈。

    排序代码:

    int sort(LISTtagNode *head,LISTtagNode *headminor){
         if(head ==NULL || headminor == NULL){
            return -1;
        }
          int Value;
          while(head->next!=NULL){
          Value = head->next->value;
            if(headminor->next ==NULL){
                 push(headminor,Value);
                 pop(head);
            }
            else{
                pop(head);
                int valuetemp;
                LISTtagNode *nodetemp;
                nodetemp = headminor->next;
                //如果Value大于辅助栈栈顶元素:
                if(Value>nodetemp->value){
                while((Value)>(nodetemp->value)&&(nodetemp->next !=NULL)){
                    valuetemp = nodetemp->value;
                    push(head,valuetemp);   
                    nodetemp = nodetemp->next;
                    popminor(headminor);
                }
                if(Value>nodetemp->value){
                    push(head,nodetemp->value);  
                    popminor(headminor);    
                }
                 push(headminor,Value);     
                //如果Value小于或者等于辅助栈栈顶元素:
                }else{
                    push(headminor,Value); 
                }
                
            }
        }
         return 1;
    }
    #include <stdio.h>
    #include<malloc.h>
    
    //声明链表节点类型
    typedef struct LISTtag LISTtagNode;
    struct    LISTtag{
        int value;
        LISTtagNode *next;
    };
    int size=0;
    
    //创建链表
    LISTtagNode * create(){
        LISTtagNode *head;
        head = (LISTtagNode*)malloc(sizeof(LISTtagNode));
        head->next =  NULL;
        return head;
    }
    
    
    //在链表头新增节点
    int push(LISTtagNode *head,int value){
        if(head == NULL){
            return -1;
        }
        //新建节点
        LISTtagNode *node;
        node = (LISTtagNode*)malloc(sizeof(LISTtagNode));
        //节点赋值,此节点跟在头节点后
        node->value = value;
        node->next = head->next;
        head->next = node;
        size++;
        return 1;
    }
    
    
    //打印链表
    int PrindLinKList(LISTtagNode *head){
         if(head == NULL){
            return -1;
        }
        printf("
     ");
        LISTtagNode *t = head;
        while (t->next != NULL) {
            t = t->next;
            printf("%d ", t->value);
        }
        return 1;
    }
    
    
    int pop(LISTtagNode *head){
        if(head ==NULL){
            return -1;
        }
        LISTtagNode *node;
        int index = 0;
        while(head->next!=NULL&&index<1){
            node = head->next;
            index++;
        }
        if(index == 1){
             printf("
    主栈弹出元素:%d 
    ",node->value);
            if(head->next->next != NULL){
                head->next = head->next->next;  
            }else{
                head->next =NULL;
            }
            free(node);
            size--;
            return 1;
        }  
        return -1;
    }
    
    
    int popminor(LISTtagNode *head){
        if(head ==NULL){
            return -1;
        }
        LISTtagNode *node;
        int index = 0;
        while(head->next!=NULL&&index<1){
            node = head->next;
            index++;
        }
        if(index == 1){
             printf("
    辅助栈弹出元素:%d 
    ",node->value);
            if(head->next->next != NULL){
                head->next = head->next->next;  
            }else{
                head->next =NULL;
            }
            free(node);
            size--;
            return 1;
        }  
        return -1;
    }
    //打印栈顶元素
    int top(LISTtagNode *head){
        if(head ==NULL){
            return -1;
        }
        LISTtagNode *node;
        int index = 0;
        while(head->next!=NULL&&index<1){
            node = head->next;
            index++;
        }
        if(index == 1){
            printf("
    栈顶元素:%d
    ",node->value);
            return 1;
        }
        return -1;
    }
    
    int empty(LISTtagNode *head){
        if(head ==NULL){
            return -1;
         }
        if(head->next!=NULL){
            return 0;
        }
        return 1;
    }
    
    //链表长度
    int length(LISTtagNode *head){
        if(head ==NULL){
            return -1;
         }
        return size;
    }
    
    
    //在链表头新增节点
    int pushminor(LISTtagNode *head,int value){
        if(head == NULL){
            return -1;
        }
        if(head->next ==NULL){
              //新建节点
            LISTtagNode *node;
            node = (LISTtagNode*)malloc(sizeof(LISTtagNode));
            //节点赋值,此节点跟在头节点后
            node->value = value;
            node->next = head->next;
            head->next = node;
            return 1;
        }else{
            if(head->next->value >= value){
                //新建节点
                LISTtagNode *node;
                node = (LISTtagNode*)malloc(sizeof(LISTtagNode));
                //节点赋值,此节点跟在头节点后
                node->value = value;
                node->next = head->next;
                head->next = node;
                return 1;
            }else{
                  //新建节点
                LISTtagNode *node;
                node = (LISTtagNode*)malloc(sizeof(LISTtagNode));
                //节点赋值,此节点跟在头节点后
                node->value = head->next->value;
                node->next = head->next;
                head->next = node;
                return 1;
            }
            
            
        }
      
    }
    
    
    
    int sort(LISTtagNode *head,LISTtagNode *headminor){
         if(head ==NULL || headminor == NULL){
            return -1;
        }
          int Value;
          while(head->next!=NULL){
          Value = head->next->value;
            if(headminor->next ==NULL){
                 push(headminor,Value);
                 pop(head);
            }
            else{
                pop(head);
                int valuetemp;
                LISTtagNode *nodetemp;
                nodetemp = headminor->next;
                //如果Value大于辅助栈栈顶元素:
                if(Value>nodetemp->value){
                while((Value)>(nodetemp->value)&&(nodetemp->next !=NULL)){
                    valuetemp = nodetemp->value;
                    push(head,valuetemp);   
                    nodetemp = nodetemp->next;
                    popminor(headminor);
                }
                if(Value>nodetemp->value){
                    push(head,nodetemp->value);  
                    popminor(headminor);    
                }
                 push(headminor,Value);     
                //如果Value小于或者等于辅助栈栈顶元素:
                }else{
                    push(headminor,Value); 
                }
                
            }
        }
         return 1;
    }
    
    
    int main () {
        //主栈
        LISTtagNode *head = create();
        //辅助栈
        LISTtagNode *headminor = create();
        push(head,2);
        push(head,5);
        push(head,32);
        push(head,22);
        push(head,6);
        push(head,1);
        push(head,3);
        PrindLinKList(head);
        sort(head,headminor);
        PrindLinKList(headminor);
        
        return 0;
    }
    实现代码

    分析:

    1.每次从主栈弹出一个元素,直到主栈元素弹完。

    while(head->next!=NULL){
      //。。。
        }

    2.辅助栈为空。

    if(headminor->next ==NULL){
                 push(headminor,Value);
                 pop(head);
            }

    3.弹出主栈元素。

    pop(head);

    4.当主栈弹出的元素大于辅助栈的元素,则将辅助栈的元素逐一弹出并压入到主栈,直到刚开始主栈弹出来的元素小于或者等于辅助栈栈顶元素时,再将主栈弹出来的元素压入辅助栈。

                //如果Value大于辅助栈栈顶元素:
                if(Value>nodetemp->value){
                while((Value)>(nodetemp->value)&&(nodetemp->next !=NULL)){
                    valuetemp = nodetemp->value;
                    push(head,valuetemp);   
                    nodetemp = nodetemp->next;
                    popminor(headminor);
                }
                if(Value>nodetemp->value){ //这里是为了判断辅助栈最后一个元素是否也满足条件
                    push(head,nodetemp->value);  
                    popminor(headminor);    
                }
                 push(headminor,Value); //最后将主栈元素压入辅助栈

    5.主栈弹出的元素小于或者等于辅助栈栈顶元素,则将主栈元素压入辅助栈。

    //如果Value小于或者等于辅助栈栈顶元素:
                }else{
                    push(headminor,Value); 
                }
  • 相关阅读:
    pku3734Blocks
    STLmultiset
    zoj 2744
    EXCEL vba 插入图片的大小裁剪尺寸移动和旋转的设置和指定
    C# WinForm下Excel导入导出
    日期格式校验
    vb获取目录下所有文件夹名称的方法
    批量 生成 word 多线程
    Java中验证日期时间格式
    递归绑定树形菜单
  • 原文地址:https://www.cnblogs.com/-wenli/p/12641322.html
Copyright © 2011-2022 走看看