栈和队列技术文章

简介: 栈和队列技术文章

栈和队列


**线性表:**连续的,每个元素都有唯一的前驱和后继

数组和链表

数组

地址是连续的

随机访问公式:数组起始地址 + 下标 * 数组单个存储单元的大小

链表

形象地说,链表就是用一串链子将结点串联起来。


结点:包含数据域和指针域。

数据域:数据

指针域:下一个结点的地址


单链表: 除了尾结点, 每一个结点都有一个后继结点


循环链表: 尾结点的下一个结点指向头结点


双线链表: 有后继结点还有前驱结点


双向循环链表: 尾结点的下一个指向头, 头结点之前指向尾结点

常用的是双链表

取中间值和判断链表是否有环的常用方法:快慢指针

反转链表:头插法

泛型

泛型: 参数化类型 ()

事先不指定数据类型,等到使用的时候再确定

泛型的好处

a. 提高了程序的安全性

b. 将运行期遇到的问题转移到了编译期

c. 省去了类型强转的麻烦

泛型的使用

泛型类
// 把泛型定义到类上, 就是泛型类

泛型类: 把泛型定义在类上
格式:class 类名 <泛型类型1,…>
注意:参数化类型必须是引用类型
    
// 注意2: 如果某一个代码中我们使用的时候应该传入泛型, 但是我们没有传, 那么它默认是Object类型
     User user = new User("zs", 18);
        Object age2 = user.getAge();

// 注意3: 注意一些泛型定义的习惯问题
        // 给泛型定义的时候: 习惯上
        // T: type
        // E: element
        // K: key
        // V: value

// 注意4: 不要给一个类定义超过两个泛型(不是语法不允许),  习惯上显得怪异

// 注意5: 在泛型类上定义的泛型, 作用域, 仅仅局限于类名和类体内

泛型的通配

泛型通配符:

① 泛型通配符<?>
任意类型,如果没有明确,那么就是Object以及任意的Java类了
② ? extends E
向下限定,E及其子类
③ ? super E
向上限定,E及其父类

     ArrayList<?> list = new ArrayList<Character>();
        // 报错的原因: 因为从编译角度, 仅能推断出?代指一个不确定的类型
        //        从java语法角度, 一个不确定的类型, 没有存储其它类型(String存储Integer肯定无法运行)
        // 为了避免运行时出现问题, 直接不让添加
        // list.add("zs");// 报错:
        // list.add(new Object());// 报错

ArrayList<? extends F> list = new ArrayList<S2>();
        // 报错的原因: 因为从编译角度, 仅能推断出? extends F代指一个不确定的f或者f的子类型
        //        从java语法角度, 一个不确定的类型, 没有存储其它类型
        // 为了避免运行时出现问题, 直接不让添加
        //list.add("zs");//报错
        //list.add(new Object());//报错
        //list.add(new F());//报错
        //list.add(new S1());//报错

        ArrayList<? super F> list = new ArrayList<F>();
        // list.add("zs");//报错
        // list.add(new Object());//报错
        list.add(new F());
        list.add(new S1());
        list.add(new S2());

class F {}
class S1 extends F{}
class S2 extends F{}

泛型擦除

java中的泛型并不是真正的泛型, java中的泛型只存在于代码编译之前, 代码编译的时候, 这些泛型的写法统统会被擦除, 变成Object以及类型强转.

FILO

链表实现栈时运用头插法

栈的应用

应用场景:

  1. 函数调用栈
  2. 反序字符串
    实现reNumber(str)方法,反转字符串
  3. 括号匹配问题
    实现judgeBracket(str)方法来判断括号匹配
  4. 编译器利用栈实现表达式求值
  5. 浏览器的前进后退功能
  6. 利用栈实现 DFS: depth-first-search 深度优先遍历
  7. 波兰表达式

队列

FIFO

用链表实现队列时,头节点作为队列头实现出队列,尾节点作为队列尾实现入队列

普通队列的应用场景是很有限的,一般在工程中用到的是阻塞队列。

阻塞队列:常用于生产者-消费者模型中。

队列大小固定:

当队列满的时候,入队列就阻塞。

当队列空的时候,出队列就阻塞。

队列应用场景:

缓存

相关文章
|
3天前
|
Python
数据结构===队列
数据结构===队列
|
3天前
|
C++
【洛谷 P1044】[NOIP2003 普及组] 栈 题解(递归+记忆化搜索)
**NOIP2003普及组栈问题**:给定操作数序列1到n,仅允许push(进栈)和pop(出栈)操作。目标是计算所有可能的输出序列总数。输入包含一个整数n(1≤n≤18)。示例输入3,输出5。当队列空时返回1,栈空则只能入栈,栈非空时可入栈或出栈。AC C++代码利用记忆化搜索求解。
6 1
|
2天前
|
缓存 调度
栈和队列的区别
栈和队列的区别
5 0
|
3天前
|
存储 程序员 编译器
堆和栈的区别
堆和栈的区别
|
3天前
|
C++
【洛谷 P1739】表达式括号匹配 题解(栈)
该编程题目要求检查给定的包含字母、运算符和括号的表达式是否括号匹配。输入为一行表达式,以`@`结束。如果括号匹配,输出`YES`,否则输出`NO`。样例包括一个匹配和一个不匹配的表达式。解决方案是使用栈,遇到左括号入栈,遇到右括号时判断栈是否为空,栈空则输出`NO`,否则出栈。当读到`@`时,栈空则输出`YES`,否则输出`NO`。提供的AC代码使用C++实现,通过`stack`处理括号匹配。
5 0
|
3天前
|
存储 Java Python
数据结构===栈
数据结构===栈
|
9天前
数据结构——栈和队列
数据结构——栈和队列
10 1
|
12天前
|
存储 算法 调度
数据结构与算法-栈篇
数据结构与算法-栈篇
13 3
|
5天前
|
算法
$停车场管理系统 栈与队列
$停车场管理系统 栈与队列
6 1
|
9天前
|
存储 算法 程序员
【C++进阶】深入STL之 栈与队列:数据结构探索之旅
【C++进阶】深入STL之 栈与队列:数据结构探索之旅
16 4