实现一个栈,出栈、入栈、返回最小值的时间 复杂度为O(1)

实现一个栈,要求实现Push(出栈)、Pop(入栈)、Min(返回最小值)的时间 复杂度为O(1) 

Stack.h

#pragma once
#include <stdio.h>
#include <malloc.h>
#include <assert.h>

typedef int DataType;

typedef struct Stack
{
	DataType* _a;
	int _top;		// 栈顶
	int _capacity;  // 容量 
}Stack;

void StackInit(Stack* ps);//初始化栈
void StackDestory(Stack* ps);//销毁栈
void StackPush(Stack* ps, DataType x);//放入元素
void StackPop(Stack* ps);//弹出元素
DataType StackTop(const Stack* ps);//查找栈顶的元素(即将被弹出的元素)
int StackEmpty(const Stack* ps);//判断栈是否为空
int StackSize(const Stack* ps);//返回栈中有多少个元素
void TestStack();

Stack.c

#include "Stack.h"

//typedef struct Stack
//{
//	DataType* _a;
//	int _top;		// 栈顶
//	int _capacity;  // 容量 
//}Stack;

void StackInit(Stack* ps)
{
	assert(ps);
	ps->_a = (DataType*)malloc(sizeof(DataType)* 3);
	ps->_capacity = 3;
	ps->_top = 0;
}

void StackDestory(Stack* ps)
{
	assert(ps);
	free(ps->_a);
	ps->_a = NULL;
	ps->_capacity = 0;
	ps->_top = 0;
}

void StackPush(Stack* ps, DataType x)
{
	//断言
	assert(ps);
	//判断栈是否已满
	if (ps->_top == ps->_capacity)
	{
		ps->_a = realloc(ps->_a, sizeof(DataType)*(ps->_capacity + 3));
		assert(ps->_a);//重新开辟内存失败会返回空指针
		ps->_capacity += 3;
	}
	//放入
	ps->_a[ps->_top] = x;
	ps->_top++;
}

void StackPop(Stack* ps)
{
	//断言
	assert(ps);
	//判空
	if (ps->_top == 0)
	{
		return;
	}
	//删除
	ps->_top--;
}

DataType StackTop(const Stack* ps)
{
	//断言
	assert(ps);
	//判空
	assert(ps->_top);
	//返回栈顶元素
	return ps->_a[ps->_top - 1];
}

int StackEmpty(const Stack* ps)
{
	//断言
	assert(ps);
	//判空
	if (ps->_top == 0)
	{
		return 0;
	}
	else
	{
		return 1;
	}
}

int StackSize(const Stack* ps)
{
	//断言
	assert(ps);
	//返回栈中有多少元素
	return ps->_top;
}

Stackone.h

#include "Stacktwo.h"
#include "Stack.h"

typedef struct DoubleStack {
	Stack st;//存数据的栈
	NStack nst;//存结构体的栈
}DoubleStack;

void DoubleStackInit(DoubleStack* ds);//初始化
void DoubleStackDestory(DoubleStack* ds);//销毁
void DoubleStackPush(DoubleStack* ds, DataType x);//入
void DoubleStackPop(DoubleStack* ds);//出
DataType DoubleStackTop(const DoubleStack* ds);//栈顶元素
int DoubleStackEmpty(const DoubleStack* ds);//判空
int DoubleStackSize(const DoubleStack* ds);//存入元素多少
int GetMinNum(const DoubleStack* ds);//取得当前最小值

void TestDoubleStack();

Stackone.c

#include "Stackone.h"

void DoubleStackInit(DoubleStack* ds)
{
	assert(ds);
	StackInit(&(ds->st));
	NStackInit(&(ds->nst));
}

void DoubleStackDestory(DoubleStack* ds)
{
	assert(ds);
	StackDestory(&(ds->st));
	NStackDestory(&(ds->nst));
}

DataType DoubleStackTop(const DoubleStack* ds)
{
	assert(ds);
	if ((ds->st)._top == 0)
	{
		printf("空栈\n");
		return -1;
	}
	return StackTop(&ds->st);
}

void DoubleStackPush(DoubleStack* ds, DataType x)
{
	SDataType s;
	SDataType ret;
	assert(ds);
	//存结构体的栈判空
	if (NStackEmpty(&ds->nst) == 0)
	{
		s.count = 1;
		s.num = x;
		StackPush(&ds->st, x);
		NStackPush(&ds->nst, s);
	}
	else
	{
		StackPush(&ds->st, x);
		if (x < NStackTop(&ds->nst).num)
		{
			s.num = x;
			s.count = 1;
			NStackPush(&ds->nst, s);
		}
		else if (x == NStackTop(&ds->nst).num)
		{
			ret = NStackTop(&ds->nst);
			NStackPop(&ds->nst);
			ret.count += 1;
			NStackPush(&ds->nst, ret);
		}
	}
}
void DoubleStackPop(DoubleStack* ds)
{
	SDataType ret;
	assert(ds);
	//获取结构体栈的栈顶元素
	ret = NStackTop(&ds->nst);
	if (ret.num == StackTop(&ds->st))//相等就结构体计数-1或者出栈
	{
		if (ret.count == 1)
		{
			NStackPop(&ds->nst);
		}
		else
		{
			ret.count--;
			NStackPop(&ds->nst);
			NStackPush(&ds->nst, ret);
		}
	}
	StackPop(&ds->st);
}

int DoubleStackEmpty(const DoubleStack* ds)
{
	assert(ds);
	return StackEmpty(&ds->st);
}

int DoubleStackSize(const DoubleStack* ds)
{
	assert(ds);
	return StackSize(&ds->st);
}

int GetMinNum(const DoubleStack* ds)
{
	assert(ds);
	return (NStackTop(&ds->nst)).num;
}

void TestDoubleStack()
{
	int tmp = INT_MIN;
	DoubleStack ds;
	DoubleStackInit(&ds);
	/*DoubleStackPush(&ds, 1);
	DoubleStackPush(&ds, 2);*/
	DoubleStackPush(&ds, -1);
	DoubleStackPush(&ds, 1);
	DoubleStackPush(&ds, 4);
	DoubleStackPush(&ds, 0);
	DoubleStackPush(&ds, -3);
	DoubleStackPush(&ds, 1);
	/*DoubleStackPop(&ds);
	DoubleStackPop(&ds);
	DoubleStackPop(&ds);*/
	DoubleStackPop(&ds);
	tmp = GetMinNum(&ds);
	printf("最小值为:%d\n", tmp);
	DoubleStackDestory(&ds);
}

Stacktwo.h

#ifndef __STACKTWO_H__
#define __STACKTWO_H__

#include <stdio.h>
#include <malloc.h>
#include <assert.h>
#include <stdlib.h>

#define START_SIZE 4
#define ADD_SIZE 3

typedef struct Statistics{
	int num;//数字
	int count;//出现次数
}Statistics;//讲最小值和最小值出现次数定义在一个结构体

typedef Statistics SDataType;

typedef struct NStack
{
	SDataType* _a;//指向存放最小值和出现次数的结构体
	int _top;//栈顶
	int _capacity;//容量 
}NStack;//存结构体的栈

void NStackInit(NStack* ps);//初始化
void NStackDestory(NStack* ps);//销毁
void NStackPush(NStack* ps, SDataType x);//入
void NStackPop(NStack* ps);//出
SDataType NStackTop(const NStack* ps);//栈顶
int NStackEmpty(const NStack* ps);//判空
int NStackSize(const NStack* ps);//元素量

#endif // !__STACKTWO_H__

Stacktwo.c

#include "Stacktwo.h"

void NStackInit(NStack* ps)
{
	ps->_a = (SDataType*)malloc(sizeof(SDataType)*START_SIZE);
	ps->_capacity = START_SIZE;
	ps->_top = 0;
}

void NStackDestory(NStack* ps)
{
	assert(ps);
	if (ps->_a == NULL)
		return;
	free(ps->_a);
	ps->_a = NULL;
}

void NStackPush(NStack* ps, SDataType x)
{
	assert(ps);
	//判断是否需要扩容
	if (ps->_capacity == ps->_top)
	{
		ps->_a = realloc(ps->_a, sizeof(SDataType)*(ps->_capacity + ADD_SIZE));
		ps->_capacity += ADD_SIZE;
		assert(ps->_a);
	}
	ps->_a[ps->_top++] = x;
}

void NStackPop(NStack* ps)
{
	assert(ps);
	if (ps->_top == 0)
		return;
	ps->_top--;
}

SDataType NStackTop(const NStack* ps)
{
	Statistics s;
	s.count = -1;
	s.num = -1;
	assert(ps);
	assert(ps->_top != 0);
	if (ps->_top == 0)
		return s;
	return ps->_a[ps->_top - 1];
}

int NStackEmpty(const NStack* ps)
{
	assert(ps);
	return ps->_top == 0 ? 0 : 1;//0为空、1为非空
}

//获取栈中元素个数
int NStackSize(const NStack* ps)
{
	assert(ps);
	return ps->_top;
}

test.c

#include "Stackone.h"

int main(void)
{

	TestDoubleStack();
	system("pause");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/LiLiLiLaLa/article/details/81779651