• 3.1栈


    栈适合于处理相反的数据

    分类

    静态栈:数组实现

    动态栈:链表实现

    静态栈

     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
    ", 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("进栈以后
    ");
    20     printfall(phead);//全部打印
    21 
    22     printf("清空以后
    ");
    23     phead = freeall(phead);
    24     printfall(phead);//全部打印
    25 
    26                      //while (phead->pNext != NULL)
    27                      //{
    28                      //    printf("出栈
    ");
    29                      //    StackNode *pout = (StackNode *)malloc(sizeof(StackNode));
    30                      //    phead = pop(phead, pout);
    31                      //    printf("出栈以后
    ");
    32                      //    printfall(phead);//全部打印
    33                      //    printf("出栈以后的数据%d,%d
    ", 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
    ", 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
    ", 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
    ", GetTop(top));
     37         top = Pop(top, &x);//退栈出栈
     38         printf("退栈出栈成功,删除结点值是%d
    ", 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
    ");//栈为空
     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
    ");//栈为空
     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("
    ");
     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 }
  • 相关阅读:
    Java设计模式之责任链模式
    多线程几个常用方法的实例
    Activiti工作流
    Java线程常用方法汇总
    Java线程的几个概念
    多线程——实现Callable接口
    java对象在JVM堆中的数据结构
    对计算机世界的认知
    wait、notify为什么要放在同步代码块中
    java synchronized关键字的底层实现
  • 原文地址:https://www.cnblogs.com/denggelin/p/5689106.html
走看看 - 开发者的网上家园