栈适合于处理相反的数据

分类

静态栈:数组实现

动态栈:链表实现

 

静态栈

 

 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 }