栈、队列、数组

栈和队列是操作受限的线性表,因此不是任何对线性表的操作都可以作为栈和队列的操作。比如,不可以随便读取栈或队列中间的某个数据

我们每一次接触到一个新的数据结构都应该分别从其逻辑结构、存储结构和数据的运算三个方面进行分析。

栈的逻辑结构

后进先出(LIFO)的受限线性表。

栈的数学性质

n个不同元素入栈,出栈元素不同排列的个数为卡特兰数
C 2 n n / ( n + 1 ) C^n_{2n}/(n+1) C2nn/(n+1)

栈的存储结构

顺序栈

顺序栈只能发生上溢,因为栈的插入和删除操作都是在栈顶进行的。

实现

利用一组地址连续的存储单元存放自栈底到栈顶的数据元素,同时附设一个指针指示当前栈顶元素的位置。

基本运算
共享栈

利用栈底位置相对不变的特性,可让两个顺序栈共享一个一维数组空间,讲两个栈的占地分别设置在共享空间的两端,两个栈顶向共享空间的中间延伸。

链栈

通常采用单链表实现,并规定所有操作都是在单链表的表头进行的。

队列

队列的逻辑结构

先进先出(FIFO)的受限线性表,只允许在队列的一段插入,而再另一端删除。向队列插入元素我们称之为入队,删除队列中的元素我们称之为出队。

队列的存储结构

顺序存储

顺序队列

顺序队列的实现是指分配一块连续的存储单元存放队列中的元素,并附设两个指针:队头指针front和队尾指针rear。

逻辑结构不是循环队列的顺序队列会出现“假溢出”的问题。

循环队列

将顺序队列假象成为一个环状的空间,即把存储队列元素的表从逻辑上视为一个环,又称循环队列。

当队首指针 Q.front = MaxSize - 1 后,再前进一个位置就自动到 0 ,这可以用 % 运算来实现。

  • 初始时: Q.front = Q.rear = 0
  • 队头指针进1:Q.front = (Q.front + 1) % MaxSize
  • 队尾指针进1:Q.rear = (Q.rear + 1) % MaxSize
  • 队列长度:(Q.rear + MaxSize - Q.front) % MaxSize

至于队空队满的判断方法,需要根据具体问题中队front和rear的定义,自行判断

链式存储

队列的链式存储表示称之为链队列,它实际上是一个带有队头指针和队尾指针的单链表。

头指针指向对头结点,尾指针指向队尾节点,即单链表的最后一个节点(注意这里与顺序存储可能有所不同,顺序存储有时候队尾指针指向的是队尾节点的下一个节点。)

不带头节点的链式队列在操作上,队列为空时,插入删除操作都需要特殊处理,因此通常将链式队列设计成一个带头节点的单链表,从而统一插入删除操作。

双端队列

双端队列是指两端都可以进行入队和出队操作的队列。其元素的逻辑结构仍然是线性结构。将队列的两端分别成为前端和后端,两端都可以出队和入队。

通常分为两种受限的双端队列:

  • 输出受限的双端队列:允许在一端进行插入和删除,但在另一端只允许插入的双端队列。
  • 输入受限的双端队列:允许在一端进行插入和删除,但在另一端指允许删除的双端队列。

判断双端队列输出序列的问题是比较难的问题。

数组和特殊矩阵

数组的逻辑结构

数组是由n个相同类型的数据元素构成的有限序列,每个数据元素称为一个数组元素,每个元素在n个线性关系的序号被成为该元素的下标,下标的取值范围称为数组的维界。

数组是线性表的推广。一维数组可视为一个线性表,二维数组可视为其元素是定长线性表的线性表,以此类推。

数组的存储结构

一个数组的所有元素在内存中占用一段连续的存储空间(顺序存储)。

对于多维数组,有两种映射方法:按行优先、按列优先

特殊矩阵的压缩存储

**压缩存储:**指为多个值相同的元素只分配一个存储空间,对零元素不分配存储空间

**特殊矩阵:**矩阵中相同的矩阵元素或零元素的分布有一定规律性的矩阵。常见的特殊矩阵有对称矩阵、三角矩阵、对角矩阵等。

  1. 对称矩阵:上三角所有元素和下三角所有对应元素相同。

    只存储下三角部分元素。

  2. 三角矩阵:上(下)三角区的所有元素均为同一常量。

    存储下三角和主对角线上所有元素后,紧接着存储对角线上方的常量一次。

  3. 对角矩阵:又称带状矩阵。常见的有三对角矩阵。

    三对角矩阵:所有非零元素都集中在以主对角线为中心的3条对角线的区域,其他区域的元素都为0。

稀疏矩阵

矩阵中的非零元素个数非常少。

因此,可以采用三元组的方式进行存储,然后按照某种规律存储这些三元组(可以采用数组存储,也可以采用十字链表法存储)。

稀疏矩阵压缩存储后便失去了随机存取特性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java实现的代码: ```java public class Stack { private int maxSize; private int[] stackArray; private int top; public Stack(int size) { maxSize = size; stackArray = new int[maxSize]; top = -1; } public void push(int value) { if (isFull()) { System.out.println("Stack is full!"); return; } stackArray[++top] = value; } public int pop() { if (isEmpty()) { System.out.println("Stack is empty!"); return -1; } return stackArray[top--]; } public int peek() { if (isEmpty()) { System.out.println("Stack is empty!"); return -1; } return stackArray[top]; } public boolean isEmpty() { return (top == -1); } public boolean isFull() { return (top == maxSize - 1); } } ``` Java实现队列的代码: ```java public class Queue { private int maxSize; private int[] queueArray; private int front; private int rear; private int nItems; public Queue(int size) { maxSize = size; queueArray = new int[maxSize]; front = 0; rear = -1; nItems = 0; } public void insert(int value) { if (isFull()) { System.out.println("Queue is full!"); return; } if (rear == maxSize - 1) { rear = -1; } queueArray[++rear] = value; nItems++; } public int remove() { if (isEmpty()) { System.out.println("Queue is empty!"); return -1; } int temp = queueArray[front++]; if (front == maxSize) { front = 0; } nItems--; return temp; } public int peekFront() { if (isEmpty()) { System.out.println("Queue is empty!"); return -1; } return queueArray[front]; } public boolean isEmpty() { return (nItems == 0); } public boolean isFull() { return (nItems == maxSize); } } ``` Java实现数组的代码: ```java public class MyArray { private int[] array; private int length; public MyArray(int[] arr) { array = arr; length = arr.length; } public int get(int index) { if (index < 0 || index >= length) { System.out.println("Invalid index!"); return -1; } return array[index]; } public void set(int index, int value) { if (index < 0 || index >= length) { System.out.println("Invalid index!"); return; } array[index] = value; } public int length() { return length; } public void display() { for (int i = 0; i < length; i++) { System.out.print(array[i] + " "); } System.out.println(); } } ``` Java实现链表的代码: ```java public class Node { public int value; public Node next; public Node(int val) { value = val; next = null; } } public class LinkedList { private Node head; public LinkedList() { head = null; } public void insertFirst(int value) { Node newNode = new Node(value); newNode.next = head; head = newNode; } public Node deleteFirst() { if (isEmpty()) { System.out.println("List is empty!"); return null; } Node temp = head; head = head.next; return temp; } public boolean isEmpty() { return (head == null); } public void display() { Node current = head; while (current != null) { System.out.print(current.value + " "); current = current.next; } System.out.println(); } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值