栈适合于处理相反的数据
分类
静态栈:数组实现
动态栈:链表实现
静态栈
1 #define _CRT_SECURE_NO_WARNINGS
2
3 #include <stdio.h>
4 #include <stdlib.h>
5
6 #define N 100
7
8 struct stack//定义栈的结构体
9 {
10 int top;//统计栈中多少个元素,data[top]是栈顶
11 int data[N];//数组用于存放数据
12 };
13 struct stack mystack = { -1,{0} };//创建结构体变量
14 //-1代表栈中没有元素,{0}将数组全部初始化0
15
16 int isempty();//判断栈是否为空
17 int setempty();//设置栈为空
18 int push(int data);//压入一个数据
19 int pop();//取出一个数组
20
21 int isempty()//1代表栈为空,0代表不为空
22 {
23 if (mystack.top == -1)//-1代表栈中没有元素
24 {
25 return 1;
26 }
27 else
28 {
29 return 0;
30 }
31 }
32
33 int setempty()//设置栈为空
34 {
35 mystack.top = -1;
36 }
37
38 int push(int data)//压入一个数据,成功返回1,失败返回0,0代表栈溢出
39 {
40 if (mystack.top + 1 <= N - 1)//没有栈溢出
41 {
42 mystack.data[mystack.top + 1] = data;//数组上升沿一个,接收新的数据
43 mystack.top += 1;//下标加1
44 return 1;
45 }
46 else
47 {
48 return 0;//栈溢出
49 }
50 }
51
52 int pop()//取出一个数组,增加容错性判断,避免为空继续弹出数据,数组越界会导致程序崩溃
53 {
54 if (isempty() == 0)//1代表栈为空,0代表不为空
55 {
56 mystack.top -= 1;//下标减1
57 return mystack.data[mystack.top + 1];//弹出一个数据
58 }
59 else
60 {
61 return -1;
62 }
63 }
64
65 main()
66 {
67 int a[10] = { 1,2,3,4,5,6,7,8,9,10 };
68 int i;
69
70 for (i = 0;i < 10;i++)
71 {
72 push(a[i]);//压入一个数据,成功返回1,失败返回0,0代表栈溢出
73 }
74
75 while (isempty() != 1)
76 {
77 printf("%d\n", pop());//打印弹出数据
78 }
79
80 system("pause");
81 }
静态栈
10进制转换为2进制
1 #define _CRT_SECURE_NO_WARNINGS
2
3 #include <stdio.h>
4 #include <stdlib.h>
5
6 #define N 100
7
8 struct stack//定义栈的结构体
9 {
10 int top;//统计栈中多少个元素,data[top]是栈顶
11 int data[N];//数组用于存放数据
12 };
13 struct stack mystack = { -1,{0} };//创建结构体变量
14 //-1代表栈中没有元素,{0}将数组全部初始化0
15
16 int isempty();//判断栈是否为空
17 int setempty();//设置栈为空
18 int push(int data);//压入一个数据
19 int pop();//取出一个数组
20
21 int isempty()//1代表栈为空,0代表不为空
22 {
23 if (mystack.top == -1)//-1代表栈中没有元素
24 {
25 return 1;
26 }
27 else
28 {
29 return 0;
30 }
31 }
32
33 int setempty()//设置栈为空
34 {
35 mystack.top = -1;
36 }
37
38 int push(int data)//压入一个数据,成功返回1,失败返回0,0代表栈溢出
39 {
40 if (mystack.top + 1 <= N - 1)//没有栈溢出
41 {
42 mystack.data[mystack.top + 1] = data;//数组上升沿一个,接收新的数据
43 mystack.top += 1;//下标加1
44 return 1;
45 }
46 else
47 {
48 return 0;//栈溢出
49 }
50 }
51
52 int pop()//取出一个数组,增加容错性判断,避免为空继续弹出数据,数组越界会导致程序崩溃
53 {
54 if (isempty() == 0)//1代表栈为空,0代表不为空
55 {
56 mystack.top -= 1;//下标减1
57 return mystack.data[mystack.top + 1];//弹出一个数据
58 }
59 else
60 {
61 return -1;
62 }
63 }
64
65 main()
66 {
67 int num = 100;//将num打印出二进制
68
69 while (num)
70 {
71 push(num % 2);//压栈
72 num /= 2;
73 }
74
75 while (isempty() != 1)//判断栈不为空,就一直出栈,1代表栈为空,0代表不为空
76 {
77 printf("%d", pop());
78 }
79
80 system("pause");
81 }
链式栈
1 头文件stacklinknode.h
2 源文件main.c
3 源文件stacklinknode.c
1 头文件stacklinknode.h
该语句的头结点是栈底,不是栈顶
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 #define datatype int
5
6 struct stacknode
7 {
8 int num;
9 datatype data;
10 struct stacknode *pNext;//指针域
11 };
12
13 typedef struct stacknode StackNode;//简写
14
15 StackNode *init(StackNode *phead);//初始化
16
17 StackNode *push(StackNode *phead, int num, datatype data);//进栈,增加头结点,返回头结点
18
19 StackNode *printfall(StackNode *phead);//全部打印
20
21 StackNode *pop(StackNode *phead, StackNode *poutdata);//出栈
22
23 StackNode *freeall(StackNode *phead);//清空
2 源文件main.c
1 #define _CRT_SECURE_NO_WARNINGS
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include "stacklinknode.h"
6
7 main1()
8 {
9 StackNode *phead = NULL;//创建一个链式栈的头结点
10
11 phead = init(phead);//设置栈为空
12
13 phead = push(phead, 1, 1);
14 phead = push(phead, 2, 11);
15 phead = push(phead, 3, 111);
16 phead = push(phead, 4, 1111);
17 phead = push(phead, 5, 11111);
18
19 printf("进栈以后\n");
20 printfall(phead);//全部打印
21
22 printf("清空以后\n");
23 phead = freeall(phead);
24 printfall(phead);//全部打印
25
26 //while (phead->pNext != NULL)
27 //{
28 // printf("出栈\n");
29 // StackNode *pout = (StackNode *)malloc(sizeof(StackNode));
30 // phead = pop(phead, pout);
31 // printf("出栈以后\n");
32 // printfall(phead);//全部打印
33 // printf("出栈以后的数据%d,%d\n", pout->num, pout->data);
34 //}
35
36 system("pause");
37 }
38
39 main()
40 {
41 int num;
42 scanf("%d", &num);
43 printf("num=%d\n", num);
44 StackNode *phead = NULL;//创建一个链式栈的头结点
45
46 while (num)//进栈
47 {
48 phead = push(phead, num % 2, 0);
49 num /= 2;
50 }
51
52 while (phead != NULL)//出栈
53 {
54 StackNode *pout = (StackNode *)malloc(sizeof(StackNode));
55 phead = pop(phead, pout);
56
57 printf("%d", pout->num);
58 }
59
60 system("pause");
61 }
3 源文件stacklinknode.c
1 #include "stacklinknode.h"
2
3 StackNode *init(StackNode *phead)//初始化
4 {
5 return NULL;
6 }
7
8 StackNode *push(StackNode *phead, int num, datatype data)//进栈,增加头结点,返回头结点
9 {
10 StackNode *pnewnode = (StackNode *)malloc(sizeof(StackNode));
11
12 pnewnode->num = num;
13 pnewnode->data = data;
14 pnewnode->pNext = NULL;//开辟结点并赋值
15
16 if (phead == NULL)//空链表,直接连接上
17 {
18 phead = pnewnode;//连接一个结点
19 }
20 else
21 {
22 StackNode *p = phead;
23 while (p->pNext != NULL)
24 {
25 p = p->pNext;//一直向前
26 }
27 p->pNext = pnewnode;//插入
28 }
29
30 return phead;
31 }
32
33 StackNode *printfall(StackNode *phead)//全部打印
34 {
35 if (phead == NULL)
36 {
37 return NULL;
38 }
39 else
40 {
41 printf("%d,%d,%x,%x\n", phead->num, phead->pNext, phead, phead->pNext);
42 printfall(phead->pNext);
43 }
44 }
45
46 StackNode *pop(StackNode *phead, StackNode *poutdata)//出栈
47 {
48 if (phead == NULL)//已经没有元素
49 {
50 return NULL;
51 }
52 else if (phead->pNext == NULL)//只有一个结点
53 {
54 poutdata->num = phead->num;//取出数据
55 poutdata->data = phead->data;
56 free(phead);
57 phead = NULL;
58 return NULL;
59 }
60 else
61 {
62 StackNode *p = phead;//建立指针,返回指针
63 while (p->pNext->pNext != NULL)
64 {
65 p = p->pNext;//循环到倒数第二个结点
66 }
67 poutdata->num = p->pNext->num;//取出数据
68 poutdata->data = p->pNext->data;
69 free(p->pNext);
70 p->pNext = NULL;
71 }
72 }
73
74 StackNode *freeall(StackNode *phead)//清空,算法思想:先把p1后面的结点删除,最后把p1删除
75 {
76 if (phead == NULL)
77 {
78 return NULL;
79 }
80 else
81 {
82 StackNode *p1 = NULL, *p2 = NULL;
83 p1 = phead;//头结点
84
85 while (p1->pNext != NULL)
86 {
87 p2 = p1->pNext;//保存下一个结点
88 p1->pNext = p2->pNext;//跳过p2
89 free(p2);
90 }
91
92 free(phead);
93
94 return NULL;
95 }
96 }
栈的链式存储结构称为链栈,它是运算受限的单链表,其插入和删除操作仅限制在表头位置上(栈顶)进行,因此不必设置头结点,将单链表的头指针head改为栈顶指针top即可。
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 typedef int DataType;//数据类型 5 6 struct stacknode//说明一个结构体 7 { 8 DataType data; 9 struct stacknode * next; 10 }; 11 12 typedef struct stacknode StackNode;//简写 13 14 int StackEmpty(StackNode * top);//判栈空 15 StackNode * Push(StackNode * top, DataType data);//进栈入栈 16 StackNode * Pop(StackNode * top, DataType * x);//退栈出栈 17 DataType GetTop(StackNode * top);//取栈顶元素 18 19 void print(StackNode * top);//遍历,非递归 20 void clear(StackNode * top);//清空 21 22 void main() 23 { 24 StackNode * top = NULL;//头指针 25 int x = 0;//保存删除结点值 26 27 top = Push(top, 1);//进栈入栈 28 top = Push(top, 2); 29 top = Push(top, 3); 30 top = Push(top, 4); 31 32 print(top);//遍历,非递归 33 34 while (!StackEmpty(top))//判栈空 35 { 36 printf("取栈顶元素是%d\n", GetTop(top)); 37 top = Pop(top, &x);//退栈出栈 38 printf("退栈出栈成功,删除结点值是%d\n", x); 39 } 40 41 print(top);//遍历,非递归 42 43 system("pause"); 44 } 45 46 int StackEmpty(StackNode * top)//判栈空 47 { 48 return top == NULL; 49 } 50 51 StackNode * Push(StackNode * top, DataType x)//进栈入栈 52 { 53 StackNode * p = (StackNode *)malloc(sizeof(StackNode));//申请新结点 54 p->data = x; 55 p->next = top;//将新结点*p插入栈顶 56 top = p;//使top指向新的栈顶 57 return top;//返回新栈顶指针 58 } 59 60 StackNode * Pop(StackNode * top, DataType * x)//退栈出栈 61 { 62 StackNode * p = top;//保存栈顶指针 63 if (StackEmpty(top)) 64 { 65 printf("stack empty\n");//栈为空 66 exit(0);//出错退出处理 67 } 68 else 69 { 70 *x = p->data;//保存删除结点值,并带回 71 top = p->next;//栈顶指针指向下一个结点 72 free(p);//删除p所指向的结点 73 return top;//并返删除后的栈顶指针 74 } 75 } 76 77 DataType GetTop(StackNode * top)//取栈顶元素 78 { 79 if (StackEmpty(top)) 80 { 81 printf("stack empty\n");//栈为空 82 exit(0);//出错退出处理 83 } 84 else 85 { 86 return top->data;//返回栈顶结点值 87 } 88 } 89 90 void print(StackNode * top)//遍历,非递归 91 { 92 StackNode * p = top; 93 while (p) 94 { 95 printf("%d ", p->data); 96 p = p->next; 97 } 98 printf("\n"); 99 } 100 101 void clear(StackNode * top)//清空 102 { 103 if (StackEmpty(top)) 104 { 105 return; 106 } 107 else 108 { 109 StackNode *p = top; 110 StackNode *q = NULL; 111 112 while (p->next != NULL) 113 { 114 q = p->next; 115 free(p); 116 p = q; 117 } 118 } 119 }