【经典数据结构算法】(2)设计包含min的栈

来源:互联网 发布:无法创建java虚拟机 编辑:程序博客网 时间:2024/05/17 06:28
  1 /*
2 * 题目:
3 * 设计包含min的栈
4 * 定义栈的数据结构,要求添加一个min函数,能够得到栈的最小元素。
5 * 要求函数min、push以及pop的时间复杂度都是O(1)
6 */
7
8 /*
9 * 分析:
10 * 自己曾经用了一天时间,也没有想出,后来看了别人的分析才知道比较好的解答方法。
11 * 这道题是典型的用空间复杂度换时间复杂度的问题,关键点在于如何保存最小的元素。
12 * 既然要求了时间复杂度低,那么就需要较高的空间复杂度,方法是设计另外一个平行栈,用来保存当前栈的最小元素。
13 * 考虑正常的栈p,和保存p中最小值的栈pmin。初始状态下p和pmin都为空,当push第一个元素的时候,将它push进p和pmin。
14 * 接下来的每次push,比较要push进来的元素与pmin中的栈顶元素,如果前者大于后者,那么只push进p即可;否则的话,
15 * 将它push进p和pmin。考虑pop的时候,p栈顶的元素只可能大于等于pmin栈顶的元素。
16 * 当p和pmin栈顶的元素相等的时候,将两者都pop出,否则的话,只pop出p的栈顶。
17 * 以下代码即为以上思想的实现。
18 */
19
20 #include "stdafx.h"
21 #include <stdio.h>
22 #include <stdlib.h>
23 /*
24 * 定义基本的结点指针
25 */
26 typedef struct node *link;
27 struct node
28 {
29 int value;
30 link next;
31 link prev;
32 };
33 /*
34 * 结点初始化函数
35 */
36 link initNode(int i)
37 {
38 link t=(link)malloc(sizeof(*t));
39 t->next=NULL;
40 t->prev=NULL;
41 t->value=i;
42 return t;
43 }
44 /*
45 * 栈p和栈pmin的栈顶p,pmin
46 */
47 link p,pmin;
48 /*
49 * push函数
50 */
51 void push(int i)
52 {
53 if(p==NULL)
54 {
55 p=initNode(i);
56 pmin=initNode(i);
57 }
58 else
59 {
60 p->next=initNode(i);
61 p->next->prev=p;
62 p=p->next;
63 if(p->value<=pmin->value)
64 {
65 pmin->next=initNode(i);
66 pmin->next->prev=pmin;
67 pmin=pmin->next;
68 }
69 }
70 }
71 /*
72 * pop函数
73 */
74 link pop()
75 {
76 link ret;
77 if(p==NULL)
78 {
79 printf("已经达到栈底");
80 ret=NULL;
81 }
82 else
83 {
84 if(p->prev==NULL)
85 {
86 ret=p;
87 p=NULL;
88 pmin=NULL;
89 }
90 else
91 {
92 if(p->value==pmin->value)
93 {
94 pmin=pmin->prev;
95 pmin->next=NULL;
96 }
97 ret=p;
98 p=p->prev;
99 p->next=NULL;
100 }
101 }
102 return ret;
103 }
104
105 int min()
106 {
107 if(pmin==NULL)
108 {
109 printf("已经到达栈底");
110 return -1;
111 }
112 else
113 return pmin->value;
114 }
115 int main(int argc, char* argv[])
116 {
117 push(10);
118 printf("min:%d\n",min());
119 push(7);
120 printf("min:%d\n",min());
121 push(3);
122 printf("min:%d\n",min());
123 push(3);
124 printf("min:%d\n",min());
125 push(8);
126 printf("min:%d\n",min());
127 push(5);
128 printf("min:%d\n",min());
129 push(2);
130 printf("min:%d\n",min());
131 push(7);
132 printf("min:%d\n",min());
133 printf("以下开始pop元素\n");
134 printf("min:%d\n",min());
135 pop();
136 printf("min:%d\n",min());
137 pop();
138 printf("min:%d\n",min());
139 pop();
140 printf("min:%d\n",min());
141 pop();
142 printf("min:%d\n",min());
143 pop();
144 printf("min:%d\n",min());
145 pop();
146 printf("min:%d\n",min());
147 pop();
148 printf("min:%d\n",min());
149 pop();
150 printf("min:%d\n",min());
151 return 0;
152 }

测试数据:连续push:10、7、3、3、8、5、2、6;然后连续pop:

原创粉丝点击