在进行栈的基本操作之前我们需要知道关于栈的两点知识:
1.栈分为顺序栈与链式栈,顺序栈与顺序表的数据成员相同,不同之处在于顺序栈只能对栈顶元素进行入栈与出栈的操作,因此顺序栈的所有操作时间复杂度都为O(1)。
2.栈的特征:先进后出
下面我们讲栈的基本操作:分为五类,初始化栈,销毁栈,入栈,出栈,取栈顶元素。
对顺序栈而言:初始化栈与销毁栈我们都只需要考虑将栈的有效元素size=0,入栈size++,出栈size--,值得注意的一点是在取栈顶元素时,由于栈是先进后出的原则,我们的栈顶元素要返回的是最后一个入栈元素的地址
对于链式栈而言,这里我们用带头结点的单向链表,此时的初始化不再是对有效元素size的变化了,而是需要将head.data=0,将head.next=NULL;销毁栈也就变成了对申请空间结点的释放,需要使用free();入栈相当于我们链表的头插;出栈由于我们栈的特征是先进后出,所以出栈也就相当于我们链表的头删;取栈顶元素就是将除头结点外第一个结点以*value的方式返回。
下面我们上核心代码
链式栈:
1 #include<stddef.h>
2 #include<stdio.h>
3 #include<stdlib.h>
4 #include"linkstack.h"
5 void LinkStackInit(LinkStack*linkstack)
6 {
7 if(linkstack==NULL)
8 {
9 return;
10 }
11 linkstack->head.data=0;
12 linkstack->head.next=NULL;
13 }
14 LinkNode*CreatNode(LinkType value)
15 {
16 LinkNode*new_node=(LinkNode*)malloc(sizeof(LinkNode));
17 new_node->data=value;
18 new_node->next=NULL;
19 return new_node;
20 }
21 void DestroyNode(LinkNode*to_delete)
22 {
23 if(to_delete==NULL)
24 {
25 return;
26 }
27 free(to_delete);
28 }
29 void LinkStackPush(LinkStack*linkstack,LinkType value)
30 {
31 if(linkstack==NULL)
32 {
33 return;
34 }
35 LinkNode*new_node=CreatNode(value);
36 new_node->next=linkstack->head.next;
37 linkstack->head.next=new_node;
38 }
39 void LinkStackPop(LinkStack*linkstack)
40 {
41 if(linkstack==NULL)
42 {
43 return;
44 }
45 if(linkstack->head.next==NULL)
46 {
47 return;
48 }
49 LinkNode*to_delete=linkstack->head.next;
50 linkstack->head.next=to_delete->next;
51 DestroyNode(to_delete);
52 }
53 int LinkStackTop(LinkStack*linkstack,LinkType* value)
54 {
55 if(linkstack==NULL)
56 {
57 return 0;
58 }
59 if(value==NULL)
60 {
61 return 0;
62 }
63 LinkNode*cur=linkstack->head.next;
64 if(cur==NULL)
65 {
66 return 0;
67 }
68 *value=cur->data;
69 return 1;
70 }
71 void LinkStackDestroy(LinkStack*linkstack)
72 {
73 if(linkstack==NULL)
74 {
75 return;
76 }
77 LinkType tmp=0;
78 while(LinkStackTop(linkstack,&tmp))
79 {
80 LinkStackPop(linkstack);
81 }
82 }
顺序栈:
1 #include<stdio.h>
2 #include"seqstack.h"
3 void SeqStackInit(SeqStack*seqstack)
4 {
5 if(seqstack==NULL)
6 {
7 return;
8 }
9 seqstack->size=0;
10 }
11 void SeqStackDestroy(SeqStack*seqstack)
12 {
13 if(seqstack==NULL)
14 {
15 return;
16 }
17 seqstack->size=0;
18 }
19 void SeqStackPush(SeqStack*seqstack,SeqStackType value)
20 {
21 if(seqstack==NULL)
22 {
23 return;
24 }
25 if(seqstack->size>=SeqStackSize)
26 {
27 return;
28 }
29 seqstack->data[seqstack->size++]=value;
30 }
31 void SeqStackPop(SeqStack*seqstack)
32 {
33 if(seqstack==NULL)
34 {
35 return;
36 }
37 if(seqstack->size==0)
38 {
39 return;
40 }
41 --seqstack->size;
42 }
43 int SeqStackTop(SeqStack*seqstack,SeqStackType*value)
44 {
45 if(seqstack==NULL)
46 {
47 return 0;
48 }
49 if(seqstack->size==0)
50 {
51 return 0;
52 }
53 if(value==NULL)
54 {
55 return 0;
56 }
57 *value=seqstack->data[seqstack->size-1];
58 return 1;
59 }