数据结构基础-线性表

一、线性表

1.1 线性表如何实现删除操作
  • 新增
    在这里插入图片描述
	s.next =p.next 
	p.next =s 
  • 删除
    在这里插入图片描述
	b= p.next 
	p.next = p.next.next;
  • 链表翻转

对于某个单向链表,它的指针结构造成了它的数据通路有去无回,一旦修改了某个指针,后面的数据就会造成失联的状态。为了解决这个问题,我们需要构造三个指针 prev、curr 和 next,对当前结点、以及它之前和之后的结点进行缓存,再完成翻转动作。具体如下图所示
添加链接描述
https://s0.lgstatic.com/i/image/M00/12/FE/Ciqc1F7OVEaAOjblAGtskMyw3Cc079.gif

while(curr){
    next = curr.next;
    curr.next = prev;
    prev = curr;
    curr = next;
}

1.2 栈- 后进先出的线性表

在这里插入图片描述

在这里插入图片描述

  • 场景
    1)浏览器的页面访问都包含了后退和前进功能
    https://s0.lgstatic.com/i/image/M00/16/04/CgqCHl7Uy5-ANiGoABFtWM1_uZU348.gif

2)给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串,判断字符串是否有效。有效字符串需满足:左括号必须与相同类型的右括号匹配,左括号必须以正确的顺序匹配。例如,{ [ ( ) ( ) ] } 是合法的,而 { ( [ ) ] } 是非法的。

public static void main(String[] args) {
    String s = "{[()()]}";
    System.out.println(isLegal(s));
}
private static int isLeft(char c) {
    if (c == '{' || c == '(' || c == '[') {
        return 1;
    } else {
        return 2;
    }
}
private static int isPair(char p, char curr) {
    if ((p == '{' && curr == '}') || (p == '[' && curr == ']') || (p == '(' && curr == ')')) {
        return 1;
    } else {
        return 0;
    }
}
private static String isLegal(String s) {
    Stack stack = new Stack();
    for (int i = 0; i < s.length(); i++) {
        char curr = s.charAt(i);
        if (isLeft(curr) == 1) {
            stack.push(curr);
        } else {
            if (stack.empty()) {
                return "非法";
            }
            char p = (char) stack.pop();
            if (isPair(p, curr) == 0) {
                return "非法";
            }
        }
    }
    if (stack.empty()) {
        return "合法";
    } else {
        return "非法";
    }
}


1.3 队列
  • 存储方式
    顺序队列,依赖数组来实现,其中的数据在内存中也是顺序存储。

而链式队列,则依赖链表来实现,其中的数据依赖每个结点的指针互联,在内存中并不是顺序存储。链式队列,实际上就是只能尾进头出的线性表的单链表。

在这里插入图片描述

  • 队列删除

队列删除数据的操作与栈不同。队列元素出口在队列头部,即下标为 0 的位置。当利用 front 指针删除一个数据时,队列中剩余的元素都需要向前移动一个位置,以保证队列头部下标为 0 的位置不为空,此时时间复杂度就变成 O(n) 了,状态如下图所示:

  • 循环队列

循环队列进行新增数据元素操作时,首先判断队列是否为满。如果不满,则可以将新元素赋值给队尾,然后让 rear 指针向后移动一个位置。如果已经排到队列最后的位置,则 rea r指针重新指向头部。

循环队列进行删除操作时,即出队列操作,需要判断队列是否为空,然后将队头元素赋值给返回值,front 指针向后移一个位置。如果已经排到队列最后的位置,就把 front 指针重新指向到头部。这个过程就好像钟表的指针转到了表盘的尾部 12 点的位置后,又重新回到了表盘头部 1 点钟的位置。这样就能在不开辟大量存储空间的前提下,不采用 O(n) 的操作,也能通过移动数据来完成频繁的新增和删除数据。

如果是循环队列,rear 指针就可以重新指向下标为 0 的位置,如下图所示:

在这里插入图片描述

如果这时再新增了 F 进入队列,就可以放入在下标为 0 的位置,rear 指针指向下标为 1 的位置。这时的 rear 和 front 指针就会重合,指向下标为 1 的位置,如下图所示:

在这里插入图片描述

  • 链式队列

在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值