2.链表结构、栈、队列、递归行为、哈希表和有序表

简介: 2.链表结构、栈、队列、递归行为、哈希表和有序表

链表结构、栈、队列、递归行为、哈希表和有序表

链表节点结构
单向链表节点结构
public class Node{
  public int value;
  public Node next;
  public Node(int data){
    value=data;
  }
}
双向链表节点结构
public class DoubleNode{
  public int value;
  public DoubleNode last;
  public DoubleNode next;
  public DoubleNode(int data){
    value=data;
  }
}
单向链表和双向链表最简单的练习题(链表的相关问题几乎都是coding问题)
1、反转单向链表和双向链表
package com.harrison.two;
import java.util.ArrayList;
import java.util.List;
//反转单向链表和双向链表
public class Code01_ReverseList {
  public static class Node {
    public int value;
    public Node next;
    public Node(int data) {// 构造方法
      this.value = data;
    }
  }
  public static class DoubleNode {
    public int value;
    public DoubleNode last;
    public DoubleNode next;
    public DoubleNode(int data) {
      this.value = data;
    }
  }
  // 反转单链表
  // 1->2->3->4
  public static Node reverseLinkedList(Node head) {
    Node pre = null;
    Node next = null;
    while (head != null) {
      next = head.next;// next指向2,意味着next就是2->3->4
      head.next = pre;// head.next为null,意味着1和2断开,此时head就是1
      pre = head;// pre为1,这是反转后的链表
      head = next;// head重新赋值为next,也就是2->3->4
    }
    return pre;
  }
  // 反转双向链表
  public static DoubleNode reverseDoubleList(DoubleNode head) {
    DoubleNode pre = null;
    DoubleNode next = null;
    while (head != null) {
      next = head.next;
      head.next = pre;
      head.last = next;
      pre = head;
      head = next;
    }
    return pre;
  }
  public static Node testReverseLinkedList(Node head) {
    if (head == null) {
      return null;
    }
    ArrayList<Node> list = new ArrayList<>();
    while (head != null) {
      list.add(head);
      head = head.next;
    }
    list.get(0).next = null;
    int N = list.size();
    for (int i = 1; i < N; i++) {
      list.get(i).next = list.get(i - 1);
    }
    return list.get(N - 1);
  }
  public static DoubleNode testReverseDoubleList(DoubleNode head) {
    if (head == null) {
      return null;
    }
    ArrayList<DoubleNode> list = new ArrayList<>();
    while (head != null) {
      list.add(head);
      head = head.next;
    }
    list.get(0).next = null;
    DoubleNode pre = list.get(0);
    int N = list.size();
    for (int i = 1; i < N; i++) {
      DoubleNode cur = list.get(i);
      cur.last = null;
      cur.next = pre;
      pre.last = cur;
      pre = cur;
    }
    return list.get(N - 1);
  }
  public static Node generateRandomLinkedList(int len, int value) {
    int size = (int) (Math.random() * (len + 1));
    if (size == 0) {
      return null;
    }
    size--;
    Node head = new Node((int) (Math.random() * (value + 1)));
    Node pre = head;
    while (size != 0) {
      Node cur = new Node((int) (Math.random() * (value + 1)));
      pre.next = cur;
      pre = cur;
      size--;
    }
    return head;
  }
  public static DoubleNode generateRandomDoubleList(int len, int value) {
    int size = (int) (Math.random() * (len + 1));
    if (size == 0) {
      return null;
    }
    size--;
    DoubleNode head = new DoubleNode((int) (Math.random() * (value + 1)));
    DoubleNode pre = head;
    while (size != 0) {
      DoubleNode cur = new DoubleNode((int) (Math.random() * (value + 1)));
      pre.next = cur;
      cur.last = pre;
      pre = cur;
      size--;
    }
    return head;
  }
  public static List<Integer> getLinkedListOriginOrder(Node head) {
    List<Integer> ans = new ArrayList<>();
    while (head != null) {
      ans.add(head.value);
      head = head.next;
    }
    return ans;
  }
  public static boolean checkLinkedListReverse(List<Integer> origin, Node head) {
    for (int i = origin.size() - 1; i >= 0; i--) {
      if (!origin.get(i).equals(head.value)) {
        return false;
      }
      head = head.next;
    }
    return true;
  }
  public static List<Integer> getDoubleListOriginOrder(DoubleNode head) {
    List<Integer> ans = new ArrayList<>();
    while (head != null) {
      ans.add(head.value);
      head = head.next;
    }
    return ans;
  }
  public static boolean checkDoubleListReverse(List<Integer> origin, DoubleNode head) {
    DoubleNode end = null;
    for (int i = origin.size() - 1; i >= 0; i--) {
      if (!origin.get(i).equals(head.value)) {
        return false;
      }
      end = head;
      head = head.next;
    }
    for (int i = 0; i < origin.size(); i++) {
      if (!origin.get(i).equals(end.value)) {
        return false;
      }
      end = end.last;
    }
    return true;
  }
  public static void main(String[] args) {
    int len = 50;
    int value = 100;
    int testTime = 100000;
    System.out.println("test begin!");
    for (int i = 0; i < testTime; i++) {
      Node node1 = generateRandomLinkedList(len, value);
      List<Integer> list1 = getLinkedListOriginOrder(node1);
      node1 = reverseLinkedList(node1);
      if (!checkLinkedListReverse(list1, node1)) {
        System.out.println("Oops1!");
      }
      Node node2 = generateRandomLinkedList(len, value);
      List<Integer> list2 = getLinkedListOriginOrder(node2);
      node2 = testReverseLinkedList(node2);
      if (!checkLinkedListReverse(list2, node2)) {
        System.out.println("Oops2!");
      }
      DoubleNode node3 = generateRandomDoubleList(len, value);
      List<Integer> list3 = getDoubleListOriginOrder(node3);
      node3 = reverseDoubleList(node3);
      if (!checkDoubleListReverse(list3, node3)) {
        System.out.println("Oops3!");
      }
      DoubleNode node4 = generateRandomDoubleList(len, value);
      List<Integer> list4 = getDoubleListOriginOrder(node4);
      node4 = reverseDoubleList(node4);
      if (!checkDoubleListReverse(list4, node4)) {
        System.out.println("Oops4!");
      }
    }
    System.out.println("test finish!");
  }
}
2、把给定值都删除
package com.harrison.two;
//删除给定值
public class Code02_DeleteGivenValue {
  public static class Node {
    public int value;
    public Node next;
    public Node(int data) {
      this.value = data;
    }
  }
  public static Node removeValue(Node head, int num) {
    // head来到第一个不需要删的位置
    while (head != null) {
      if (head.value != num) {
        break;
      }
      head = head.next;
    }
    // 1 ) head == null
    // 2 ) head != null
    Node pre = head;
    Node cur = head;
    while (cur != null) {
      if (cur.value == num) {
        pre.next = cur.next;
      } else {
        pre = cur;
      }
      cur = cur.next;
    }
    return head;
  }
}
栈和队列的实际实现

其底层实现原理双向链表的调整,而且时间复杂度都是O(1),跟数据量没有关系,因为总是在操作一个头和一个尾。实现方式有两种:双向链表实现和数组实现

栈和队列常见面试题:怎么用数组实现不超过固定大小的队列和栈?栈——正常使用 队列——环形数组

1、双向链表实现
package com.harrison.two;
import java.util.Stack;
import java.util.LinkedList;
import java.util.Queue;
//栈和队列的实际实现:1、双向链表实现
//使用双向链表节点类型实现一个队列
public class Code03_DoubleEndsQueueToStackAndQueue {
  // 双向链表节点类型
  public static class Node<T> {
    public T value;
    public Node<T> last;
    public Node<T> next;
    public Node(T data) {
      this.value = data;
    }
  }
  public static class DoubleEndsQueue<T> {
    public Node<T> head;
    public Node<T> tail;
    public void addFromHead(T value) {
      Node<T> cur = new Node<T>(value);
      if (head == null) {
        head = cur;
        tail = cur;
      } else {
        cur.next = head;
        head.last = cur;
        head = cur;
      }
    }
    public void addFromBottom(T value) {
      Node<T> cur = new Node<T>(value);
      if (head == null) {
        head = cur;
        tail = cur;
      } else {
        cur.last = tail;
        tail.next = cur;
        tail = cur;
      }
    }
    public T popFromHead() {
      if (head == null) {
        return null;
      }
      Node<T> cur = head;
      if (head == tail) {
        head = null;
        tail = null;
      } else {
        head = head.next;
        cur.next = null;
        head.last = null;
      }
      return cur.value;
    }
    public T popFromBottom() {
      if (head == null) {
        return null;
      }
      Node<T> cur = tail;
      if (head == tail) {
        head = null;
        tail = null;
      } else {
        tail = tail.last;
        tail.next = null;
        cur.last = null;
      }
      return cur.value;
    }
    public boolean isEmpty() {
      return head == null;
    }
  }
  public static class MyStack<T> {
    private DoubleEndsQueue<T> queue;
    public MyStack() {
      queue = new DoubleEndsQueue<T>();
    }
    public void push(T value) {
      queue.addFromHead(value);
    }
    public T pop() {
      return queue.popFromHead();
    }
    public boolean isEmpty() {
      return queue.isEmpty();
    }
  }
  public static class MyQueue<T> {
    private DoubleEndsQueue<T> queue;
    public MyQueue() {
      queue = new DoubleEndsQueue<T>();
    }
    public void push(T value) {
      queue.addFromHead(value);
    }
    public T poll() {
      return queue.popFromBottom();
    }
    public boolean isEmpty() {
      return queue.isEmpty();
    }
  }
  public static boolean isEqual(Integer o1, Integer o2) {
    if (o1 == null && o2 != null) {
      return false;
    }
    if (o1 != null && o2 == null) {
      return false;
    }
    if (o1 == null && o2 == null) {
      return true;
    }
    return o1.equals(o2);
  }
  public static void main(String[] args) {
    int oneTestDataNum = 100;
    int value = 10000;
    int testTimes = 100000;
    for (int i = 0; i < testTimes; i++) {
      MyStack<Integer> myStack = new MyStack<>();
      MyQueue<Integer> myQueue = new MyQueue<>();
      Stack<Integer> stack = new Stack<>();
      Queue<Integer> queue = new LinkedList<>();
      for (int j = 0; j < oneTestDataNum; j++) {
        int nums = (int) (Math.random() * value);
        if (stack.isEmpty()) {
          myStack.push(nums);
          stack.push(nums);
        } else {
          if (Math.random() < 0.5) {
            myStack.push(nums);
            stack.push(nums);
          } else {
            if (!isEqual(myStack.pop(), stack.pop())) {
              System.out.println("oops!");
            }
          }
        }
        int numq = (int) (Math.random() * value);
        if (stack.isEmpty()) {
          myQueue.push(numq);
          queue.offer(numq);
        } else {
          if (Math.random() < 0.5) {
            myQueue.push(numq);
            queue.offer(numq);
          } else {
            if (!isEqual(myQueue.poll(), queue.poll())) {
              System.out.println("oops!");
            }
          }
        }
      }
    }
    System.out.println("finish!");
  }
}
2、数组实现
package com.harrison.two;
//栈和队列的实际实现:2、数组实现
public class Code04_RingArray {
  public static class MyQueue {
    private int[] arr;
    private int pushi;// end
    private int polli;// begin
    private int size;
    private final int limit;
    public MyQueue(int limit) {
      arr = new int[limit];
      pushi = 0;
      polli = 0;
      size = 0;
      this.limit = limit;
    }
    public void push(int value) {
      if (size == limit) {
        throw new RuntimeException("队列满了,不能再加了");
      }
      size++;
      arr[pushi] = value;
      pushi = nextIndex(pushi);
    }
    public int pop() {
      if (size == 0) {
        throw new RuntimeException("队列空了,不能再拿了");
      }
      size--;
      int ans = arr[polli];
      polli = nextIndex(polli);
      return ans;
    }
    public boolean isEmpty() {
      return size == 0;
    }
    // 如果现在的下标是i,返回下一个位置
    private int nextIndex(int i) {
      return i < limit - 1 ? i + 1 : 0;
    }
  }
}
3、实现一个特殊的栈,在基本功能(pop()和push())的基础上,再实现返回栈中最小元素的功能
  • pop()、push()、getMin()操作的时间都是O(1)
  • 设计的栈类型可以使用现成的栈结构

分析1):设计两个栈,data栈和min栈,data栈是普通的栈,正常加数据,第一个数两个栈都加,从第二个数开始,min栈加数据的原则为:当前的数和目前最小栈的栈顶谁小加谁。所以说,data栈和min栈同步上升,弹出数据的时候两个栈一起弹,弹出数据没有规则。这种方法费一点空间,省一点时间,因为弹出时不要判断。

分析2):前面相同,从第二个数开始,如果当前数比最小栈的栈顶大,不压入min栈;如果当前数小于等于最小栈的栈顶,压入min栈。弹出规则:当前要弹出的数与最小栈的栈顶相等的时候弹出。这种方法省一点空间,费一点时间

package com.harrison.two;
import java.util.Stack;
//实现一个特殊的栈,在基本功能(pop()和push())的基础上,再实现返回栈中最小元素的功能
public class Code05_GetMinStack {
  public static class MyStack1 {
    private Stack<Integer> stackData;
    private Stack<Integer> stackMin;
    public MyStack1() {
      this.stackData = new Stack<Integer>();
      this.stackMin = new Stack<Integer>();
    }
    public void push(int newNum) {
      if (this.stackMin.isEmpty()) {
        this.stackMin.push(newNum);
      } else if (newNum <= this.getmin()) {
        this.stackMin.push(newNum);
      }
      this.stackData.push(newNum);
    }
    public int pop() {
      if (this.stackData.isEmpty()) {
        throw new RuntimeException("Your stack is empty.");
      }
      int value = this.stackData.pop();
      if (value == this.getmin()) {
        this.stackMin.pop();
      }
      return value;
    }
    public int getmin() {
      if (this.stackMin.isEmpty()) {
        throw new RuntimeException("Your stack is empty.");
      }
      return this.stackMin.peek();
    }
  }
  public static class MyStack2 {
    private Stack<Integer> stackData;
    private Stack<Integer> stackMin;
    public MyStack2() {
      this.stackData = new Stack<Integer>();
      this.stackMin = new Stack<Integer>();
    }
    public void push(int newNum) {
      if (this.stackMin.isEmpty()) {
        this.stackMin.push(newNum);
      } else if (newNum < this.getmin()) {
        this.stackMin.push(newNum);
      } else {
        int newMin = this.stackMin.peek();
        this.stackMin.push(newMin);
      }
      this.stackData.push(newNum);
    }
    public int pop() {
      if (this.stackData.isEmpty()) {
        throw new RuntimeException("Your stack is empty.");
      }
      this.stackMin.pop();
      return this.stackData.pop();
    }
    public int getmin() {
      if (this.stackMin.isEmpty()) {
        throw new RuntimeException("Your stack is empty.");
      }
      return this.stackMin.peek();
    }
  }
  public static void main(String[] args) {
    MyStack1 stack1 = new MyStack1();
    stack1.push(3);
    System.out.println(stack1.getmin());
    stack1.push(4);
    System.out.println(stack1.getmin());
    stack1.push(1);
    System.out.println(stack1.getmin());
    System.out.println(stack1.pop());
    System.out.println(stack1.getmin());
    System.out.println("=============");
    MyStack1 stack2 = new MyStack1();
    stack2.push(3);
    System.out.println(stack2.getmin());
    stack2.push(4);
    System.out.println(stack2.getmin());
    stack2.push(1);
    System.out.println(stack2.getmin());
    System.out.println(stack2.pop());
    System.out.println(stack2.getmin());
  }
}
如何用栈结构实现队列结构(用两个栈)

如何用两个栈拼队列结构:设计两个栈,push栈和pop栈,压入pop栈的时候,pop必须为空。push栈倒出数据的时候,一定要一次全都倒空

package com.harrison.two;
import java.util.Stack;
//如何用栈结构实现队列结构:用两个栈拼队列结构
public class Code06_TwoStacksImplementQueue {
  public static class TwoStacksQueue {
    public Stack<Integer> stackPush;
    public Stack<Integer> stackPop;
    public TwoStacksQueue() {
      stackPush = new Stack<Integer>();
      stackPop = new Stack<Integer>();
    }
    // push栈向pop栈倒入数据
    private void pushToPop() {
      if (stackPop.empty()) {
        while (!stackPush.empty()) {
          stackPop.push(stackPush.pop());
        }
      }
    }
    public void add(int pushInt) {
      stackPush.push(pushInt);
      pushToPop();
    }
    public int poll() {
      if (stackPop.empty() && stackPush.empty()) {
        throw new RuntimeException("Queue is empty!");
      }
      pushToPop();
      return stackPop.pop();
    }
    public int peek() {
      if (stackPop.empty() && stackPush.empty()) {
        throw new RuntimeException("Queue is empty!");
      }
      pushToPop();
      return stackPop.peek();
    }
  }
  public static void main(String[] args) {
    TwoStacksQueue test = new TwoStacksQueue();
    test.add(1);
    test.add(2);
    test.add(3);
    System.out.println(test.peek());
    System.out.println(test.poll());
    System.out.println(test.peek());
    System.out.println(test.poll());
    System.out.println(test.peek());
    System.out.println(test.poll());
  }
}
如何用队列结构实现栈结构(用两个队列)
package com.harrison.two;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
//如何用队列结构实现栈结构(用两个队列)
public class Code07_TwoQueueImplementStack {
  public static class TwoQueueStack<T> {
    public Queue<T> queue;
    public Queue<T> help;
    public TwoQueueStack() {
      queue = new LinkedList<>();
      help = new LinkedList<>();
    }
    public void push(T value) {
      queue.offer(value);
    }
    public T poll() {
      while (queue.size() > 1) {
        help.offer(queue.poll());
      }
      T ans = queue.poll();
      Queue<T> tmp = queue;
      queue = help;
      help = tmp;
      return ans;
    }
    public T peek() {
      while (queue.size() > 1) {
        help.offer(queue.poll());
      }
      T ans = queue.poll();
      help.offer(ans);
      Queue<T> tmp = queue;
      queue = help;
      help = tmp;
      return ans;
    }
    public boolean isEmpty() {
      return queue.isEmpty();
    }
  }
  public static void main(String[] args) {
    System.out.println("test begin");
    TwoQueueStack<Integer> myStack = new TwoQueueStack<>();
    Stack<Integer> test = new Stack<>();
    int testTime = 1000000;
    int max = 1000000;
    for (int i = 0; i < testTime; i++) {
      if (myStack.isEmpty()) {
        if (!test.isEmpty()) {
          System.out.println("Oops");
        }
        int num = (int) (Math.random() * max);
        myStack.push(num);
        test.push(num);
      } else {
        if (Math.random() < 0.25) {
          int num = (int) (Math.random() * max);
          myStack.push(num);
          test.push(num);
        } else if (Math.random() < 0.5) {
          if (!myStack.peek().equals(test.peek())) {
            System.out.println("Oops");
          }
        } else if (Math.random() < 0.75) {
          if (!myStack.poll().equals(test.pop())) {
            System.out.println("Oops");
          }
        } else {
          if (myStack.isEmpty() != test.isEmpty()) {
            System.out.println("Oops");
          }
        }
      }
    }
    System.out.println("test finish!");
  }
}
递归
  • 怎么从思想上理解递归
  • 怎么从实际实现的角度出发理解递归

递归是有实际结构支持其运行的,任何递归行为都能改成非递归行为,方法就是不让系统帮忙压栈,而是自己去压栈模拟这个行为。因为递归实际上运用的是系统栈。

例:求数组arr[L…R]中的最大值,怎么用递归方法实现:

  1. 将arr[L…R]范围分成左右两半,左边[L…Mid],右边[Mid+1…R]
  2. 左部分求最大值,右部分求最大值
  3. [L…R]范围上的最大值就是max{左部分最大值,右部分最大值}

注意:2是个递归过程,当范围上只有一个数,就可以不用再递归了

package com.harrison.two;
public class Code08_GetMax {
  // 求arr中的最大值
  public static int getMax(int[] arr) {
    return process(arr, 0, arr.length - 1);
  }
  // arr[L..R]范围上求最大值 L ... R N
  public static int process(int[] arr, int L, int R) {
    // arr[L..R]范围上只有一个数,直接返回,base case
    if (L == R) {
      return arr[L];
    }
    // L...R 不只一个数
    // mid = (L + R) / 2
    int mid = L + ((R - L) >> 1); // 中点 1
    int leftMax = process(arr, L, mid);
    int rightMax = process(arr, mid + 1, R);
    return Math.max(leftMax, rightMax);
  }
}
哈希表和有序表
哈希表

Java中int、double、float等基本类型是按值传递;Integer、Double、Float等包裹出来的大类型,使用的时候是按引用传递,但是如果值在-128~127范围时,又变成按值传递。超过此范围才按引用传递。但是这些大类型在哈希表里一律按值传递!!!但是哈希表并不总是按值传递,非系统规定的类型,如自己定义的类型就会按引用传递。

哈希表在使用层面可以理解为一种集合结构,如果只有key,没有伴随数据value,可以使用HashSet结构;如果都有,可以使用HashMap结构。有无伴随数据是二者唯一的区别,实际结构是一回事。

使用哈希表增删改查的操作,可以认为时间复杂度为O(1),但是常数时间比较大。

有序表

哈希表所有的增删改查有序表都支持,次外,可以把记录乱序存入有序表,但在有序表内部是按顺序组织好的,从小到大的顺序。但是以上操作的时间复杂度为O(logn)。

package com.harrison.two;
import java.util.HashMap;
import java.util.HashSet;
import java.util.TreeMap;
public class HashMapAndSortedMap {
  public static class Node{
    public int value;
    public Node(int v) {
      value=v;
    }
  }
  public static void main(String[] args) {
    //      key      value
    HashMap<Integer, String>map=new HashMap<>();
    map.put(1,"我是1");
    map.put(2,"我是2");
    map.put(3,"我是3");
    map.put(4,"我是4");
    System.out.println(map.containsKey(1));
    System.out.println(map.containsKey(10));
    System.out.println(map.get(4));
    System.out.println(map.get(10));
    System.out.println(map.get(10)==null);
    map.put(4,"他是4");
    System.out.println(map.get(4));
    map.remove(4);
    System.out.println(map.get(4));
    //      key
    HashSet<String> set=new HashSet<>();
    set.add("abc");
    set.contains("abc");
    set.remove("abc");
    //哈希表 增、删、改、查,在使用时,时间复杂度都是O(1)
    System.out.println("=====================");
    int a=100000;
    int b=100000;
    System.out.println(a==b);
    Integer c=100000;
    Integer d=100000;
    System.out.println(c==d);
    Integer e=127;
    Integer f=127;
    System.out.println(e==f);
    Integer g=128;
    Integer h=128;
    System.out.println(g==h);
    HashMap<Node, String> map2=new HashMap<>();
    Node node1=new Node(1);
    Node node2=node1;
    map2.put(node1, "我是node1");
    map2.put(node2, "我是node1");
    System.out.println(map2.size());
    System.out.println("======================");
    TreeMap<Integer, String> treeMap=new TreeMap<>();
    treeMap.put(10,"我是10");
    treeMap.put(2,"我是2");
    treeMap.put(40,"我是40");
    treeMap.put(7,"我是7");
    System.out.println(treeMap.containsKey(1));
    System.out.println(treeMap.containsKey(10));
    System.out.println(treeMap.get(4));
    System.out.println(treeMap.get(10));
    System.out.println(treeMap.get(10)==null);
    treeMap.put(4,"他是4");
    System.out.println(treeMap.get(4));
    treeMap.remove(4);
    System.out.println(treeMap.get(4));
    System.out.println(treeMap.firstKey());
    System.out.println(treeMap.lastKey());
    //<=8
    System.out.println(treeMap.floorKey(8));
    //>=8
    System.out.println(treeMap.ceilingKey(8));
  }
}

   


相关文章
|
1月前
|
存储 算法 搜索推荐
探索常见数据结构:数组、链表、栈、队列、树和图
探索常见数据结构:数组、链表、栈、队列、树和图
85 64
|
4月前
|
存储 C++
C++的list-map链表与映射表
```markdown C++ 中的`list`和`map`提供链表和映射表功能。`list`是双向链表,支持头尾插入删除(`push_front/push_back/pop_front/pop_back`),迭代器遍历及任意位置插入删除。`map`是键值对集合,自动按键排序,支持直接通过键来添加、修改和删除元素。两者均能使用范围for循环遍历,`map`的`count`函数用于统计键值出现次数。 ```
|
5月前
|
数据安全/隐私保护
第2章 栈、队列、链表
第2章 栈、队列、链表
|
5月前
|
存储 C++
C++的list-map链表与映射表
这篇教程介绍了C++中`list`链表和`map`映射表的基本使用。`list`链表可通过`push_front()`、`push_back()`、`pop_front()`和`pop_back()`进行元素的添加和删除,使用迭代器遍历并支持在任意位置插入或删除元素。`map`是一个键值对的集合,元素自动按键值排序,可使用下标操作符或`insert()`函数插入元素,通过迭代器遍历并修改键值对,同时提供`count()`方法统计键值出现次数。教程中包含多个示例代码以帮助理解和学习。
|
5月前
|
存储 算法 数据可视化
深入解析力扣160题:相交链表的解决方法(哈希表法与双指针法详细图解)
深入解析力扣160题:相交链表的解决方法(哈希表法与双指针法详细图解)
|
5月前
|
SQL 算法 数据可视化
LeetCode题目92:反转链表ll 【python 递归与迭代方法全解析】
LeetCode题目92:反转链表ll 【python 递归与迭代方法全解析】
|
6月前
|
算法 测试技术
【数据结构与算法 | 基础篇】单向循环链表实现队列
【数据结构与算法 | 基础篇】单向循环链表实现队列
|
5月前
栈和链表的区分
栈和链表的区分
20 0
|
6月前
|
存储 调度 C语言
链表,栈,队列的区别及其应用
链表,栈,队列的区别及其应用
|
5月前
|
存储 SQL 算法
LeetCode力扣第114题:多种算法实现 将二叉树展开为链表
LeetCode力扣第114题:多种算法实现 将二叉树展开为链表