特殊的线性表(stack)

1. 什么是栈?

栈(stack)是限定仅在表尾进行插入和删除操作的线性表。

2. 栈的特点:

1.) 栈又称为后进先出(Last In First out)的线性表,栈元素具有线性关系,即前驱后继关系。

2.) 栈的特殊之处在于:它的栈底是固定的,只允许在栈顶进行插入和删除操作。

3. 栈的顺序存储结构(Java数组实现):

// 栈的数组实现, 底层使用数组:
public class ArrayStack<T> {
	private Object[] arr; // 数组首元素作为栈底,因为它变化小
	private int length;

	// 数据初始化
	public ArrayStack(){
		arr = new Object[16];
		length = 0;
	}

	// 元素入栈
	public boolean push(T data) {
		if (length >= arr.length) { // 判断是否需要进行数组扩容
			resize();
		}
		arr[length++] = data;
		return true;
	}

	// 元素出栈
	@SuppressWarnings("unchecked")
	public T pop() {
		if (length == 0) {
			return null;
		}
		return (T) arr[--length];
	}

	// 将数组中的数据置为null, 方便GC进行回收
	public void clear() {
		for (int i = 0; i < length; i++) {
			arr[length] = null;
		}
		length = 0;
	}

	// 数组扩充容量
	private void resize() {
		Object[] temp = new Object[arr.length * 3 / 2 + 1];
		for (int i = 0; i < length; i++) {
			temp[i] = arr[i];
			arr[i] = null;
		}
		arr = temp;
	}

	// 获取栈中元素个数
	public int length() {
		return length;
	}

	// 判断数组是否为空
	public boolean isEmpty() {
		return length == 0;
	}

	// 打印栈中元素
	public String toString() {
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < length; i++) {
			sb.append(arr[i].toString());
			if (i != length - 1) {
				sb.append(", ");
			}
		}
		return sb.toString();
	}

	public static void main(String[] args) {
		ArrayStack<Integer> stack = new ArrayStack<Integer>();
		long start = System.currentTimeMillis();
		for (int i = 0; i < 1000000; i++) {
			stack.push(i); // 入栈
		}
		long temp = System.currentTimeMillis();
		System.out.println("push time: " + (temp - start));
		while (stack.pop() != null){
			 ; // 出栈
		}
		System.out.println("pop time: " + (System.currentTimeMillis() - temp));
	}
}
运行时间:
	push time: 257ms
	pop time: 5ms

 

4. 栈的链式存储结构(Java链表实现):

// 结点元素
public class Node<T> {
	private Node<T> prev; // 记住当前结点的前一结点
	private T data; // 数据域

	public Node() {
	}

	public Node(T data, Node<T> prev) {
		this.data = data;
		this.prev = prev;
	}

	public Node<T> getPrev() {
		return prev;
	}

	public void setPrev(Node<T> prev) {
		this.prev = prev;
	}

	public T getData() {
		return data;
	}

	public void setData(T data) {
		this.data = data;
	}
}
// 栈的链表实现, 底层使用单链表:
public class LinkedStack<T> {
	private Node<T> top; // 栈顶指针(链表尾结点)
	private int size; // 栈的长度

	// 数据初始化
	public LinkedStack() {
		top = null;
		size = 0;
	}

	// 结点入栈
	public boolean push(T data) {
		Node<T> newNode = new Node<T>(data,top); // 将top设置为新节点的前驱结点
		top = newNode; // 将新结点设置为栈顶指针
		size++;
		return true;
	}

	// 结点出栈
	public T pop() {
		if (top != null) {
			Node<T> tempNode = top;
			top = top.getPrev(); // 将栈顶指针的前驱结点设置为栈顶指针
			size--;
			return tempNode.getData();
		}
		return null;
	}

	// 判断栈是否为空
	public boolean isEmpty() {
		return size == 0;
	}

	// 获取栈的长度
	public int length() {
		return size;
	}

	// 打印栈中元素
	public String toString() {
		Node<T> node = top;
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < size; i++) {
			sb.append(node.getData().toString());
			if (i != size - 1) {
				sb.append(", ");
			}
			node = node.getPrev();
		}
		return sb.reverse().toString();
	}

	public static void main(String[] args) {
		LinkedStack<Integer> stack = new LinkedStack<Integer>();
		long start = System.currentTimeMillis();
		for (int i = 0; i < 1000000; i++) {
			stack.push(i); // 入栈
		}
		long temp = System.currentTimeMillis();
		System.out.println("push time: " + (temp - start));
		while (stack.pop() != null){
			;  // 出栈
		}
		System.out.println("pop time: " + (System.currentTimeMillis() - temp));
	}
}
运行时间:
	push time: 986ms
	pop time: 15ms

5. 两种实现方式比较:

通过入栈和出栈时间比较可以看出,数组实现在性能上还是有明显优势的,这是因为数组实现的栈在增加和删除元素时并不需要移动大量的元素,只是在扩大数组容量时,需要进行拷贝。然而链表实现的栈在入栈时需要将数据包装成Node,出栈时需要从Node中取出数据,同时还要维护栈顶指针和前驱指针。

6. JDK API中的栈:

1.) java.util.Stack: 一个普通的顺序栈,底层基于数组实现。这个类是线程安全的。 
2.) java.util.LinkedList: 一个双向链表,线程不安全,可以当做栈来使用。在多线程环境下可以使用Collections类的工具方法将其改造成线程安全类。

3.) 两个类都提供了push(),pop(),peek()等方法。

时间: 2024-10-24 00:40:50

特殊的线性表(stack)的相关文章

[笔记]python数据结构之线性表:linkedlist链表,stack栈,queue队列

python数据结构之线性表 python内置了很多高级数据结构,list,dict,tuple,string,set等,在使用的时候十分舒心.但是,如果从一个初学者的角度利用python学习数据结构时,这些高级的数据结构可能给我们以迷惑. 比如,使用list实现queue的时候,入队操作append()时间复杂度可以认为是O(1),但是,出队操作pop(0)的时间复杂度就是O(n). 如果是想利用python学学数据结构的话,我觉得还是自己实现一遍基本的数据结构为好. 1.链表 在这里,我想使

数据结构和算法学习总结04 线性表---栈

栈 栈(Stack)是特殊的线性表,是只允许在一端进行插入和删除的线性表. 允许插入和删除的叫栈顶,反之则是栈底. 栈的插入称为进栈,删除称为出栈. 特性是:后进先出,所以栈也叫后进先出表,简称LIFO表(Last In First Out). 因为栈是线性表,所以也有顺序表和链表两种形式,一般我们常用顺序表. 从代码中可以看出:与顺序表相比实际上就是插入和删除操作发生了改变. #include <iostream> using namespace std; const int Stack_S

数据结构代码整理(线性表,栈,串,二叉树)。。持续更新中。。。

//线性表 #include <cstdio> #include <cstring> #include <iostream> #include <cstdlib> using namespace std; ///都用c语言写的 ///建议从主函数开始看 int sequence_map[100005]; ///顺序表的数组 int total_sequence=0,total_list=0; ///定义两个全局变量用来计算顺序表与链表长度,初始值为0 str

[考研系列之数据结构]线性表之栈

?基本概念 栈的定义 限定仅在表尾进行插入或删除的线性表 组成 栈顶 栈底 基本操作 入栈(PUSH) 往栈中插入一个元素 弹栈(POP) 从栈顶删除一个元素 栈的表示 顺序栈 链栈 对于顺序栈,有两个指针base和top base指向栈底 top指向栈顶 对于栈的一些基本情况: 栈不存在时候 base=NULL 栈为空时  top=base 栈的长度 top-base 链栈略过. 栈的应用 1 数制转换 数制转换我们使用一种称之为"辗转相除法"的算法.此算法的基本原理基于: N=(N

特殊线性表(queue)

队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表.进行插入操作的端称为队尾,进行删除操作的端称为队头.队列中没有元素时,称为空队列. 在队列这种数据结构中,最先插入的元素将是最先被删除的元素:反之最后插入的元素将是最后被删除的元素,因此队列又称为“先进先出”(FIFO—first in first out)的线性表. 队列(Queue)是只允许在一端进行插入,而在另一端进行删除的运算受限

线性表之栈与队列

一.栈是限定仅在表尾进行插入和删除操作的线性表 队列是只允许在一端进行插入操作,而在另另一端进行删除操作的线性表. 允许插入和删除的一端称为栈顶,另一端称为栈底,不包含任何数据元素的栈称为空栈,栈称为后进先出  LIFO结构 栈的抽象数据类型 ADT 栈 (stack) Data 同线性表.元素具有相同的类型,相邻元素具有前驱和后继关系 Operation InitStack(*S):初始化操作,建立一个空栈S DestroyStack(*S):若栈存在,则销毁它 ClearStack(*S):

Java学习笔记(2)----散列集/线性表/队列/集合/图(Set,List,Queue,Collection,Map)

1. Java集合框架中的所有实例类都实现了Cloneable和Seriablizable接口.所以,它们的实例都是可复制和可序列化的. 2. 规则集存储的是不重复的元素.若要在集合中存储重复的元素,就需要使用线性表.线性表不仅可以存储重复的元素,而且允许用户指定存储的位置.用户可以通过下标来访问线性表中的元素. 3. Java集合支持三种类型的规则集:散列集HashSet.链式散列集LinkedHashSet和树形集TreeSet.HashSet以一个不可预知的顺序存储元素:LinkedHas

数据结构和算法 (二)数据结构基础、线性表、栈和队列、数组和字符串

Java面试宝典之数据结构基础 —— 线性表篇 一.数据结构概念 用我的理解,数据结构包含数据和结构,通俗一点就是将数据按照一定的结构组合起来,不同的组合方式会有不同的效率,使用不同的场景,如此而已.比 如我们最常用的数组,就是一种数据结构,有独特的承载数据的方式,按顺序排列,其特点就是你可以根据下标快速查找元素,但是因为在数组中插入和删除元素会 有其它元素较大幅度的便宜,所以会带来较多的消耗,所以因为这种特点,使得数组适合:查询比较频繁,增.删比较少的情况,这就是数据结构的概念.数据结构 包括

数据结构:线性表插入一次删除一次的代码

#include <iostream> #include <cmath> #include <cstring> #include <algorithm> #include <stack> #include <queue> #include <cstdio> using namespace std; int insertsqlist(int weizhi,double charu,int *t,double b[]){