數據結構(八)棧的鏈式存儲結構


  一、棧的鏈式存儲結構,簡稱為鏈棧。思路就是把棧頂放在單鏈表的頭部,通常對於鏈棧來說,是不需要頭結點的。

  二、鏈棧基本不存在棧滿的情況,除非內存已經沒有可以使用的空間。對於空棧來說,鏈表原定義是頭指針指向空,那么鏈棧的空其實就是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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM