单双链表、栈和队列、递归和Master公式、哈希表和有序表的使用和性能

03 单双链表、栈和队列、递归和Master公式、哈希表和有序表的使用和性能

内容:

  • 单链表、双链表

  • 栈、队列

  • 递归的物理实质

  • 评估递归复杂度的Master公式

  • 哈希表的使用和性能

  • 有序表的使用和性能

题目:

反转单链表、反转双链表


public static Node reverseLinkedList(Node head) {
    Node pre = null;
    Node next = null;
    while (head != null) {
        next = head.next;
        head.next = pre;
        pre = head;
        head = next;
    }
    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 class Node {
    public int value;
    public Node next;

    public Node(int data) {
        this.value = data;
    }
}

// head = removeValue(head, 2);
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;
}

双端链表


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 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;
  }
}

实现有getMin功能的栈


public static class MyStack1 {
    private Stack<Integer> stackData;
    private Stack<Integer> stackMin;

    public MyStack1() {
        stackData = new Stack<Integer>();
        stackMin = new Stack<Integer>();
    }

    public void push(int newNum) {
        if (stackMin.isEmpty() || newNum <= this.getmin()) {
            stackMin.push(newNum);
        }
        stackData.push(newNum);
    }

    public int pop() {
        if (stackData.isEmpty()) {
            throw new RuntimeException("Your stack is empty.");
        }
        int value = stackData.pop();
        if (value == getmin()) {
            stackMin.pop();
        }
        return value;
    }

    public int getmin() {
        if (stackMin.isEmpty()) {
            throw new RuntimeException("Your stack is empty.");
        }
        return stackMin.peek();
    }
}

public static class MyStack2 {
    private Stack<Integer> stackData;
    private Stack<Integer> stackMin;

    public MyStack2() {
        stackData = new Stack<Integer>();
        stackMin = new Stack<Integer>();
    }

    public void push(int newNum) {
        if (stackMin.isEmpty() || newNum < getmin()) {
            stackMin.push(newNum);
        } else {
            stackMin.push(stackMin.peek());
        }
        stackData.push(newNum);
    }

    public int pop() {
        if (stackData.isEmpty()) {
            throw new RuntimeException("Your stack is empty.");
        }
        stackMin.pop();
        return stackData.pop();
    }

    public int getmin() {
        if (stackMin.isEmpty()) {
            throw new RuntimeException("Your stack is empty.");
        }
        return stackMin.peek();
    }
}

两个栈实现队列


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());
}

两个队列实现栈


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!");

}

用递归行为得到数组中的最大值,并用master公式来估计时间复杂度


// 求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);
}

哈希表和有序表使用的code展示


public static class Node {
    public int value;

    public Node(int v) {
        value = v;
    }
}

public static class Zuo {
    public int value;

    public Zuo(int v) {
        value = v;
    }
}

public static void main(String[] args) {

    HashMap<Integer, String> test = new HashMap<>();
    Integer a = 19000000;
    Integer b = 19000000;
    System.out.println(a == b);

    test.put(a, "我是3");
    System.out.println(test.containsKey(b));

    Zuo z1 = new Zuo(1);
    Zuo z2 = new Zuo(1);
    HashMap<Zuo, String> test2 = new HashMap<>();
    test2.put(z1, "我是z1");
    System.out.println(test2.containsKey(z2));

    // UnSortedMap
    HashMap<Integer, String> map = new HashMap<>();
    map.put(1000000, "我是1000000");
    map.put(2, "我是2");
    map.put(3, "我是3");
    map.put(4, "我是4");
    map.put(5, "我是5");
    map.put(6, "我是6");
    map.put(1000000, "我是1000001");

    System.out.println(map.containsKey(1));
    System.out.println(map.containsKey(10));

    System.out.println(map.get(4));
    System.out.println(map.get(10));

    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("=====================");

    Integer c = 100000;
    Integer d = 100000;
    System.out.println(c.equals(d));

    Integer e = 127; // - 128 ~ 127
    Integer f = 127;
    System.out.println(e == f);

    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 有序表:接口名
    // 红黑树、avl、sb树、跳表
    // O(logN)
    System.out.println("有序表测试开始");
    TreeMap<Integer, String> treeMap = new TreeMap<>();

    treeMap.put(3, "我是3");
    treeMap.put(4, "我是4");
    treeMap.put(8, "我是8");
    treeMap.put(5, "我是5");
    treeMap.put(7, "我是7");
    treeMap.put(1, "我是1");
    treeMap.put(2, "我是2");

    System.out.println(treeMap.containsKey(1));
    System.out.println(treeMap.containsKey(10));

    System.out.println(treeMap.get(4));
    System.out.println(treeMap.get(10));

    treeMap.put(4, "他是4");
    System.out.println(treeMap.get(4));

    // treeMap.remove(4);
    System.out.println(treeMap.get(4));

    System.out.println("新鲜:");

    System.out.println(treeMap.firstKey());
    System.out.println(treeMap.lastKey());
    // <= 4
    System.out.println(treeMap.floorKey(4));
    // >= 4
    System.out.println(treeMap.ceilingKey(4));
    // O(logN)

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值