首頁 Java java教程 堆疊有幾種實作方式?

堆疊有幾種實作方式?

Jun 28, 2020 am 11:42 AM
堆疊 實現方式

堆疊有3種實作方式,實作方式為:1、靜態數組堆棧,要求結構的長度固定,長度在編譯時候就得確定;2、動態數組堆棧,長度可以在運行時候才確定以及可以更改原來數組的長度;3、鍊式結構堆棧,無長度上線,需要的時候再申請分配記憶體空間。

堆疊有幾種實作方式?

堆疊有3種實作方式,實作方式為:

一、靜態陣列堆疊

  在靜態數組堆疊中,STACK_SIZE表示堆疊所能儲存的元素的最大值,用top_element作為數組下標來表示堆疊裡面的元素,當top_element == -1的時候表示堆疊為空;當top_element == STACK_SIZE - 1的時候表示堆疊為滿。 push的時候top_element加1,top_element == 0時表示第一個堆疊元素;pop的時候top_element減1。

a_stack.c 原始碼如下:

[cpp] view plain copy
/* 
**  
** 静态数组实现堆栈程序 a_stack.c ,数组长度由#define确定 
*/  
  
#include"stack.h"  
#include<assert.h>  
#include<stdio.h>  
  
#define STACK_SIZE 100 /* 堆栈最大容纳元素数量 */  
  
/* 
** 存储堆栈中的数组和一个指向堆栈顶部元素的指针 
*/  
static STACK_TYPE stack[STACK_SIZE];  
static int top_element = -1;  
  
/* push */  
void push(STACK_TYPE value)  
{  
    assert(!is_full()); /* 压入堆栈之前先判断是否堆栈已满*/  
    top_element += 1;  
    stack[top_element] = value;  
}  
  
/* pop */  
void pop(void)  
{  
    assert(!is_empty()); /* 弹出堆栈之前先判断是否堆栈已空 */  
    top_element -= 1;  
}  
  
/* top */  
STACK_TYPE top(void)  
{  
    assert(!is_empty());  
    return stack[top_element];  
}  
  
/* is_empty */  
int is_empty(void)  
{  
    return top_element == -1;  
}  
  
/* is_full */  
int is_full(void)  
{  
    return top_element == STACK_SIZE - 1;  
}  
  
/* 
** 定义一个print函数,用来打印堆栈里面的元素。 
*/  
void print(void)  
{  
    int i;  
    i = top_element;  
    printf("打印出静态数组堆栈里面的值: ");  
    if(i == -1)  
        printf("这是个空堆栈\n");  
    while(i!= -1)  
        printf("%d ",stack[i--]);  
    printf("\n");  
}  
int main(void)  
{  
    print();  
    push(10); push(9); push(7); push(6); push(5);  
    push(4);  push(3); push(2); push(1); push(0);  
    printf("push压入数值后:\n");  
    print();  
    printf("\n");  
    pop();  
    pop();  
    printf("经过pop弹出几个元素后的堆栈元素:\n");  
    print();  
    printf("\n");  
    printf("top()调用出来的值: %d\n",top());  
    return 1;  
}
登入後複製

  結果如下圖:

堆疊有幾種實作方式?

二、動態陣列堆疊

  頭檔還是用stack.h,改動的並不是很多,增加了stack_size變數取代STACK_SIZE來保存堆疊的長度,數組由一個指標來代替,在全域變數下預設為0。

  create_stack函數首先檢查堆疊是否已經創建,然後才分配所需數量的記憶體並檢查分配是否成功。 destroy_stack函數先檢查堆疊是否存在,已經釋放記憶體之後把長度和指標變數重新設定為零。 is_emptyis_full 函數中加入了一條斷言,防止任何堆疊函數在堆疊被建立之前就被呼叫。

d_stack.c原始程式碼如下:

[cpp] view plain copy
/* 
** 动态分配数组实现的堆栈程序 d_stack.c 
** 堆栈的长度在创建堆栈的函数被调用时候给出,该函数必须在任何其他操作堆栈的函数被调用之前条用。 
*/  
#include"stack.h"  
#include<stdio.h>  
#include<malloc.h>  
#include<assert.h>  
  
/* 
** 用于存储堆栈元素的数组和指向堆栈顶部元素的指针 
*/  
static STACK_TYPE *stack;  
static int        stack_size;  
static int        top_element = -1;  
  
/* create_stack */  
void create_stack(size_t size)  
{  
    assert(stack_size == 0);  
    stack_size = size;  
    stack = (STACK_TYPE *)malloc(stack_size * sizeof(STACK_TYPE));  
    if(stack == NULL)  
        perror("malloc分配失败");  
}  
  
/* destroy */  
void destroy_stack(void)  
{  
    assert(stack_size > 0);  
    stack_size = 0;  
    free(stack);  
    stack = NULL;  
}  
  
/* push */  
void push(STACK_TYPE value)  
{  
    assert(!is_full());  
    top_element += 1;  
    stack[top_element] = value;  
}  
  
/* pop */  
void pop(void)  
{  
    assert(!is_empty());  
    top_element -= 1;  
}  
  
/* top */  
STACK_TYPE top(void)  
{  
    assert(!is_empty());  
    return stack[top_element];  
}  
  
/* is_empty */  
int is_empty(void)  
{  
    assert(stack_size > 0);  
    return top_element == -1;  
}  
  
/* is_full */  
int is_full(void)  
{  
    assert(stack_size > 0);  
    return top_element == stack_size - 1;  
}  
  
  
/* 
** 定义一个print函数,用来打印堆栈里面的元素。 
*/  
void print(void)  
{  
    int i;  
    i = top_element;  
    printf("打印出动态数组堆栈里面的值: ");  
    if(i == -1)  
        printf("这是个空堆栈\n");  
    while(i!= -1)  
        printf("%d ",stack[i--]);  
    printf("\n");  
}  
int main(void)  
{  
    create_stack(50);  
    print();  
    push(10); push(9); push(7); push(6); push(5);  
    push(4);  push(3); push(2); push(1); push(0);  
    printf("push压入数值后:\n");  
    print();  
    printf("\n");  
    pop();  
    pop();  
    printf("经过pop弹出几个元素后的堆栈元素:\n");  
    print();  
    printf("\n");  
    printf("top()调用出来的值: %d\n",top());  
    destroy_stack();  
    return 1;  
}
登入後複製

  結果如下圖:

堆疊有幾種實作方式?

#三、鏈式堆疊

  由於只有堆疊頂部元素才可以被訪問,因此適用單鍊錶可以很好實現鍊式堆疊,而且無長度限制。把一個元素壓入堆疊是透過在鍊錶頭部添加一個元素來實現。彈出一個元素是透過刪除鍊錶頭部第一個元素來實現。由於沒有長度限制,故不需要create_stack函數,需要destroy_stack進行釋放記憶體以避免記憶體洩漏。

頭檔stack.h不變,l_stack.c原始程式碼如下:

[cpp] view plain copy
/* 
** 单链表实现堆栈,没有长度限制 
*/  
#include"stack.h"  
#include<stdio.h>  
#include<malloc.h>  
#include<assert.h>  
  
#define FALSE 0  
  
/* 
** 定义一个结构以存储堆栈元素。 
*/  
typedef struct STACK_NODE  
{  
    STACK_TYPE value;  
    struct STACK_NODE *next;  
} StackNode;  
  
/* 指向堆栈中第一个节点的指针 */  
static StackNode *stack;  
  
/* create_stack */  
void create_stack(size_t size)  
{}  
  
/* destroy_stack */  
void destroy_stack(void)  
{  
    while(!is_empty())  
        pop();  /* 逐个弹出元素,逐个释放节点内存 */  
}  
  
/* push */  
void push(STACK_TYPE value)  
{  
    StackNode *new_node;  
    new_node = (StackNode *)malloc(sizeof(StackNode));  
    if(new_node == NULL)  
        perror("malloc fail");  
    new_node->value = value;  
    new_node->next = stack;  /* 新元素插入链表头部 */  
    stack = new_node;       /* stack 重新指向链表头部 */  
}  
  
/* pop */  
void pop(void)  
{  
    StackNode *first_node;  
      
    assert(!is_empty());  
    first_node = stack;  
    stack = first_node->next;  
    free(first_node);  
}  
  
/* top */  
STACK_TYPE top(void)  
{  
    assert(!is_empty());  
    return stack->value;  
}  
  
/* is_empty */  
int is_empty(void)  
{  
    return stack == NULL;  
}  
  
/* is_full */  
int is_full(void)  
{  
    return FALSE;  
}  
  
  
/* 
** 定义一个print函数,用来打印堆栈里面的元素。 
*/  
void print(void)  
{  
    StackNode *p_node;  
    p_node = stack;  
    printf("打印出链式堆栈里面的值: ");  
    if(p_node == NULL)  
        printf("堆栈为空\n");  
    while(p_node != NULL)  
    {  
        printf("%d ", p_node->value);  
        p_node = p_node->next;  
    }  
    printf("\n");  
}  
int main(void)  
{  
    print();  
    push(10); push(9); push(7); push(6); push(5);  
    push(4);  push(3); push(2); push(1); push(0);  
    printf("push压入数值后:\n");  
    print();  
    printf("\n");  
    pop();  
    pop();  
    printf("经过pop弹出几个元素后的堆栈元素:\n");  
    print();  
    printf("\n");  
    printf("top()调用出来的值: %d\n",top());  
    destroy_stack();  
    return 1;  
}
登入後複製

  結果如下圖:

堆疊有幾種實作方式?

推薦教學:《java影片教學

以上是堆疊有幾種實作方式?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1664
14
CakePHP 教程
1423
52
Laravel 教程
1321
25
PHP教程
1269
29
C# 教程
1249
24
實作MyBatis中批次刪除操作的多種方式 實作MyBatis中批次刪除操作的多種方式 Feb 19, 2024 pm 07:31 PM

MyBatis中實現批量刪除語句的幾種方式,需要具體程式碼範例近年來,由於資料量的不斷增加,批量操作成為了資料庫操作的一個重要環節之一。在實際開發中,我們經常需要批量刪除資料庫中的記錄。本文將重點介紹在MyBatis中實作批量刪除語句的幾種方式,並提供相應的程式碼範例。使用foreach標籤實作批量刪除MyBatis提供了foreach標籤,可以方便地遍歷一個集

如何在iPhone上自訂和編輯待機模式:iOS 17的新功能 如何在iPhone上自訂和編輯待機模式:iOS 17的新功能 Sep 21, 2023 pm 04:01 PM

待機是iOS17更新中的一項新功能,它提供了一種新的增強方式,可以在手機快速閒置時存取資訊。透過StandBy,您可以輕鬆查看時間、查看即將發生的事件、瀏覽日曆、獲取您所在位置的天氣更新等等。啟動後,iPhone在充電時設定為橫向時會直觀地進入待機模式。此功能非常適合床頭櫃等無線充電點,或在日常任務中離開iPhone充電時。它允許您輕掃待機中顯示的各種小部件,以存取來自各種應用程式的不同資訊集。但是,您可能希望根據您的偏好和您經常需要的資訊修改這些小部件,甚至刪除一些小部件。因此,讓我們深入

iOS 17:如何在待機模式下自訂小工具 iOS 17:如何在待機模式下自訂小工具 Sep 17, 2023 pm 01:57 PM

待機是iOS17中一種新的可自訂鎖定螢幕模式,可在iPhone充電並側臥時啟動。可以將其視為iPhone的一種智慧顯示屏,例如,當您的裝置在廚房,書桌或床頭櫃上充電時,可以​​快速存取可以遠處查看的不同可瀏覽資訊螢幕。自訂備用構件待機由三個螢幕組成,可透過在iPhone顯示器上水平滑動來存取。第一個螢幕是互動式小工具的位置,而向左滑動會顯示第二個和第三個螢幕,分別顯示照片圖庫中的照片和大時鐘顯示。小部件螢幕由兩個並排顯示的互動式小部件堆疊組成,您可以獨立地上下滑動。這些堆疊就像主螢幕小工具堆疊

PHP中的OAuth2鑑權方法及實作方式 PHP中的OAuth2鑑權方法及實作方式 Aug 07, 2023 pm 10:53 PM

PHP中的OAuth2鑑權方法及實現方式隨著網路的發展,越來越多的應用程式需要與第三方平台互動。為了保護用戶的隱私和安全,許多第三方平台使用OAuth2協定來實現用戶鑑權。在本文中,我們將介紹PHP中的OAuth2鑑權方法及實作方式,並附上對應的程式碼範例。 OAuth2是一種授權框架,它允許使用者授權第三方應用程式存取其在另一個服務提供者上的資源,而無需提

Golang實作繼承方法的基本原理和方式 Golang實作繼承方法的基本原理和方式 Jan 20, 2024 am 09:11 AM

Golang繼承方法的基本原理與實作方式在Golang中,繼承是物件導向程式設計的重要特性之一。透過繼承,我們可以使用父類別的屬性和方法,從而實現程式碼的複用和擴展性。本文將介紹Golang繼承方法的基本原理和實作方式,並提供具體的程式碼範例。繼承方法的基本原理在Golang中,繼承是透過嵌入結構體的方式來實現的。當一個結構體嵌入另一個結構體時,被嵌入的結構體就擁有了嵌

PHP實現直播功能的三種方式 PHP實現直播功能的三種方式 May 21, 2023 pm 11:00 PM

隨著網路的普及和高速網路的加速,直播已經成為了一種非常流行的網路應用。直播能夠為用戶提供即時的視訊和音訊串流,並能夠進行互動和交流,因此在各種社交平台和線上教育中廣泛應用。而在直播應用中,PHP也是非常重要的程式語言之一,許多網站和應用程式都使用PHP來實現直播功能。本文將介紹PHP實現直播功能的三種方式。一、使用RTMP協定RTMP(RealTime

PHP7.0中的響應式程式設計有哪些實作方式? PHP7.0中的響應式程式設計有哪些實作方式? May 27, 2023 am 08:24 AM

在過去的幾十年中,電腦程式設計已經經歷了許多變化和進化。其中一個最新的程式設計範式被稱為響應式程式設計(reactiveprogramming),它在高品質、高並發的網路應用程式開發中變得更加流行。 PHP是一種流行的Web程式語言,提供了豐富的函式庫和框架來支援響應式程式設計。在本文中,我們將介紹PHP7.0中響應式程式設計的實作方式。什麼是響應式程式設計?在開始討論PHP7.0

PHP郵件佇列系統的原理和實作方式是什麼? PHP郵件佇列系統的原理和實作方式是什麼? Sep 13, 2023 am 11:39 AM

PHP郵件佇列系統的原理和實作方式是什麼?隨著網路的發展,電子郵件已經成為人們日常生活和工作中必不可少的溝通方式之一。然而,隨著業務的成長和用戶數量的增加,直接發送電子郵件可能會導致伺服器效能下降、郵件發送失敗等問題。為了解決這個問題,可以使用郵件佇列系統來透過串列佇列的方式傳送和管理電子郵件。郵件佇列系統的實作原理如下:郵件入佇列當需要傳送郵件時,不再直

See all articles