zoukankan      html  css  js  c++  java
  • C语言强化(二)设计可以求最小元素的栈

    上一篇详解了二叉树转双向链表,此篇作为【C语言强化】系列第二篇,来聊聊有关栈的一道题,

    通过这道题,你可以掌握

    • 如何使用栈“先进后出"的特性
    • 如何巧妙地借助辅助栈
    • 如何在结构体中定义可共享的静态成员变量
    题目


    看似很简单的求最小值函数,思路有很多很多。笔者首先想到每次push入栈都进行一次排序,使这个栈的栈顶永远是最小元素,然后就发现这是一个很蠢很蠢的想法,第一这样做会改变了栈的结构,第二不满足题目对时间复杂度的要求。
    愚蠢归愚蠢,还是有点用的。既然不能改变原来栈的结构,那为何不弄俩栈呢?辅助栈的想法由此而出。
    接下来是时间复杂度的问题,显然每次都进行排序是不可行的了,那么是否可以记录保存每个最小值的下一个最小值呢,也就是说,当我当前这个最小值被pop出去后,我要知道下一个最小值是哪个。这时栈的【先进后出】特性就派上用场了。
    头脑风暴到此结束。下面是具体思路
    牢牢把握住栈【先进后出】的特性,模拟各种实际情况,得出算法
    辅助栈:
    栈结构体中添加一个辅助栈,这里称为【最小值栈】,存储最小值的历史记录,所以该最小值栈的栈顶即为当前栈的最小元素
    算法实现:
    --push
    当push进来的元素值大于、等于最小值栈的栈顶,最小值栈不变,因为根据栈的特性,只有当前最小值元素上面的所有元素都出去的时候,该最小值元素才能pop出去,否则该最小值元素用于是最小值。
    反之,当push进来的元素值小于最小值栈的栈顶,则将该元素放进最小值栈。
    --pop
    当pop出去的元素不是最小值栈栈顶,则最小值栈不变
    如果pop出去的值为当前最小值,则最小值栈也pop出一个元素,此时最小值栈的栈顶就是下一个最小值元素

    源代码
    #include <stdio.h>
    #include<stdlib.h>
    #include <iostream>
    
    using namespace std;
    
    /**
    题目:
    定义栈的数据结构 要求添加一个min函数,找出栈的最小元素
    要求min、push、pop函数的时间复杂度都为O(1)
    
    思路
    牢牢把握住栈【先进后出】的特性,模拟各种实际情况,得出算法
    
    栈结构体中添加一个辅助栈,这里称为【最小值栈】,存储最小值的历史记录
    所以该最小值栈的栈顶即为当前栈的最小元素
    
    当push进来的元素值大于、等于最小值栈的栈顶,最小值栈不变
    因为根据栈的特性,只有当前最小值元素上面的所有元素都出去的时候,该最小值元素才能pop出去
    反之,则将该元素放进最小值栈
    
    当pop出去的元素不是最小值栈栈顶,则最小值栈不变
    反之,最小值栈pop出栈顶
    这样如果pop出去的值为当前最小值,则最小值栈也pop出一个元素
    此时最小值栈的栈顶就是下一个最小值元素
    */
    
    /*
    创建栈结点结构体
    value	值
    nextNode	下一个结点
    push()	入栈函数
    pop()	出栈函数
    min()	求最小值函数
    push2()	入栈并且求最小值
    pop2()	出栈并且求最小值
    */
    
    struct StackNode{
    	int value;
    	static StackNode * minNode;
    	StackNode * nextNode;
    	/**
    	push()	入栈函数
    	value	入栈的值
    	返回	栈顶
    	*/
    	StackNode * push(int value){
    		StackNode * top = new StackNode();
    		if(NULL!=this){
    			top=this;
    			StackNode * push = new StackNode();
    			push->value=value;
    			push->nextNode=top;
    			top=push;
    			
    		}else{
    			top->nextNode=NULL;
    			top->value=value;
    		}
    		cout<<"入栈,value="<<value<<endl;
    		return top;
    	}
    	/**
    	pop()	出栈函数
    	返回	栈顶
    	*/
    	StackNode* pop(){
    		if(NULL!=this){
    			cout<<"出栈,value="<<this->value<<endl;
    			return this->nextNode;
    		}
    		else{
    			cout<<"栈已经为空"<<endl;
    			return this;
    		}
    	}
    	/**
    	求最小值函数
    	flag	判断是push还是pop
    	value	push的值或者pop出去的值
    	*/
    	void min(bool flag,int value){
    		//push
    		if(flag){
    			//非空
    			if(NULL!=minNode){
    				//push进来的值小于等于原来的最小值,则push进入最小值栈
    				if(value<=minNode->value){
    					cout<<"最小值栈入栈"<<endl;
    					minNode=minNode->push(value);
    				}
    			}else{
    				//空,则直接放进去
    				cout<<"MinNode==NULL"<<endl;
    				cout<<"最小值栈入栈"<<endl;
    				minNode=minNode->push(value);
    			}
    		}else{
    			//pop
    			//非空且pop的值等于最小值,则最小值栈pop
    			if((NULL!=minNode)&&(minNode->value==value)){
    				cout<<"最小值栈出栈"<<endl;
    				minNode=minNode->pop();
    			}
    		}
    		if(NULL!=minNode)
    			cout<<"现在栈的最小值value="<<minNode->value<<endl;
    	}
    	//push+min
    	StackNode* push2(int value){
    		StackNode* node=this->push(value);
    		this->min(true,value);
    		return node;
    	}
    	//pop+min
    	StackNode* pop2(){
    		int value = this->value;
    		StackNode* node=this->pop();
    		this->min(false,value);
    		return node;
    	}
    };
    //结构体静态变量初始化!
    StackNode * StackNode::minNode = NULL;
    
    StackNode * stack;
    
    void main()
    {
    	stack=stack->push2(5);
    	stack=stack->push2(2);
    	stack=stack->push2(4);
    	stack=stack->push2(1);
    	stack=stack->push2(1);
    	while(NULL!=stack){
    		stack=stack->pop2();
    	}
    	system("pause");
    }

    效果图


    总结,所有与栈有关的题目,都记住这四个字——”先进后出“

  • 相关阅读:
    office 365 激活
    jdk 的 安装以及环境变量配置
    eclipse 创建maven项目失败
    一千行mysql笔记
    mysql 之 清空表中数据
    java 之 servlet
    java 之 javaBean
    java 之 jsp详解
    java 之 jsp tomcat启动失败问题
    npm install, npm install -g, npm install --save, npm install --save-dev之间的区别
  • 原文地址:https://www.cnblogs.com/javdroider/p/5184300.html
Copyright © 2011-2022 走看看