zoukankan      html  css  js  c++  java
  • 数据结构(八)栈的链式存储结构

      一、栈的链式存储结构,简称为链栈。思路就是把栈顶放在单链表的头部,通常对于链栈来说,是不需要头结点的。

      二、链栈基本不存在栈满的情况,除非内存已经没有可以使用的空间。对于空栈来说,链表原定义是头指针指向空,那么链栈的空其实就是top=NULL。

      三、栈的链式存储结构的C语言代码实现:

    #include "stdio.h"    
    #include "stdlib.h"   
    #include "io.h"  
    #include "math.h"  
    #include "time.h"
    
    #define OK 1
    #define ERROR 0
    #define TRUE 1
    #define FALSE 0
    #define MAXSIZE 20 /* 存储空间初始分配量 */
    
    typedef int Status; 
    typedef int SElemType; /* SElemType类型根据实际情况而定,这里假设为int */
    
    
    /* 链栈结构 */
    typedef struct StackNode
    {
            SElemType data;
            struct StackNode *next;
    }StackNode,*LinkStackPtr;
    
    
    typedef struct
    {
            LinkStackPtr top;
            int count;
    }LinkStack;
    
    Status visit(SElemType c)
    {
            printf("%d ",c);
            return OK;
    }
    
    /*  构造一个空栈S */
    Status InitStack(LinkStack *S)
    { 
            S->top = (LinkStackPtr)malloc(sizeof(StackNode));
            if(!S->top)
                    return ERROR;
            S->top=NULL;
            S->count=0;
            return OK;
    }
    
    /* 把S置为空栈 */
    Status ClearStack(LinkStack *S)
    { 
            LinkStackPtr p,q;
            p=S->top;
            while(p)
            {  
                    q=p;
                    p=p->next;
                    free(q);
            } 
            S->count=0;
            return OK;
    }
    
    /* 若栈S为空栈,则返回TRUE,否则返回FALSE */
    Status StackEmpty(LinkStack S)
    { 
            if (S.count==0)
                    return TRUE;
            else
                    return FALSE;
    }
    
    /* 返回S的元素个数,即栈的长度 */
    int StackLength(LinkStack S)
    { 
            return S.count;
    }
    
    /* 若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR */
    Status GetTop(LinkStack S,SElemType *e)
    {
            if (S.top==NULL)
                    return ERROR;
            else
                    *e=S.top->data;
            return OK;
    }
    
    /* 插入元素e为新的栈顶元素 */
    Status Push(LinkStack *S,SElemType e)
    {
            LinkStackPtr s=(LinkStackPtr)malloc(sizeof(StackNode)); 
            s->data=e; 
            s->next=S->top;    /* 把当前的栈顶元素赋值给新结点的直接后继,见图中① */
            S->top=s;         /* 将新的结点s赋值给栈顶指针,见图中② */
            S->count++;
            return OK;
    }
    
    /* 若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR */
    Status Pop(LinkStack *S,SElemType *e)
    { 
            LinkStackPtr p;
            if(StackEmpty(*S))
                    return ERROR;
            *e=S->top->data;
            p=S->top;                    /* 将栈顶结点赋值给p,见图中③ */
            S->top=S->top->next;    /* 使得栈顶指针下移一位,指向后一结点,见图中④ */
            free(p);                    /* 释放结点p */        
            S->count--;
            return OK;
    }
    
    Status StackTraverse(LinkStack S)
    {
            LinkStackPtr p;
            p=S.top;
            while(p)
            {
                     visit(p->data);
                     p=p->next;
            }
            printf("
    ");
            return OK;
    }
    
    int main()
    {
            int j;
            LinkStack s;
            int e;
            if(InitStack(&s)==OK)
                    for(j=1;j<=10;j++)
                            Push(&s,j);
            printf("栈中元素依次为:");
            StackTraverse(s);
            Pop(&s,&e);
            printf("弹出的栈顶元素 e=%d
    ",e);
            printf("栈空否:%d(1:空 0:否)
    ",StackEmpty(s));
            GetTop(s,&e);
            printf("栈顶元素 e=%d 栈的长度为%d
    ",e,StackLength(s));
            ClearStack(&s);
            printf("清空栈后,栈空否:%d(1:空 0:否)
    ",StackEmpty(s));
            return 0;
    }
    
    
    输出为:
    栈中元素依次为:10 9 8 7 6 5 4 3 2 1 
    弹出的栈顶元素 e=10
    栈空否:0(1:空 0:否)
    栈顶元素 e=9 栈的长度为9
    清空栈后,栈空否:1(1:空 0:否)

      四、栈的链式存储空间的Java语言代码实现:

    • 接口类:
    package bigjun.iplab.linkStack;
    
    public interface IListStack {
        // 判断顺序栈是否为空
        public boolean isStackEmpty();
        // 将一个已经存在的顺序栈置成空表
        public void stackClear();
        // 求顺序栈的长度
        public int stackLength();
        // 读取顺序栈的栈顶元素
        public int getTopElem() throws Exception;
        // 在顺序栈中插入元素e
        public void stackPush(int e);
        // 删除顺序栈中的栈顶元素
        public void stackPop() throws Exception ;
        // 输出顺序栈中的所有元素
        public void stackTraverse();
    }
    • 节点类:
    package bigjun.iplab.linkStack;
    
    public class Node {
        
        public Integer data;   // 存放结点的数据元素的数据域(int类型不能设置null,而Integer类型可以)
        public Node next;      // 存放后继元素的引用
        
        // 可实现初始化一个空的结点
        public Node() {
            this(null, null);
        }
        
        // 可实现构造一个数据域值为指定参数值,而指针域为空的结点
        public Node(Integer data) {
            this(data, null);
        }
        
        // 可实现构造一个数据域和指针域值都为指定参数的结点
        public Node(Integer data, Node next) {
            this.data = data;
            this.next = next;
        }
        
    }
    • 实现类:
    package bigjun.iplab.linkStack;
    
    public class LinkStack implements IListStack {
        
        public Node top;
        
        public LinkStack() {
            top = new Node();
        }
    
        public boolean isStackEmpty() {
            return top == null;
        }
    
        public void stackClear() {
            top = null;
        }
    
        public int stackLength() {
            Node pNode = top;     // 初始化,pNode指向栈顶元素
            int length = 0;       // length为计数器
            while (pNode != null) 
                pNode = pNode.next;
                ++length;
            return length;
        }
    
        @Override
        public int getTopElem() throws Exception {
            if (!isStackEmpty()) {
                return top.data;
            } else {
                throw new Exception("栈为空,无法获取栈顶元素");
            }
        }
    
        public void stackPush(int e) {
            Node p = new Node(e);
            p.next = top;
            top = p;
        }
    
        public void stackPop() throws Exception {
            if (isStackEmpty()) 
                throw new Exception("栈为空,无法弹出栈顶元素");
            else {
                top = top.next;
            }
        }
    
        public void stackTraverse() {    // 从栈顶元素到栈底元素
            Node p = top;
            System.out.print("此时,链栈中的元素为: ");
            while (p.data != null) {// 这块有一个问题,就是由于Node类的构造函数的原因,第一个Node的data会为空,如果用p != null的话,就会输出一个null
                System.out.print(p.data + " ");
                p = p.next;
            }
            System.out.println();
        }
        
        public static void main(String[] args) throws Exception {
            LinkStack lStack = new LinkStack();
            for (int j = 1; j <= 10; j++) {
                lStack.stackPush(j);
            }
            lStack.stackTraverse();
            
            System.out.println("栈顶元素为: " + lStack.getTopElem());
            System.out.println("栈是否为空: " + lStack.isStackEmpty());
            
            lStack.stackPop();
            lStack.stackTraverse();
            System.out.println("栈顶元素为: " + lStack.getTopElem());
            
            lStack.stackClear();
            System.out.println("栈是否为空: " + lStack.isStackEmpty());
        }
    
    }
    • 输出:
    此时,链栈中的元素为: 10 9 8 7 6 5 4 3 2 1 
    栈顶元素为: 10
    栈是否为空: false
    此时,链栈中的元素为: 9 8 7 6 5 4 3 2 1 
    栈顶元素为: 9
    栈是否为空: true
  • 相关阅读:
    20210131
    20210130
    20210129
    20210128
    20210127
    例3-7
    例3-5
    例3-4
    例3-3
    例3-2
  • 原文地址:https://www.cnblogs.com/BigJunOba/p/9183390.html
Copyright © 2011-2022 走看看