大话数据结构系列之链栈结构(九)

链栈的定义

栈的链式存储结构,简称为链栈

链栈 VS 顺序栈
如果使用过程中元素变化不可预料,有时很小,有时非常大,最好使用链栈。
反之,如果它的变化在可控范围内,建议使用顺序栈会更好一点儿(节省空间)

链栈代码实现( C、Java)

C 语言实现

#include "stdio.h"    
#include "stdlib.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;
}

Java 语言实现

package com.example.stack;

/* 链栈结构 */
public class LinkStack<T> {

    
    @SuppressWarnings("hiding")
    class Node<T> {
    
        protected Node<T> next;
        
        protected T data;
        
        public Node(T data){
            this.data = data;
        }
    }
    
    /* 栈顶节点 */
    public Node<T> head;
    
    /*链栈长度 */
    private int size;
    
    /*  构造一个空栈S */
    int initStack(){
        this.head = new Node<T>(null);
        this.size = 0;
        return 1;
    }
    
    /* 把S置为空栈 */
    int clearStack(){
        //无法做到像C语言中的free(),直接放到内存空间
        Node<T> tempNode = new Node<T>(null);
        tempNode = this.head;
        while(tempNode != null){
            tempNode = tempNode.next;
        }
        return 1;
    }
    
    /* 若栈S为空栈,则返回TRUE,否则返回FALSE */
    boolean stackEmpty(){
        if(this.size == 0)
            return true;
        else
            return false;
    }
    
    
    /* 返回的size,即栈的长度 */
    int stackLength(){
        return this.size;
    }
    
    /* 若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR */
    T getTop(){
        if(this.head == null)
            throw new NullPointerException("为空栈!");
        else
            return this.head.data;
    }
    
    /* 插入元素e为新的栈顶元素 
     * 这里的next类似于线性链表结构的 prior
     */
    int push(T elem){
        Node<T> tempNode = new Node<T>(elem);
        tempNode.next = this.head;
        this.head = tempNode;
        this.head = tempNode;
        this.size++;
        return 1;
    }
    
    /* 若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR */
    T pop(){
        if(this.size == 0)
            throw new NullPointerException("为空栈!");
        T elem = this.head.data;
        this.head = this.head.next;
        this.size--;
        return elem;
    }
    
    /* 从栈底到栈顶依次对栈中每个元素显示 */
    void stackTraverse(){
        Node<T> tempNode = this.head;
        while(tempNode.data != null){
            System.out.println(tempNode.data);
            tempNode = tempNode.next;
        }
    }
     
     public static void main(String[] args){
            int j;
            LinkStack<Integer> s = new LinkStack<Integer>();
            if(s.initStack() == 1)
                    for(j=1;j<=10;j++)
                            s.push(j);
            System.out.println("栈中元素依次为:");
            s.stackTraverse();
            System.out.println("弹出的栈顶元素 e=%d\n"+s.pop());
            System.out.println("栈空否:%d(1:空 0:否)\n"+s.stackEmpty());
            System.out.println("栈顶元素 e=%d "+s.getTop()+"栈的长度为%d\n"+s.stackLength());
            s.clearStack();
            System.out.println("清空栈后,栈空否:%d(1:空 0:否)\n"+s.stackEmpty());
     }
    
}

发布了222 篇原创文章 · 获赞 54 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/weixin_39966065/article/details/104021987