栈与队列的算法总结

 

栈与队列的算法总结

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

 

含有最小值的栈

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

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

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

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

栈与队列的算法总结_第1张图片

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

#include 
#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("\n ");
    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("\n主栈弹出元素:%d \n",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("\n栈顶元素:%d\n",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\n",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 
#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("\n ");
    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("\n主栈弹出元素:%d \n",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("\n辅助栈弹出元素:%d \n",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("\n栈顶元素:%d\n",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); 
            }

 

你可能感兴趣的:(栈与队列的算法总结)