数据结构---最小栈两种方法(C语言实现)

代码环境:Linux
代码实现(一切尽在注释中):

MinkStack.h

#pragma once
#include<stdio.h>
#include<stdlib.h>

typedef char SeqStackType;

typedef struct SeqStack{
    SeqStackType* data;    
    size_t size;
    size_t capacity;    //MAX_SIZE的替代品,data这段内存能容纳的元素个数
}SeqStack;

typedef struct MinStack{
    SeqStack stack;
}MinStack;

//初始化
void SeqStackInit(SeqStack* stack);

//打印函数
void SeqStackPrint(SeqStack* stack,const char* ch);

//扩容
void SeqStackResize(SeqStack* stack);

//入栈
void SeqStackPush(SeqStack* stack,SeqStackType value);

//出栈
void SeqStackPop(SeqStack* stack);

//取栈顶元素
SeqStackType SeqStackTopValue(SeqStack* stack);

//销毁
void SeqStackDestory(SeqStack* stack);

//方法一
//可求出最小元素的push    flag == 1表示入栈 flag == 0 表示出栈
void SeqStackMin1(SeqStack* stack,SeqStack* stack2,int flag,SeqStackType value);

//入栈
void SeqStackPush2(SeqStack* stack1,SeqStack* stack2,SeqStackType value);

//出栈
void SeqStackPop2(SeqStack* stack1,SeqStack* stack2);

//入栈一个元素
void SeqStackPush3(SeqStack* stack, SeqStackType value);

//出栈一个元素
void SeqStackPop3(SeqStack* stack);

//取栈顶元素
SeqStackType SeqStackGetTop(SeqStack* stack);

MinStack.c

#include<stlib.h>
#include<stdio.h>
#include"MinStack.h"

//初始化
void SeqStackInit(SeqStack* stack){
    if(stack == NULL){
        //非法输入
        return;
    }
    stack->size = 0;
    stack->capacity = 1000;
    stack->data = (SeqStackType*)malloc(stack->capacity* sizeof(SeqStackType));
}

//打印函数
void SeqStackPrint(SeqStack* stack,const char* ch){
    if(stack == NULL){
        return;
    }
    printf("*****%s*******\n",ch);
    size_t i = 0;
    for(; i < stack->size; ++i){
        if(stack->data[i] == 0){
            return;
        }
        printf("入栈的第%d个元素是:[%c]\n",i+1,stack->data[i]);
    }
    printf("size = %d\n",stack->size);
}

//扩容
void SeqStackResize(SeqStack* stack){
    if(stack->size < stack->capacity){
        //TOOD
        ///home/xue/mycd/mycd/DataStructure/stackseqlist
        return;
    }
    stack->size = stack->capacity * 2 + 1;
    SeqStackType* new_ptr = (SeqStackType*)malloc(stack->capacity*sizeof(SeqStackType));
    size_t i = 0 ;
    for(; i < stack->size; ++i){
        new_ptr[i] = stack->data[i];
    }
    free(stack->data);
    stack->data = new_ptr;
    return;
}

//入栈
void SeqStackPush(SeqStack* stack,SeqStackType value){
    if(stack == NULL){
        return;
    }
    if(stack->size == stack->capacity){    //BUG
        SeqStackResize(stack); 
    }
    stack->data[stack->size++] = value;
}

//出栈
void SeqStackPop(SeqStack* stack){
    if(stack == NULL){
        return;
    }
    if(stack->size = 0){
        printf("空栈");
        return;
    }
    stack->size--;
}

//取栈顶元素
SeqStackType SeqStackTopValue(SeqStack* stack){
    if(stack == NULL){
        return;
    }
    size_t i = stack->size - 1;
    SeqStackType value = stack->data[i];
    return value;
}

//销毁
void SeqStackDestory(SeqStack* stack){
    free(stack->data);
    stack->size = 0;
    stack->capacity = 0;
}

//方法一:
//创建一个辅助栈,每次入栈之前把栈顶元素和辅助栈的栈顶元素比较
//如果小于等于辅助栈栈顶元素,则入栈辅助栈
//出栈时,把辅助栈栈顶元素和出栈元素相比较
//如果小于等于辅助栈栈顶元素,则把辅助栈栈顶元素也出栈

//方法一
//可求出最小元素的push    flag == 1表示入栈 flag == 0 表示出栈
void SeqStackMin1(SeqStack* stack,SeqStack* stack2,int flag,SeqStackType value){
    if(flag == 1){
        if(stack->size == 1){
            SeqStackPush(stack2,value);
        }
        //比较当前元素和辅助元素栈顶元素的大小
        //如果大于辅助栈栈顶元素,则不理会
        //反之则需要压入辅助栈
        else{
            //调用入栈的栈顶元素value和 辅助栈的栈顶元素比较
            SeqStackType cur = SeqStackTopValue(stack2);
            if(value > cur){
                return;
            }
            else{
                SeqStackPush(stack2,value);
            }
        }
    }
    //0表示操作为出栈操作
    else if(flag == 0){
        //出栈时,把栈顶元素和辅助栈栈顶元素相比较,如果大于则不理会
        SeqStackType cur2 = SeqStackTopValue(stack2);
        if(value > cur2){
            return;
        }
        else{
            //如果当前栈顶元素小于等于辅助栈的栈顶元素,则辅助栈栈顶元素也该出栈
            SeqStackPop(stack2);
        }
    }
}

//入栈
void SeqStackPush2(SeqStack* stack1,SeqStack* stack2,SeqStackType value){
    if(stack1 == NULL){
        return;
    }
    if(stack2 == NULL){
        return;
    }
    if(stack1->size >= stack1->capacity){
        SeqStackResize(stack1);
    }
    stack1->data[stack1->size] = value;
    stack1->size++;
    SeqStackMin1(stack1,stack2,1,value);
}


//出栈
void SeqStackPop2(SeqStack* stack1,SeqStack* stack2){
    if(stack1 == NULL){
        return;
    }
    if(stack2 == NULL){
        return;
    }
    //出栈得先判断
    SeqStackType tmp = SeqStackTopValue(stack1);
    SeqStackMin1(stack1,stack2,0,tmp);

    stack1->size--;

    if(stack1->size == 0){
        //此时栈已经空了
        return;
    }
}

//入栈一个元素
void SeqStackPush3(SeqStack* stack, SeqStackType value){
    if(stack == NULL){
        return;
    }
    //判断空栈
    if(stack->size == 0){
        //空栈的时候压栈两次,规定栈顶元素为最小值
        stack->data[stack->size] = value;
        stack->size++;
        stack->data[stack->size] = value;
        stack->size++;
        return;
    }
    //不是空栈
    //取出栈顶元素,与当前元素比较
    //如果当前元素大于已知最小元素,则压栈时,把当前元素入栈,再把最小元素入栈
    //如果当前元素小于一直元素,则把当前元素入栈两次
    //取出栈顶元素
    SeqStackType tmp = SeqStackTopValue(stack);
    //把当前元素入栈,再把最小元素入栈,即tmp
    if(value > tmp){
        SeqStackPush(stack,value);
        SeqStackPush(stack,tmp);
    }
    else{
        SeqStackPush(stack,value);
        SeqStackPush(stack,value);
    }
}

//出栈一个元素
void SeqStackPop3(SeqStack* stack){
    if(stack == NULL){
        return;
    }
    if(stack->size == 0){
        printf("栈为空");
        return;
    }
    //压栈时压入两个元素,出栈时也要出两个元素
    SeqStackPop(stack);
    SeqStackPop(stack);
}

//取栈顶元素
SeqStackType SeqStackGetTop(SeqStack* stack){
    if(stack == NULL){
        return;
    }
    //栈顶元素是最小值
    SeqStackType min = SeqStackTopValue(stack);
    SeqStackPop(stack);
    SeqStackType top_value = SeqStackTopValue(stack);
    //再把最小值入栈
    SeqStackPush(stack,min);
    return top_value;
}

/////////////////////////////////////
//**********************************
//*******Test***********************
////////////////////////////////////


#define TESTHEAD printf("\n\n===============%s=====================\n",__FUNCTION__)

//测试入栈
void TestPush(){
    SeqStack stack;
    TESTHEAD;
    SeqStackInit(&stack);
    SeqStackPush(&stack,'a');
    SeqStackPush(&stack,'b');
    SeqStackPush(&stack,'c');
    SeqStackPush(&stack,'d');
    SeqStackPush(&stack,'e');
    SeqStackPush(&stack,'f');
    SeqStackPrint(&stack,"入栈六个元素");
}

//测试出栈
void TestPop(){
    SeqStack stack;
    TESTHEAD;
    SeqStackInit(&stack);
    SeqStackPush(&stack,'a');
    SeqStackPush(&stack,'b');
    SeqStackPush(&stack,'c');
    SeqStackPush(&stack,'d');
    SeqStackPush(&stack,'e');
    SeqStackPush(&stack,'f');
    SeqStackPrint(&stack,"入栈六个元素");

    SeqStackPop(&stack);
    SeqStackPop(&stack);
    SeqStackPop(&stack);
    SeqStackPrint(&stack,"出栈三个元素");
}

//测试取栈顶元素
void TesGetTop(){
    SeqStack stack;
    TESTHEAD;
    SeqStackInit(&stack);
    SeqStackPush(&stack,'a');
    SeqStackPush(&stack,'b');
    SeqStackPush(&stack,'c');
    SeqStackPush(&stack,'d');
    SeqStackPush(&stack,'e');
    SeqStackPush(&stack,'f');
    SeqStackPrint(&stack,"入栈六个元素");

    SeqStackType tmp = SeqStackTopValue(&stack);
    printf("expect f,actual:%c\n\n",tmp);
}

//测试取最小元素
void TestMinValue1(){
    SeqStack stack1;
    SeqStack stack2;
    SeqStackInit(&stack1);
    SeqStackInit(&stack2);
    TESTHEAD;
    SeqStackPush2(&stack1,&stack2,'g');
    SeqStackPush2(&stack1,&stack2,'d');
    SeqStackPush2(&stack1,&stack2,'c');
    SeqStackPush2(&stack1,&stack2,'a');
    SeqStackPush2(&stack1,&stack2,'e');
    SeqStackPush2(&stack1,&stack2,'f');

    SeqStackPop2(&stack1,&stack2);
    SeqStackPop2(&stack1,&stack2);
    SeqStackPop2(&stack1,&stack2);
    SeqStackPop2(&stack1,&stack2);

    SeqStackPrint(&stack1,"栈1");
    SeqStackPrint(&stack2,"栈2");

    SeqStackType min = SeqStackTopValue(&stack2);
    printf("expect d,actual:%c\n\n",min);
}

//测试取最小元素
void TestMinValue2(){
    SeqStack stack;
    SeqStackInit(&stack);

    TESTHEAD;
    SeqStackPush3(&stack,'d');
    SeqStackPush3(&stack,'e');
    SeqStackPush3(&stack,'f');
    SeqStackPush3(&stack,'a');
    SeqStackPush3(&stack,'c');

    SeqStackPop3(&stack);
    SeqStackPop3(&stack);

    SeqStackPrint(&stack,"栈打印");

    SeqStackType min = SeqStackTopValue(&stack);
    printf("expect d,actual:%c\n\n",min);

    //尝试取栈顶元素
    SeqStackType top = SeqStackGetTop(&stack);
    printf("expect f,actual:%c",top);
}

//测试出栈

int main(){
    TestPush();
    TestPop();
    TesGetTop();
    TestMinValue1();
    TestMinValue2();
    return 0;
}

Makefile:

MinStack:MinStack.c
    gcc $^ -o $@ 
.PHONY:clean
clean:
    rm -rf *.o MinStack

猜你喜欢

转载自blog.csdn.net/devil_net/article/details/80004283
今日推荐