以下代码中出现的关于基于顺序表实现栈和基于顺序表实现队列的相关操作来自于我的博客:
栈:https://blog.youkuaiyun.com/tongxuexie/article/details/79858068
队列:https://blog.youkuaiyun.com/tongxuexie/article/details/79858973
1.入栈、出栈、取栈中最小元素的事件复杂度均为O(1)(两种方法)
头文件minstack.h
1 //头文件只被编译一次
2 #pragma once
3 #include"seqstack.h"
4 //定义结构体
5 typedef struct MinStack
6 {
7 SeqStack stack;
8 }MinStack;
源文件minstack.c
1 #include<stdio.h>
2 #include"seqstack.h"
3 #include"minstack.h"
4
5 /*==========方法1:出栈、入栈、取栈中最小元素的时间复杂度均为O(1)=======*/
6 //1.初始化
7 //思路:直接对原本的栈进行初始化,即对minstack->stack初始化
8 void MinStackInit(MinStack* minstack)
9 {
10 //非法输入
11 if(minstack==NULL)
12 return;
13 //利用之前所写的基于顺序表的栈进行初始化
14 SeqStackInit(&minstack->stack);
15 }
16 //2.入栈
18 void MinStackPush(MinStack* minstack,SeqStackType value)
19 {
20 //非法输入
21 if(minstack==NULL)
22 return;
23 //取栈顶元素
24 SeqStackType top;
25 int ret=SeqStackTop(&(minstack->stack),&top);
26 //如果取栈顶元素失败,说明为空栈,直接入栈两次value
27 if(ret==0)
28 {
29 SeqStackPush(&(minstack->stack),value);
30 SeqStackPush(&(minstack->stack),value);
31 }
32 else
33 {
34 SeqStackType min=top<value?top:value;
35 //先入栈value
36 SeqStackPush(&(minstack->stack),value);
37 //再入栈min
38 SeqStackPush(&(minstack->stack),min);
39 }
40 }
41 //3.出栈
42 //思路:直接利用SeqStackPop出栈两次即可,因为入栈时入栈了两次
43 void MinStackPop(MinStack* minstack)
44 {
45 //非法输入
46 if(minstack==NULL)
47 return;
48 //出栈两次
49 SeqStackPop(&(minstack->stack));
50 SeqStackPop(&(minstack->stack));
51 }
52 //4.取栈中最小元素
53 //思路:由于入栈时的思想,所以栈顶元素就是最小元素
54 //返回两个信息:1.执行成功与否 2.最小元素的值
55 int MinStackTop(MinStack* minstack,SeqStackType* value)
56 {
57 //非法输入
58 if(minstack==NULL||value==NULL)
59 return 0; //返回0表示执行失败
60 //空栈时
61 if((minstack->stack).size==0)
62 return 0;
63 //取栈顶元素
64 SeqStackTop(&(minstack->stack),value);
65 //返回1表示执行成功
66 return 1;
67 }
68 /*==========测试代码块1=======*/
69 //1.测试MinStackInit
70 void Test_MinStackInit()
71 {
72 HEADER;
73 MinStack minstack;
74 MinStackInit(&minstack);
75 printf("size expected 0,actual %d\n",(&minstack.stack)->size);
76 printf("capacity expected 1000,actual %d\n",(&minstack.stack)->capacity);
77 }
78 //2.测试MinStackPush
79 void Test_MinStackPush()
80 {
81 HEADER;
82 MinStack minstack;
83 MinStackInit(&minstack);
84 MinStackPush(&minstack,'c');
85 MinStackPush(&minstack,'b');
86 MinStackPush(&minstack,'a');
87 MinStackPush(&minstack,'d');
88 SeqStackPrintChar(&(minstack.stack),"入栈");
89 }
90 //3.测试MinStackPop
91 void Test_MinStackPop()
92 {
93 HEADER;
94 MinStack minstack;
95 MinStackInit(&minstack);
96 MinStackPush(&minstack,'c');
97 MinStackPush(&minstack,'b');
98 MinStackPush(&minstack,'a');
99 MinStackPush(&minstack,'d');
100 MinStackPop(&minstack);
101 SeqStackPrintChar(&(minstack.stack),"出栈一次");
102 MinStackPop(&minstack);
103 MinStackPop(&minstack);
104 SeqStackPrintChar(&(minstack.stack),"出栈三次");
105 MinStackPop(&minstack);
106 MinStackPop(&minstack);
107 SeqStackPrintChar(&(minstack.stack),"尝试对空栈出栈");
108 }
109 //4.测试MinStackTop
110 void Test_MinStackTop()
111 {
112 HEADER;
113 MinStack minstack;
114 SeqStackType value;
115 MinStackInit(&minstack);
116 int ret;
117 ret=MinStackTop(&minstack,&value);
118 printf("expected 0,actual %d\n",ret);
119 MinStackPush(&minstack,'c');
120 MinStackPush(&minstack,'b');
121 MinStackPush(&minstack,'a');
122 MinStackPush(&minstack,'d');
123 ret=MinStackTop(&minstack,&value);
124 printf("expected 1,actual %d\n",ret);
125 printf("expected a,actual %c\n",value);
126 MinStackPop(&minstack);
127 MinStackPop(&minstack);
128 ret=MinStackTop(&minstack,&value);
129 printf("expected 1,actual %d\n",ret);
130 printf("expected b,actual %c\n",value);
131 }
132 /*==========方法2:出栈、入栈、取栈中最小元素的时间复杂度均为O(1)=======*/
133 //思路:设置两个栈:1.一个栈用来正常入栈出栈 2.一个栈是对正常栈的栈顶元素与将要入栈的值的较小值进行入栈
134 //1.初始化
135 //思路:利用SeqStackInit对两个栈分别初始化
136 void StackInit(SeqStack* normal_stack,SeqStack* min_stack)
137 {
138 //非法输入
139 if(normal_stack==NULL||min_stack==NULL)
140 return;
141 //对normal_stack初始化
142 SeqStackInit(normal_stack);
143 //对min_stack初始化
144 SeqStackInit(min_stack);
145 }
146 //2.入栈
147 //思路:normal_stack中正常入栈value,min_stack中入栈value与normal_stack的栈顶元素top的较小值min
148 void StackPush(SeqStack* normal_stack,SeqStack* min_stack,SeqStackType value)
149 {
150 //非法输入
151 if(normal_stack==NULL||min_stack==NULL)
152 return;
153 //取normal_stack的栈顶元素
154 SeqStackType top;
155 int ret=SeqStackTop(normal_stack,&top);
156 //如果为空栈,则都入栈value
157 if(ret==0)
158 {
159 SeqStackPush(normal_stack,value);
160 SeqStackPush(min_stack,value);
161 }
162 //如果非空,normal_stack入栈value,min_stack入栈min
163 else
164 {
165 SeqStackType min=top<value?top:value;
166 //normal_stack入栈value
167 SeqStackPush(normal_stack,value);
168 //min_satck入栈min
169 SeqStackPush(min_stack,min);
170 }
171 }
172 //3.出栈
173 //思路:分别对normal_stack和min_stack出栈一次
174 void StackPop(SeqStack* normal_stack,SeqStack* min_stack)
175 {
176 //非法输入
177 if(normal_stack==NULL||min_stack==NULL)
178 return;
179 //对normal_stack出栈
180 SeqStackPop(normal_stack);
181 //对min_stack出栈
182 SeqStackPop(min_stack);
183 }
184 //4.取栈中最小元素
185 //思路:对min_stack取栈顶元素即为normal_stack栈中最小元素
186 //返回两个有效信息:1.是否执行成功,用返回值带出 2.最小元素的值,用参数带出
187 int StackTop(SeqStack* min_stack,SeqStackType* top)
188 {
189 //非法输入
190 if(min_stack==NULL)
191 return 0; //返回0表示执行失败
192 //空栈时
193 if(min_stack->size==0)
194 return 0;
195 //非空栈
196 return SeqStackTop(min_stack,top); //执行成功返回1
197 }
198 /*==============测试代码块2=============*/
199 //1.测试StackInit
200 void Test_StackIn