数据结构(八)栈的链式存储结构

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

  二、链栈基本不存在栈满的情况,除非内存已经没有可以使用的空间。对于空栈来说,链表原定义是头指针指向空,那么链栈的空其实就是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("\n");
        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\n",e);
        printf("栈空否:%d(1:空 0:否)\n",StackEmpty(s));
        GetTop(s,&e);
        printf("栈顶元素 e=%d 栈的长度为%d\n",e,StackLength(s));
        ClearStack(&s);
        printf("清空栈后,栈空否:%d(1:空 0:否)\n",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
posted @ 2018-06-14 15:48  BigJunOba  阅读(2571)  评论(0编辑  收藏  举报