zoukankan      html  css  js  c++  java
  • 栈的链式存储结构及应用(C、Java代码)

    链式存储结构最大的好处就是没有空间的限制,可以通过指针指向将结点像以链的形式把结点链接,我们熟悉的线性表就有链式存储结构。

    当然,栈同样有链式存储结构,栈的链式存储结构,简称链栈。

    从图片可以看到,和单链表很像,拥有一个头指针top,又称作栈顶指针,所以此时就不再需要单链表里面的头结点了。

    对于链栈来说,基本不存在栈满的情况,除非计算机内存已经没有了可使用的空间,如果真的存在,那么计算机系统已经面临着即将死机崩溃的情况,而不是这个链栈是否溢出的问题了。

    对于空栈来说,链表的定义是头指针指向NULL,而链栈是top=NULL

    链栈的结构定义:

     1 /*链栈的定义需要用到两个结构体*/
     2 typedef struct StackNode{        //单链表节点类型
     3     int data;
     4     StackNode* next;
     5 
     6 }StrackNode;
     7 typedef struct StackNode *LinkStackPtr;
     8 
     9 typedef struct {    //
    10 
    11     LinkStackPtr top;   //栈底指针
    12     int count;          
    13 
    14 }LinkStact;

    进栈操作

    /*入栈*/
    void PushStack(LinkStact *s,int e){   //这边栈应该传地址
    
        LinkStackPtr a =(StackNode*)malloc(sizeof(StackNode));   //新的节点
        a->data = e;
        a->next = s->top; //把当前的栈顶元素赋值给新结点的直接后继
        s->top =a;  /* 将新的结点s赋值给栈顶指针 */
        s->count++;        
    }

     这里重新回忆一下参数传参的两种方式:传值、传地址。

    传值:传值无非就是实参拷贝传递给形参,单向传递(实参->形参),二者中间做了一个拷贝动作,即两者的实际地址不同了,所以对任何一方的操作都不会影响到另一方。

    传地址:形参和实参是同一个变量,即使用相同的内存空间,二者有相同的地址,修改任意一方都将相互影响。

     出栈操作

    /*出栈,并返回栈顶元素*/
    int PopStack(LinkStact *s){
        int top;
        LinkStackPtr p;
        p = s->top;      /* 将栈顶结点赋值给p */
        if(p ==NULL)
            return -1;
        top = p->data;
        s->top=s->top->next;  /* 使得栈顶指针下移一位,指向后一结点,即指向新的栈顶 */
        free(p);   //释放内存
        s->count--;   //长度减一
    
        return top;
    }

    使用栈时确记要记得给栈初始化

    1 /*初始化一个空栈*/
    2 int InitStack(LinkStact *s){
    3     s->top = (StackNode *)malloc(sizeof(StackNode));
    4     if(!s->top)
    5         return 0;
    6     s->top=NULL;
    7     s->count=0;
    8     return 1;
    9 }

    遍历栈操作

     1 /*遍历栈*/
     2 void StackTraverse(LinkStact s){
     3     LinkStackPtr p;
     4     p=s.top;   //指针指向栈顶
     5     while(p)        //当栈不为空时
     6     {
     7         printf("%d ",p->data);
     8         p =p->next;
     9     }
    10 }

    清空栈操作

     1 /*清空栈*/
     2 void ClearStack(LinkStact *s){
     3 
     4     LinkStackPtr p,q;
     5     p = s->top;   //取栈顶
     6     while(p){
     7         q=p;
     8         p=p->next;
     9         free(q);
    10     }
    11     s->count=0;
    12 }

    其他的操作见代码:

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 
      4 /*链栈的定义需要用到两个结构体*/
      5 typedef struct StackNode{        //单链表节点类型
      6     int data;
      7     StackNode* next;
      8 
      9 }StrackNode;
     10 typedef struct StackNode *LinkStackPtr;
     11 
     12 typedef struct {    //
     13 
     14     LinkStackPtr top;   //栈底指针
     15     int count;          
     16 
     17 }LinkStact;
     18 
     19 /*初始化一个空栈*/
     20 int InitStack(LinkStact *s){
     21     s->top = (StackNode *)malloc(sizeof(StackNode));
     22     if(!s->top)
     23         return 0;
     24     s->top=NULL;
     25     s->count=0;
     26     return 1;
     27 }
     28 
     29 /*清空栈*/
     30 void ClearStack(LinkStact *s){
     31 
     32     LinkStackPtr p,q;
     33     p = s->top;   //取栈顶
     34     while(p){
     35         q=p;
     36         p=p->next;
     37         free(q);
     38     }
     39     s->count=0;
     40 }
     41 
     42 /*判断是否为空栈,为空返回0,否则返回1*/
     43 int StackEmpty(LinkStact *s){
     44     if(s->count==0)
     45         return 1;
     46     else
     47         return 0;
     48 }
     49 
     50 /*入栈*/
     51 void PushStack(LinkStact *s,int e){   //这边栈应该传地址
     52 
     53     LinkStackPtr a =(StackNode*)malloc(sizeof(StackNode));   //新的节点
     54     a->data = e;
     55     a->next = s->top; //把当前的栈顶元素赋值给新结点的直接后继
     56     s->top =a;  /* 将新的结点s赋值给栈顶指针 */
     57     s->count++;        
     58 }
     59 
     60 /*出栈,并返回栈顶元素*/
     61 int PopStack(LinkStact *s){
     62     int top;
     63     LinkStackPtr p;
     64     p = s->top;      /* 将栈顶结点赋值给p */
     65     if(p ==NULL)
     66         return -1;
     67     top = p->data;
     68     s->top=s->top->next;  /* 使得栈顶指针下移一位,指向后一结点,即指向新的栈顶 */
     69     free(p);   //释放内存
     70     s->count--;   //长度减一
     71 
     72     return top;
     73 }
     74 
     75 /*返回栈的长度*/
     76 int StackLength(LinkStact s){
     77     return s.count;
     78 }
     79 
     80 /*若栈不为空,则返回栈顶元素*/
     81 int GetTop(LinkStact s){
     82     if(s.count == NULL)
     83         return 0;
     84     else
     85         return s.top->data;
     86 }
     87 
     88 /*遍历栈*/
     89 void StackTraverse(LinkStact s){
     90     LinkStackPtr p;
     91     p=s.top;   //指针指向栈顶
     92     while(p)        //当栈不为空时
     93     {
     94         printf("%d ",p->data);
     95         p =p->next;
     96     }
     97 }
     98 
     99 int main(){
    100     LinkStact s;
    101     printf("进栈10个数据
    ");
    102     if(InitStack(&s)==1){
    103         for(int i=1;i<=10;i++)
    104             PushStack(&s,i);
    105     }
    106     StackTraverse(s);   //遍历栈
    107     printf("
    ");
    108     
    109     printf("进栈后长度:%d
    ",StackLength(s));
    110 
    111     printf("出栈,取栈顶元素,栈顶元素是 :%d",GetTop(s));
    112     printf("
    ");
    113 
    114     printf("栈是否为空? 1:0:%d
    ",StackEmpty(&s));
    115 
    116     printf("出栈一个元素:%d
    ",PopStack(&s));
    117 
    118     StackTraverse(s);
    119 
    120 
    121     return 0;
    122 }
    View Code

    另外附上Java代码

     1 package 栈的链式存储间结构;
     2 
     3 public class LinkStack {
     4     StackNode top; // 类似于单链表节点
     5     int count; // 元素个数
     6 
     7     /**
     8      * 栈的初始化
     9      */
    10     @SuppressWarnings("unused")
    11     public void initStack(LinkStack S) {
    12         S = new LinkStack();
    13         if (S == null) {
    14             System.out.println("创建栈失败...");
    15         } else
    16             S.count = 0;
    17         S.top = null;
    18     }
    19 
    20     /**
    21      * 入栈操作 ,n 表示进栈元素
    22      */
    23     public void pushStack(LinkStack S, int n) {
    24         StackNode node = new StackNode();
    25         node.data = n;
    26         node.next = S.top; // 新节点的next指向栈顶
    27         S.top = node; // 栈底指向新节点,类似单链表的插入操作
    28         S.count++;
    29     }
    30 
    31     /**
    32      * 出栈操作
    33      */
    34     public void popStack(LinkStack S) {
    35         if (S.count != 0) {
    36             System.out.println("出栈一个元素:" + S.top.data);
    37             S.top = S.top.next; // 栈底指针下移
    38             S.count--;
    39         }
    40     }
    41 
    42     /**
    43      * 求栈顶元素
    44      */
    45     public int getTop(LinkStack S) {
    46         if (S.top != null) {
    47             return S.top.data;
    48         } else
    49             return 0;
    50     }
    51 
    52     /**
    53      * 遍历栈元素,
    54      */
    55     public void traverseStack(LinkStack S) {
    56         StackNode p; // 确记:遍历时top指针不能移动,所以只能新建一个对象来指向top的位置
    57         p = S.top;
    58         while (p != null) {
    59             System.out.print(p.data + " ");
    60             p = p.next;
    61         }
    62     }
    63 
    64     /**
    65      * 判断栈是否为空
    66      * 
    67      */
    68     public boolean elemptyStack(LinkStack S) {
    69         if (S.count == 0)
    70             return true;
    71         else
    72             return false;
    73     }
    74 
    75     /**
    76      * 清空栈
    77      */
    78     public void clearStack(LinkStack S) {
    79         while (S.count != 0) {
    80             S.top = S.top.next; // 移动到下一位
    81             S.count--;
    82         }
    83     }
    84 
    85     /**
    86      * 获取栈长度
    87      */
    88     public int getStackLength(LinkStack S) {
    89         return S.count;
    90     }
    91 
    92 }
    View Code
    1 package 栈的链式存储间结构;
    2 
    3 public class StackNode {
    4     int data;
    5     StackNode next;
    6 }
    View Code
     1 package 栈的链式存储间结构;
     2 
     3 public class Test {
     4 
     5     public static void main(String[] args) {
     6         LinkStack stack = new LinkStack();
     7         System.out.println("初始化栈...");
     8         stack.initStack(stack);
     9         for (int i = 0; i < 10; i++)
    10             stack.pushStack(stack, i);
    11         System.out.println("进栈元素:");
    12         stack.traverseStack(stack);
    13         System.out.println("");
    14 
    15         System.out.println("取栈顶元素:");
    16         System.out.println(stack.getTop(stack));
    17 
    18         System.out.println("栈是否为空:" + stack.elemptyStack(stack));
    19 
    20         stack.popStack(stack);
    21         System.out.println("重新遍历栈元素:");
    22         stack.traverseStack(stack);
    23 
    24         System.out.println("清空栈:");
    25         stack.clearStack(stack);
    26         System.out.println("重新遍历栈元素:");
    27         stack.traverseStack(stack);
    28 
    29         System.out.println("获取栈长度:" + stack.getStackLength(stack));
    30     }
    31 
    32 }
    View Code

    完毕 - . -

  • 相关阅读:
    Kubernetes Admission Controller解析
    容器化Node Exporter对主机磁盘使用率的监控问题
    Prometheus监控指标的label注入方法
    Prometheus告警模型分析
    Kubernetes Controller执行框架解析
    深入理解Istio核心组件之Pilot
    Prometheus存储模型分析
    如何利用Prometheus监控你的应用
    Prometheus在Kubernetes下的服务发现机制
    JSON字符串和js对象转换
  • 原文地址:https://www.cnblogs.com/liuzeyu12a/p/10306640.html
Copyright © 2011-2022 走看看