1. 程式人生 > >資料結構——棧的基本總結

資料結構——棧的基本總結

最近刷資料結構的黑寶書,順便將資料結構進行下總結,就先從最熟悉的棧開始吧。

棧(stack),資料結構中的一種,準確的來說,應該是資料邏輯結構

棧的基本特點為: 後進先出,就像生活中我們取放盤子,當一摞盤子在桌子上時候,我們總是會取最上邊的盤子,同時,我們在放盤子時,也會放在最上面。同樣這種機制也在我們瀏覽網頁時也有出現,在我們瀏覽網頁時,左上角的轉到上一頁就是這種,最近瀏覽的網站在最上層,當返回時,先取到最上層的地址,這樣即實現了逐層後退。

棧有幾個基本的操作

  • push         向棧底新增一個元素     
  • pop           從棧頂取出一個元素
  • peek         
    複製棧頂元素,但不進行刪除
  • size           判定棧中所含元素的個數
  • isEmpty    判斷棧是否為空

因為對樹結構還不夠熟悉,我們就用簡單的陣列連結串列來實現一個棧。

陣列實現

利用陣列實現棧,我們可以設定自定義容量和預設容量,也可以設定自動擴容機制。陣列實現機制相對來說更加簡單,考慮到棧的操作總是取最近新增的元素,所以,我們以頭部作為棧底,尾部作為棧頂,這樣向棧內新增元素時,時間複雜度為常數,對於經常對棧頂進行操作,並且棧內資料非常龐大的情況下,效率相對較高。

下面利用Java程式碼進行方法實現

package Stack;

public class ArrayStack {
	/*
	 * 該類為使用陣列實現的一個棧(Stack)
	 * 具有成員方法pop,push,peek,isEmpty,size,getMaxElementNumber
	 * 具有構造方法兩種,預設容量和指定容量
	 * 陣列應具有自動擴容能力(可選)
	 */
	//該值為棧索引,各項方法均對其進行操作(固定長度陣列)
	private int STACK_ARRAY_INDEX_OF_HANDMOVEMENT = 0;
	//該值為棧最大容量數
	public int TOP;
	
	private Object[] StackArray;
	
	public ArrayStack() {
		//預設棧容量為15
		StackArray = new Object[15];
	}
	
	public ArrayStack(int TOP) {
		//指定棧容量
		StackArray = new Object[TOP];
		//返回TOP值,用於後續判斷操作
		this.TOP = TOP;
	}
	/*
	 * 棧推入操作  具有判滿功能
	 */
	public boolean push(Object element) {
		//判斷棧頂是否滿元素,若滿,進行擴容,若空進行新增
		if(StackArray[StackArray.length-1] != null) {
			/*
			 * 準備新陣列,將原陣列資料全部複製進去
			 * 將原陣列刪除並擴容 擴容指數為2倍
			 * 將新陣列資料複製進原陣列
			 */
			Object[] StackArrayNew = new Object[StackArray.length];
			for(int i = 0;i<=StackArrayNew.length;i++) {
				StackArrayNew[i] = StackArray[i];
			}
			StackArray = new Object[StackArrayNew.length * 2];
			for(int i = 0;i<=StackArrayNew.length;i++) {
				StackArray[i] = StackArrayNew[i];
			}
			StackArray[STACK_ARRAY_INDEX_OF_HANDMOVEMENT] = element;
			STACK_ARRAY_INDEX_OF_HANDMOVEMENT++;
			return true;
		}else {
			StackArray[STACK_ARRAY_INDEX_OF_HANDMOVEMENT] = element;
			STACK_ARRAY_INDEX_OF_HANDMOVEMENT++;
			return true;
		}
	}
	
	/*
	 * 棧取出操作,具有判空功能
	 */
	public Object pop() {
		//判斷棧中是否有元素,若有返回Object例項,若無返回提示
		
		if(StackArray[0] == null) {
			return null;
		}else {
			Object theReturnResult =                                                
StackArray[STACK_ARRAY_INDEX_OF_HANDMOVEMENT];
			StackArray[STACK_ARRAY_INDEX_OF_HANDMOVEMENT] = null;
			return theReturnResult;
		}
	}
	/*
	 * 判斷棧中元素個數方法
	 */
	public int size() {
		int index = 0;
		while(StackArray[index] == null) {
			index++;
		}
		return index;  
	}
	/*
	 * 判斷是否為空
	 */
	public boolean isEmpty() {
		if(StackArray[0] == null) 
			return true;
			return false;
	}
	/*
	 * peek複製棧頂元素
	 */
	public Object peek() {
		//判斷棧中是否有元素,若有返回Object例項,若無返回提示
		if(StackArray[0] == null) {
			System.out.println("該棧為空");
			return null;
		}else {
			Object theReturnResult = StackArray[STACK_ARRAY_INDEX_OF_HANDMOVEMENT];
			return theReturnResult;
		}
	}
}

Ps:該棧內實現了基本的五個操作,並且對基本的操作進行了判空功能。

連結串列實現

在這裡就先不進行連結串列的介紹,等有時間再開一篇連結串列的總結。

為了實現起來更加方便,利用單鏈表即可滿足棧的需求。對於連結串列來說,增刪改的操作時間為常數,而因為其引用的特性,遍歷的花費十分昂貴,所以我們為了優化棧的效能,儘可能減少遍歷連結串列所浪費的時間,我們將連結串列表頭作為棧頂,這樣每次存取操作只需要用頭引用取表頭資料即可。

首先我們需要在連結串列內維護一個節點類

package MyLinkedList;
/*
 * 該類為單鏈表類的節點類,該類只服務於LinkedList類,並不進行對外暴露
 */
public class SingleLinkedListNode {
	//該引用為連結串列中的資料部分,用於存放資料
	public Object data;
	//該引用為指向下一個連結串列,最後一個可迴圈或者置空
	public SingleLinkedListNode Next;
	
	public SingleLinkedListNode(Object data,SingleLinkedListNode Next) {
		this.data = data;
		this.Next = Next;
	}

	public Object getData() {
		return data;
	}

	public void setData(Object data) {
		this.data = data;
	}

	public SingleLinkedListNode getNext() {
		return Next;
	}

	public void setNext(SingleLinkedListNode next) {
		Next = next;
	}
	
}

下面用連結串列實現

package MyLinkedList;
/*
 * 該類為單鏈表類的節點類,該類只服務於LinkedList類,並不進行對外暴露
 */
public class SingleLinkedListNode {
	//該引用為連結串列中的資料部分,用於存放資料
	public Object data;
	//該引用為指向下一個連結串列,最後一個可迴圈或者置空
	public SingleLinkedListNode Next;
	
	public SingleLinkedListNode(Object data,SingleLinkedListNode Next) {
		this.data = data;
		this.Next = Next;
	}

	public Object getData() {
		return data;
	}

	public void setData(Object data) {
		this.data = data;
	}

	public SingleLinkedListNode getNext() {
		return Next;
	}

	public void setNext(SingleLinkedListNode next) {
		Next = next;
	}
}

只實現了幾個基本操作,對於size,isEmpty等方法,和陣列實現原理相同。

最後再簡單介紹一種較為特殊的棧,該棧為棧中的一個特殊形式,主要用於取消操作,使用陣列進行實現,該棧不能進行自動擴容,並且棧滿後將從棧低進行元素刪除。

其原理和以上兩種棧無差別,只不過在棧滿後,先將棧底元素刪除,再將棧元素向前移動,最後在棧頂新增元素。

package Stack;

public class OverFlowStack {
	/*
	 * 該棧為棧中的一個特殊形式,主要用於取消操作,使用陣列進行實現 
	 * 該棧不能進行自動擴容,並且棧滿後將從棧低進行元素刪除
	 * 該棧具有方法為pop,push,peek,size,isEmpty
	 */

	// 該值為棧索引,各項方法均對其進行操作(固定長度陣列)
	private int STACK_ARRAY_INDEX_OF_HANDMOVEMENT = 0;

	public int TOP;

	private Object[] OverFlowStack;

	public OverFlowStack() {
		// 預設棧容量為15
		OverFlowStack = new Object[15];
	}

	public OverFlowStack(int TOP) {
		// 指定棧容量
		OverFlowStack = new Object[TOP];
		// 返回TOP值,用於後續判斷操作
		this.TOP = TOP;
	}

	public boolean push(Object element) {
		// 首先對棧進行資料判斷,如果棧內還有空間,直接新增
		// 如果棧內已經滿資料,從棧底刪除最後一個數據並進行陣列索引的移動
		if (OverFlowStack[OverFlowStack.length - 1] == null) {
			OverFlowStack[STACK_ARRAY_INDEX_OF_HANDMOVEMENT] = element;
			return true;
		} else {
			// 通過while進行對棧內資料移動的操作
			// 移動次數為INDEX-1
			int temp = 0;
			while (temp <= OverFlowStack.length - 1) {
				OverFlowStack[temp] = OverFlowStack[temp + 1];
				temp++;
			}
			return true;
		}
	}
	/*
	 * 棧取出操作,具有判空功能
	 */
	public Object pop() {
		//判斷棧中是否有元素,若有返回Object例項,若無返回提示
		
		if(OverFlowStack[0] == null) {
			return null;
		}else {
			Object theReturnResult = OverFlowStack[STACK_ARRAY_INDEX_OF_HANDMOVEMENT];
			OverFlowStack[STACK_ARRAY_INDEX_OF_HANDMOVEMENT] = null;
			return theReturnResult;
		}
	}
	/*
	 * 判斷棧中元素個數方法
	 */
	public int size() {
		int index = 0;
		while(OverFlowStack[index] == null) {
			index++;
		}
		return index;  
	}
	/*
	 * 判斷是否為空
	 */
	public boolean isEmpty() {
		if(OverFlowStack[0] == null) 
			return true;
			return false;
	}
	/*
	 * peek複製棧頂元素
	 */
	public Object peek() {
		//判斷棧中是否有元素,若有返回Object例項,若無返回提示
		if(OverFlowStack[0] == null) {
			System.out.println("該棧為空");
			return null;
		}else {
			Object theReturnResult = OverFlowStack[STACK_ARRAY_INDEX_OF_HANDMOVEMENT];
			return theReturnResult;
		}
	}
}

基本內容就總結到這裡,如果有錯誤的地方請留言指出,萌新發文,請大神輕噴。

本文原創,轉載請註明來源。

QQ   489282384

                         JoryB

相關推薦

資料結構——基本總結

最近刷資料結構的黑寶書,順便將資料結構進行下總結,就先從最熟悉的棧開始吧。 棧(stack),資料結構中的一種,準確的來說,應該是資料邏輯結構。 棧的基本特點為: 後進先出,就像生活中我們取放盤子,當一摞盤子在桌子上時候,我們總是會取最上邊的盤子,同時,我們在放盤子時,也

資料結構基本操作

#include<iostream> #define MAXSIZE 100 #define OVERFLOW -1 #define OK 1 #define ERROR 0 using namespace std; typedef int SElemType

案例3.2:括號匹配的檢驗(c++實現/資料結構/基本操作)

#include<iostream> #define MaxSize 100 #define OK 1 #define ERROR 0 using namespace std; typedef char ElemType; typedef int Status

演算法與資料結構-基本操作C語言實現

序言 複習棧的基本操作及其C語言實現,主要以鏈式棧為例。 本文將介紹棧的以下基本操作: 棧的建立(順序棧和鏈式棧) 棧的初始化 棧遍歷 棧清空/銷燬 判斷棧是否為空 求棧的長度 返回並刪除棧頂元素 1. 棧建立 - 順序棧和鏈式棧 //順序棧的

資料結構——基本操作(二進位制轉十進位制例項—c語言程式碼)

棧棧是一種重要的線性結構。棧必須通過線性表或者連結串列來實現,順序表點選開啟連結和連結串列點選開啟連結既可以向之前介紹的那樣獨立存在,同時它們也是一些特殊的資料結構(棧,佇列)的實現基礎。定義:棧是一個先進後出的線性表,只要求在表尾進行插入和刪除等操作,這是棧相對於連結串列和

[資料結構-]基本操作&括號匹配

堆疊的三種實現方式 用靜態資料實現 #include<stdio.h> #define MAX_SIZE 100 int top = -1; int stack[MAX_SIZ

資料結構---(C語言陣列實現)

https://blog.csdn.net/morixinguan/article/details/51374184 資料結構---棧(C語言陣列實現)   棧的全名稱為堆疊,棧其實就是與佇列相反的過程,佇列是先進先出,而棧便是先進後出了,如下圖:  

java之---實現資料結構--(基本版)

package 資料結構; /** * java程式碼實現棧 */ class stack { private class Data { private Object obj; private Data next = null; Da

【極客時間】資料結構與演算法總結

【極客時間】資料結構與演算法總結: 02| 資料結構是為演算法服務的,演算法要作用在特定的資料結構之上。 20個最常用的最基礎的資料結構與演算法: 10個數據結構:陣列、連結串列、棧、佇列、散列表、二叉樹、堆、跳錶、圖、Trie樹 10個演算法:遞迴、排序、二分

資料結構——操作的實現

#include <stdio.h> #include <malloc.h> #define OK 1 #define ERROR 0 #define INFEASIBLE -1 #define OVERFLOW -2 #define TRUE 1 #define FALSE

資料結構 數值轉換

新手,可能會有問題,歡迎指正 #include <iostream> #include <cstdio> #include <malloc.h> #define STACK_INIT_SIZE 100 #define STACKINCREMENT 10

[資料結構&基操][C++]一個二維網狀資料結構基本操作

一是因為上學期學了資料結構,二是因為面對物件的程式設計學的不精,我便用資料結構做了一個資訊管理系統作為C艹大作業。 沒想到居然拿了優秀 ψ(`∇´)ψ (不管難否,反正是筆者五級分制中唯一的優秀)   先上資料結構圖   貼程式碼 結構體: ​t

資料結構-與佇列

棧的定義 棧是限定僅在表尾進行插入和刪除操作的線性表 我們把允許插入和刪除的一端稱為棧頂 (top) ,另一端稱為棧底 (bottom) ,不含任何資料元素的棧稱為空棧。 棧又稱為後進先出 (Last In Filrst Out) 的線性表,簡稱LIFO結構。 理解棧的定義需要注意:

java資料結構——

棧是一種特殊的線性表,僅能線上性表的一端操作,棧頂允許操作,棧底不允許操作,遵循“後進先出”的特點。資料結構圖如下: 基本操作包括建立棧、入棧、出棧、獲取棧頂元素、獲取棧的大小等。棧的實現分為兩種,一種是通過陣列實現;一種是通過連結串列來實現。二者的區別是陣列實現棧簡單簡潔,而使用連結

《java常用演算法手冊》 第二章 資料結構 佇列

 順序棧的實現: package LineStructure; //參考 https://blog.csdn.net/icarus_wang/article/details/79561863 public cla

leetcode與資料結構---動態規劃總結(一)

這幾天一直在做leetcode上關於動態規劃方面的題目,雖然大二下的演算法設計課上較為詳細的講過動態規劃,奈何遇到新穎的題目或者稍加背景的題目立刻就原形畢露不知題目所云了。動態規劃算是較難的一個專題了,但只要找到遞推關係其最終的程式碼又相當簡便。現在把這幾天做過的題目整理總結一下,畢竟只求做

java中的資料結構——

棧的工作原理,後進先出。 棧,佇列是比陣列和其他資料結構更抽象的結構,主要通過介面對棧,佇列進行定義,而他們的主要實 現機制對使用者是不可見的。 棧的主要機制可以用陣列來實現,也可以用連結串列來實現。優先順序佇列的內部 實現可以用陣列或一種特殊的樹(堆)來實現。 棧只允許訪問一個數據項,即最

JAVA基礎(61)---資料結構基本概念和邏輯結構以及儲存結構

資料結構                    本章的目的:對資料結構有一個大概的瞭解和認知 資料:能夠儲存

Pyhon資料結構——(stack)

棧可以看成一個容器。先入棧的資料儲存在容器底部,後入棧的資料儲存在容器頂部。出棧的時候,後入棧的資料先出,先入棧的資料後出。因此棧有一個特性叫做後入先出(last in first out,LIFO)。 在pystack.py指令碼中,利用列表,建立了一個簡單的棧結構。程式碼如下:

資料結構與演算法總結——常見排序演算法(未完待續)

本文包含的排序演算法 氣泡排序 插入排序 選擇排序 歸併排序 快速排序 希爾排序 堆排序 桶排序 基數排序 本文關於C++ 的知識點 儘量使用vector代