栈的链式存储结构及应用(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个数据\n");
102     if(InitStack(&s)==1){
103         for(int i=1;i<=10;i++)
104             PushStack(&s,i);
105     }
106     StackTraverse(s);   //遍历栈
107     printf("\n");
108     
109     printf("进栈后长度:%d\n",StackLength(s));
110 
111     printf("出栈,取栈顶元素,栈顶元素是 :%d",GetTop(s));
112     printf("\n");
113 
114     printf("栈是否为空? 1:0:%d\n",StackEmpty(&s));
115 
116     printf("出栈一个元素:%d\n",PopStack(&s));
117 
118     StackTraverse(s);
119 
120 
121     return 0;
122 }
View Code

另外附上Java代码

猜你喜欢

转载自www.cnblogs.com/liuzeyu12a/p/10306640.html
今日推荐