栈的链式存储结构及应用(CJava代码)

Posted liuzeyu12a

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了栈的链式存储结构及应用(CJava代码)相关的知识,希望对你有一定的参考价值。

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

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

从图片可以看到,和单链表很像,拥有一个头指针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代码

 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

完毕 - . -

以上是关于栈的链式存储结构及应用(CJava代码)的主要内容,如果未能解决你的问题,请参考以下文章

数据结构&算法08-栈概念&源码

数据结构栈的链式存储结构

C/C++数据结构-完整代码栈(栈的顺序存储,栈的链式存储,就近匹配,中缀表达式和后缀表达式)

栈的链式存储结构

数据结构学习笔记——链式存储结构实现栈

数据结构学习笔记——链式存储结构实现栈(链栈)