数据结构---03---顺序栈---20205106009---郭睿玥

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
/*郭睿玥第三次算法实验作业*/
 
 
/*实验原理
    栈是一种受限的线性表,由于规定了栈的入栈与出栈只能在一端进行,故而产生了后进先出,
先进后出的结果,因而常应用于具有这种特性的问题中进行模拟,广泛使用于程序设计中。
    顺序栈是栈的顺序映像的实现,可采用静态顺序存储结构和动态存储结构,在静态顺序存储时
需分配一个预先设定大小的数组与栈顶指示器,规定若栈为空则栈顶指示器为-1,否则栈顶指示器
指向当前栈顶元素,栈满则栈顶指示器为预先设定的值减1,入栈时需栈顶指示器加1,此时元素入
栈即可,出栈时将当前栈顶指示器指向的元素返回,栈顶指示器减1即可。动态存储时需动态申请
预先设定的空间交给栈底指针,对栈操作时栈底指针不动,栈顶指针移动,为方便操作可将栈的长
度封装进来,动态实现的优点在于若空间不够时,可再申请一个增量的空间进行补充,但缺点是较
静态而言稍复杂一些。
*/
 
/*实验环境
CodeBlocks*/
 
 
/*实验目的
掌握顺序栈的基本操作:初始化栈、判栈空、入栈、出栈、取栈顶数据元素等运算及程序实现方法。
*/
 
 
 
/*实验内容
(1)定义栈的顺序存取结构。
(2)分别定义顺序栈的基本操作(初始化栈、判栈空、入栈、出栈等)。
(3)设计一个测试主函数进行测试。
(4)根据自己的理解添加更多的内容。
*/
 
 
 
/*算法实现如下*/
# include <stdio.h>
# include <malloc.h>
# include <stdlib.h>
#define STACK 5// 初始化栈的最大长度
#define STACKINCREMENT 3// 若栈最大空间不够时,需要增加的长度
 
typedef int Status;// 定义函数返回值类型
typedef int SElemType; // 定义每条数据的结构体类型
 
 
typedef struct {
       SElemType *top;// 栈顶指针
       SElemType *bottom;// 栈底指针
       SElemType stacksize;// 栈的最大长度
}stack;
 
Status initstack(stack *s)
{
    s->bottom=(SElemType*) malloc(sizeof(SElemType)*STACK ); // 分配初始空间
    if(!s->bottom) return 0;
    s->top=s->bottom;// 栈顶与栈底相同
    s->stacksize=STACK;// 栈的最大长度等于初始长度
    printf("创建成功\n");
    return 1;
}
 
Status push(stack *s,SElemType e)// 进栈,参数e是要进栈的元素
{// 若栈的最大长度不会够用时,重新开辟,增大长度
    if(s->top-s->bottom>=s->stacksize)
    {
        s->bottom=(SElemType*)realloc(s->bottom,sizeof(SElemType)*(s->stacksize+ STACKINCREMENT));
        if (!s->bottom)  return  0;
        s->top=s->bottom+s->stacksize ;// 栈顶指针为栈底指针加上栈之前的最大长度
        s->stacksize+=STACKINCREMENT;  // 栈当前的最大长度等于栈之前的最大长度与增加的长度之和
    }
    *s->top++=e;// 先赋值,后栈顶指针上移
    return 1;
}
 
Status stackempty(stack *s)// 判断栈是否为空,只需要判断栈顶指针与栈底指针是否相同即可
{
    if(s->bottom==s->top)  {
            printf("是空栈\n");
            return 1;
    }
    return 0;
}
 
void clearstack(stack *s)
{
    if(!stackempty(s))
    s->top = s->bottom;
    printf("清空成功\n");
    return 0;
}
 
Status DestroyStack(stack *s )// 销毁栈,释放栈空间,栈顶栈底指针置为NULL,长度置为0
{
    free(s->bottom);
    s->stacksize = 0;
    s->bottom = s->top = NULL;
    printf("销毁成功\n");
    return 0;
}
 
Status pop(stack *s)// 出栈
{
    if(stackempty(s)) return 0;
    s->top--;
    return 1;
}
 
Status getop(stack*s)// 获取栈顶的元素,参数e用来存放栈顶的元素
{
    SElemType e;
    if(stackempty(s)) return 0;
    e=*(s->top-1);
    return e;
}
 
Status traverse(stack*s)// 遍历栈,依次打印每个元素
{
    if(stackempty(s))
         return 0;
    SElemType * p;
    p=s->top;// 由栈顶依次向下遍历
     while (p!=s->bottom)
    {   p--;
        printf("%d",*p);
        printf("\n");
    }
    return 1;
}
 
 
 
int main()
{   stack S;
    int choice;
    do {/*显示操作界面*/
        printf("***********************\n");
        printf("*      1. 构建空栈*\n");
        printf("*      2. 清空栈*\n");
        printf("*      3. 栈的判空*\n");
        printf("*      4. 压栈*\n");
        printf("*      5. 弹栈 *\n");
        printf("*      6. 获取栈顶元素\n");
        printf("*      7. 显示全部元素\n");
        printf("*      8. 销毁栈\n");
        printf("*      0. 退出。 *\n");
        printf("***********************\n");
        printf("\n");
        printf("请选择你要操作的选项:");
        scanf("%d", &choice);//输入需要进行的选项
        printf("\n");
        switch (choice) {
        case 1:{
                initstack(&S);
                break;
            }
        case 2:{
                clearstack(&S);
                break;
            }
        case 3:{
                stackempty(&S);
                break;
            }
        case 4:{
                int i, n, f;
                printf("输入你想要入栈的元素个数:\n");
                scanf("%d", &n);
                for (i = 1; i <= n; i++) {
                        printf("请输入新一项");
                        scanf("%d", &f);
                        push(&S, f);
                }
                break;
            }
        case 5:{
                pop(&S);
                break;
            }
        case 6:{
                printf("%d\n",getop(&S));
                break;
            }
        case 7:{
                traverse(&S);
                break;
            }
        case 8:{
            DestroyStack(&S);
            break;
            }
        case 0:{
                printf("\n退出系统成功!请按任意键结束!\n");//退出程序
                exit(0);
            }
            break;
        }
    } while (choice);//只要选择不为需要进行的功能不为0则该程序可以一直进行下去
}
 
/*以下是实验结果
操作界面如下
1. 构建空栈*
2. 清空栈*
3. 栈的判空*
4. 压栈*
5. 弹栈
6. 获取栈顶元素
7. 显示全部元素
8. 销毁栈
0. 退出。
郭睿玥 算法与数据结构第三次作业
(以下内容中操作界面的显示已经省略)
 
输入
请选择你要操作的选项:1
创建成功
请选择你要操作的选项:3
是空栈
请选择你要操作的选项:4
请输入你要入栈元素的个数;4
请输入新的一项;6
请输入新的一项7
请输入新的一项5
请输入新的一项9
请选择你要操作的选项:5
请选择你要操作的选项:6
5
请选择你要操作的选项:7
5
7
6
请选择你要操作的选项:2
清空成功
请选择你要操作的选项:8
销毁成功
请选择你要操作的选项:0
退出系统成功!
*/

 

posted @   张同光  阅读(170)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示