【数据结构真不难】栈与队列——五一专属|向所有热爱分享的“技术劳动者”致敬(三)

简介: 【数据结构真不难】栈与队列——五一专属|向所有热爱分享的“技术劳动者”致敬(三)

8.链队列


8.1定义


链队列:使用链式存储的队列,使用不带头结点head的单链表。

  • front结点:队首元素
  • rear结点:队尾元素微信图片_20220530222752.png

8.2链队列类


public class LinkQueue {
    private Node front;   //队首(出队/删除)
    private Node rear;    //队尾(入队/插入)
}

 8.4算法:链队列入队


 分析:

非空微信图片_20220530223003.png

微信图片_20220530222926.png

public void offer(Object x) {
    Node p = new Node(x);
    if(front == null) {   //空
        front = rear = p;
        //front = p;
        //rear = p;
    } else {        //非空
        rear.next = p;    //1.尾指针的指针域指向新结点
        rear = p;     //2.尾指针指向队尾
    }
}

8.5算法:链队列出队


分析:空队列、一个元素、很多元素

  • 很多元素微信图片_20220530222930.png

一个元素:需要额外的处理队尾,将其设置成null

微信图片_20220530222934.png

空队列:返回null即可

public Object poll() {
    if(front != null) {   //非空
        Node p = front;       //记录队首元素
        front = front.next;     //队首移动到下一个
        if(p == rear) {         //只有一个元素时,队首和队尾相同
            rear = null;        //队首已经是null,队尾也应该是null
        }
        return p.data;        //返回之前队首元素的数据
    } else {        //空
        return null;
    }
}

9.优先级队列


9.1定义


优先级队列:就是一种带优先级的队列,也就是内部需要根据关键字的值进行排序的队列。


与普通队列基本操作一致,队首删除。


区别:进行==插入==操作时,不在是队尾,对队伍中找到合适的位置。


优先级队列也可以使用两种存取方式,但常用链式存储。


默认队列

微信图片_20220530223225.png

插入操作:数字小的优先级越高微信图片_20220530223243.png

9.2优先级队列相关类

微信图片_20220530223249.png

数据对象:数据元素的值、结点的优先级

/*
  { elem: a, priority: 1}
*/
public class PriorityData {
    public Object elem;       //数据元素的值
    public int priority;      //结点的优先级
}

队列对象

public class PriorityQueue {
    private Node front;   //队首
    private Node rear;    //队尾
}

数据之间关系

node.next        //指针域

node.data        //数据域,存放的数据类型是 PriorityData

9.3算法:优先级队列入队


  • 需求:数字越==小==优先级越高。
  • 分析:
  • 前提:从队首进入,依次进行比较
  • 情况1:队首插入(p如果指向队首front,表示新结点优先级的数字小)微信图片_20220530223316.png

情况2:队尾插入 (q为null 或 p等于队尾rear)微信图片_20220530223321.png

情况3:剩余的中间微信图片_20220530223327.png

public void offer(PriorityData x) {
    Node s = new Node(x);       //构建新结点
    // 如果空
    if(front == null) {   //空
        front = rear = s;
    } else {        //非空
        // 1) 移动:按照优先级进行移动,优先级大就需要继续移动
        Node p = front;   //用于记录前驱(之前的)
        Node q = front;   //用于记录下一个
        while( q != null && (x.priority >= q.data.priority )) {
            p = q;      //记录前驱
            q = p.next;
        }
        // 2) 插入
        if(q==front) {      // 2.1 队首
            s.next = front;     //新结点s指向队首front
            front = s;        //队首指针,指向队列的开始
        } else if (q == null) { // 2.2 队尾
            rear.next = s;      //队尾指针域next,指向新结点
            rear = s;       //队尾指针,指向队尾
        } else {        // 2.3 中间
            p.next = s;
          s.next = q;
        }
    }
}

10.递归


10.1定义


  • 程序调用自身的编程技巧称为递归( recursion),由两部分组成:递推、回归。
  • 递推:方法依次调用,没有返回。
  • 回归:程序准备依次返回。微信图片_20220530224134.png

10.2算法:1-n和

package recursion;
public class TestSum {
    public static void main(String[] args) {
        System.out.println(sum(10));
    }
    /**
     * 求1-n的和
     * @param n
     * @return
     */
    private static int sum(int n) {
        if(n == 1) {
            return 1;
        }
        return n + sum(n-1);
    }
}

10.3算法:n!


package recursion;
public class TestFactorial {
    public static void main(String[] args) {
        System.out.println(factorial(4));
    }
    private static int factorial(int n) {
        if(n == 1) {
            return 1;
        }
        return n * factorial(n-1);
    }
}

  10.4算法:斐波那契数


  • 定义

0、1、1、2、3、5、8、13、21、34 .... n

固定值

f(0) = 0

f(1) = 1

后面的每一项都是前两项的和

f(2) = f(0) + f(1)

f(n) = f(n-1) + f(n-2)


算法

package recursion;
public class TestFibonacci {
    public static void main(String[] args) {
        // 斐波那契数列
        for(int i = 0 ; i <= 10 ; i ++) {
            System.out.print(fibonacci(i) + "、");
        }
    }
    /**
     * 计算斐波那契数列的第n项
     * f(0) = 0
     * f(1) = 1
     * ...
     * f(n) = f(n-1) + f(n-2)
     * @param n
     * @return
     */
    private static int fibonacci(int n) {
        if(n == 0) {
            return 0;
        }
        if(n == 1) {
            return 1;
        }
        return fibonacci(n-1) + fibonacci(n-2);
    }
}


相关文章
|
2天前
|
存储 C语言 C++
【C++数据结构——栈与队列】顺序栈的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现顺序栈的基本运算。开始你的任务吧,祝你成功!​ 相关知识 初始化栈 销毁栈 判断栈是否为空 进栈 出栈 取栈顶元素 1.初始化栈 概念:初始化栈是为栈的使用做准备,包括分配内存空间(如果是动态分配)和设置栈的初始状态。栈有顺序栈和链式栈两种常见形式。对于顺序栈,通常需要定义一个数组来存储栈元素,并设置一个变量来记录栈顶位置;对于链式栈,需要定义节点结构,包含数据域和指针域,同时初始化栈顶指针。 示例(顺序栈): 以下是一个简单的顺序栈初始化示例,假设用C语言实现,栈中存储
112 75
|
2天前
|
存储 C++ 索引
【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】
【数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】初始化队列、销毁队列、判断队列是否为空、进队列、出队列等。本关任务:编写一个程序实现环形队列的基本运算。(6)出队列序列:yzopq2*(5)依次进队列元素:opq2*(6)出队列序列:bcdef。(2)依次进队列元素:abc。(5)依次进队列元素:def。(2)依次进队列元素:xyz。开始你的任务吧,祝你成功!(4)出队一个元素a。(4)出队一个元素x。
24 13
【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】
|
2天前
|
存储 C语言 C++
【C++数据结构——栈与队列】链栈的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现链栈的基本运算。开始你的任务吧,祝你成功!​ 相关知识 初始化栈 销毁栈 判断栈是否为空 进栈 出栈 取栈顶元素 初始化栈 概念:初始化栈是为栈的使用做准备,包括分配内存空间(如果是动态分配)和设置栈的初始状态。栈有顺序栈和链式栈两种常见形式。对于顺序栈,通常需要定义一个数组来存储栈元素,并设置一个变量来记录栈顶位置;对于链式栈,需要定义节点结构,包含数据域和指针域,同时初始化栈顶指针。 示例(顺序栈): 以下是一个简单的顺序栈初始化示例,假设用C语言实现,栈中存储整数,最大
26 9
|
2天前
|
C++
【C++数据结构——栈和队列】括号配对(头歌实践教学平台习题)【合集】
【数据结构——栈和队列】括号配对(头歌实践教学平台习题)【合集】(1)遇到左括号:进栈Push()(2)遇到右括号:若栈顶元素为左括号,则出栈Pop();否则返回false。(3)当遍历表达式结束,且栈为空时,则返回true,否则返回false。本关任务:编写一个程序利用栈判断左、右圆括号是否配对。为了完成本关任务,你需要掌握:栈对括号的处理。(1)遇到左括号:进栈Push()开始你的任务吧,祝你成功!测试输入:(()))
21 7
|
2月前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
78 5
|
2月前
|
C语言
【数据结构】栈和队列(c语言实现)(附源码)
本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
261 9
|
2月前
|
存储 算法
非递归实现后序遍历时,如何避免栈溢出?
后序遍历的递归实现和非递归实现各有优缺点,在实际应用中需要根据具体的问题需求、二叉树的特点以及性能和空间的限制等因素来选择合适的实现方式。
42 1
|
2月前
|
存储 算法 Java
数据结构的栈
栈作为一种简单而高效的数据结构,在计算机科学和软件开发中有着广泛的应用。通过合理地使用栈,可以有效地解决许多与数据存储和操作相关的问题。
|
2月前
|
存储 JavaScript 前端开发
执行上下文和执行栈
执行上下文是JavaScript运行代码时的环境,每个执行上下文都有自己的变量对象、作用域链和this值。执行栈用于管理函数调用,每当调用一个函数,就会在栈中添加一个新的执行上下文。
|
2月前
|
存储
系统调用处理程序在内核栈中保存了哪些上下文信息?
【10月更文挑战第29天】系统调用处理程序在内核栈中保存的这些上下文信息对于保证系统调用的正确执行和用户程序的正常恢复至关重要。通过准确地保存和恢复这些信息,操作系统能够实现用户模式和内核模式之间的无缝切换,为用户程序提供稳定、可靠的系统服务。
57 4