我是靠谱客的博主 舒服豆芽,最近开发中收集的这篇文章主要介绍数据结构学习笔记(一) 基础数据结构Date Structure Note Part.1,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

文章目录

  • Date Structure Note Part.1
    • Big O notation: Runtime Complexity
    • Space complexity
    • Lists
      • Arrays
        • operation
      • Build an Array
      • LinkedList
        • Overview of Linked Lists
        • Runtime Complexity
        • Build a Linked List
      • Array VS LinkedList
        • Quick
        • Compare runtime complexity
        • Interview Question
    • Stack
      • What can use for
      • Feature: LIFO (Last in First out)
      • Operations
      • Interview Question
      • Build a Stack
    • Queues
      • What can use for
      • Feature: FIFO (First in First out)
      • Operations
      • Interview Question
      • Build a Queue
      • Build a Priority Queue (Default: min Heap)
    • Hash Tables
      • What can use for
      • Operations
      • Interview Question
      • Hash Function
      • Collisions
      • Build a Hash Table

Date Structure Note Part.1

Big O notation: Runtime Complexity

  1. O(1): constance
  2. O(n): related to the input size
  3. O(n^2): O(n * n) very slow
  4. O(log n): very fast
  5. O(2^n): very very slow

Sort: O(1) > O(log n) > O(n) > O(n^2) > O(2^n)

Space complexity

  1. O(1) : constance
  2. O(n): related to the input size

Lists

Arrays

operation

  1. Lookup by Index: O(1)
  2. Lookup by Value: O(n)
  3. Insert: O(n)
  4. Delete: O(n)

Build an Array

package Arrays;
public class Main {
public static void main(String[] args) {
Array numbers = new Array(3);
numbers.insert(10);
numbers.insert(20);
numbers.insert(30);
numbers.insert(40);
numbers.removeAt(3);
System.out.println(numbers.indexOf(100));
}
}
package Arrays;
public class Array {
private int[] array;
private int lastIndex = -1;
public Array(int length) {
array = new int[length];
}
public void insert(int item) {
if (lastIndex + 1 >= array.length) resize();
array[++lastIndex] = item;
}
public int removeAt(int index) {
if (index > lastIndex) return -1;
int result = array[index];
for (int i = index + 1; i <= lastIndex; i++)
array[i - 1] = array[i];
lastIndex--;
return result;
}
public int indexOf(int item) {
for (int i = 0; i <= lastIndex; i++)
if (array[i] == item) return i;
return -1;
}
private void resize() {
int[] newArray = new int[array.length * 2];
// O(n)
for (int i = 0; i < array.length; i++)
newArray[i] = array[i];
array = newArray;
}
}

LinkedList

Overview of Linked Lists

  1. view: Head -> Node -> … -> Tail
  2. Structure: Value nextNode

Runtime Complexity

  1. Insert: At the End: O(1); At the Beginning: O(1); In the Middle: O(n);
  2. Delete: From the End: O(n); From the Beginning: O(1); From the Middle: O(n);

Build a Linked List

package Arrays;
public class Main {
public static void main(String[] args) {
LinkedList numbers = new LinkedList();
numbers.addFirst(10);
numbers.addFirst(20);
numbers.addFirst(30);
numbers.addFirst(40);
numbers.deleteFirst();
System.out.println(numbers.toString());
System.out.println(numbers.indexOf(100));
}
package LinkedList;
import java.util.Arrays;
import java.util.NoSuchElementException;
public class LinkedList {
private class Node {
private int value;
private Node next;
public Node(int value) {
this.value = value;
}
}
private Node first;
private Node last;
private int size = 0;
public void addFirst(int item) {
if (isEmpty()) first = last = new Node(item);
else {
Node node = new Node(item);
node.next = first;
first = node;
}
size++;
}
public void addLast(int item) {
if (isEmpty()) first = last = new Node(item);
else {
Node node = new Node(item);
last.next = node;
last = node;
}
size++;
}
public void deleteFirst() {
if (isEmpty()) throw new NoSuchElementException();
if (size == 1)
first = last = null;
else {
Node temp = first;
first = first.next;
temp.next = null;
}
size--;
}
public void deleteLast() {
if (isEmpty()) throw new NoSuchElementException();
if (size == 1)
first = last = null;
else {
Node previous = getPrevious(last);
last = previous;
previous.next = null;
}
size--;
}
private Node getPrevious(Node node) {
Node current = first;
while (current != null && current.next != node)
current = current.next;
return null;
}
public int indexOf(int item) {
int index = -1;
Node current = first;
for (int i = 0; i < size; i++) {
if (current.value == item) index = i;
current = current.next;
}
return index;
}
public boolean contains(int item) {
return indexOf(item) != -1;
}
public int size() {
return size;
}
public boolean isEmpty() {
return first == null || last == null;
}
@Override
public String toString() {
Node current = first;
int[] output = new int[size];
for (int i = 0; i < size; i++) {
output[i] = current.value;
current = current.next;
}
return Arrays.toString(output);
}
}

Array VS LinkedList

Quick

  1. Static arrays have a fixed size
  2. Dynamic arrays grow by 50-100%
  3. Linked lists don’t waste memory
  4. Use arrays if you know the number of items to store
  5. new ArrayList(100)

Compare runtime complexity

Lookup Arrays LinkedList

By Index O(1) O(n)

By Value O(n) O(n)

Insert

Beginning/End O(n) O(1)

Middle O(n) O(n)

Delete

Beginning O(n) O(1)

Middle O(n) O(n)

End O(n) O(n)/O(1) -> double linked list

Interview Question

  1. Reverse a linked list. (three pointer)

    eg. [10, 20, 30] -> [30, 20, 10]

public void reverse() {
if (isEmpty()) return;
Node previous = first;
Node current = first.next;
while (current != null) {
Node next = current.next;
current.next = previous;
previous = current;
current = next;
}
last = first;
last.next = null;
first = previous;
}
  1. Find the Kth node from the end of a linked list in one pass. (two pointer)

    eg. [10, 20, 30, 40, 50] k=1(50); k=2(40)…

public int getKthFromTheEnd(int k) {
int distance = k - 1;
if (distance > size || k <= 0) throw new IllegalArgumentException();
Node left = first, right = first;
for (int i = 0; i < distance; i++)
right = right.next;
while (right.next != null) {
left = left.next;
right = right.next;
}
return left.value;
}

Stack

What can use for

  1. Implement the undo feature
  2. Build compilers
  3. Evaluate expressions
  4. Build navigation

Feature: LIFO (Last in First out)

Operations

  1. push(item) O(1)
  2. pop() O(1)
  3. peek() O(1)
  4. isEmpty() O(1)

Interview Question

  1. Reversing a sting. (implement by stack)

    eg. “abcd” -> “dcba”

public String reverse(String str) {
if (str == null) throw new IllegalArgumentException();
Stack<Character> stack = new Stack<>();
StringBuilder stringBuilder = new StringBuilder();
for (char ch : str.toCharArray())
stack.add(ch);
while (!stack.isEmpty())
stringBuilder.append(stack.pop());
return stringBuilder.toString();
}
  1. Is string balanced.

    eg. “(1 + 1)” is balance; "(1 + " is not balance.

public static boolean isbalanced(String input) {
if (input == null) throw new IllegalArgumentException();
Stack<Character> leftBrace = new Stack<>();
Stack<Character> rightBrace = new Stack<>();
for (char ch : input.toCharArray())
if (
ch == '{' ||
ch == '[' ||
ch == '(' ||
ch == '<' ||
ch == '>' ||
ch == ')' ||
ch == ']' ||
ch == '}')
leftBrace.push(ch);
while (!leftBrace.isEmpty()) {
char ch = leftBrace.peek();
if (
ch == '>' ||
ch == ')' ||
ch == ']' ||
ch == '}') {
rightBrace.add(leftBrace.pop());
continue;
}
if (ch == '<')
if (rightBrace.isEmpty() || rightBrace.peek() != '>')
return false;
if (ch == '(')
if (rightBrace.isEmpty() || rightBrace.peek() != ')')
return false;
if (ch == '[')
if (rightBrace.isEmpty() || rightBrace.peek() != ']')
return false;
if (ch == '{')
if (rightBrace.isEmpty() || rightBrace.peek() != '}')
return false;
rightBrace.pop();
leftBrace.pop();
}
return rightBrace.isEmpty();
}
private final List<Character> leftBrackets = Arrays.asList('{', '[', '(', '<');
private final List<Character> rightBrackets = Arrays.asList('}', ']', ')', '>');
public boolean isbalanced(String input) {
Stack<Character> stack = new Stack<>();
for (char ch : input.toCharArray()) {
if (isLeftBracket(ch))
stack.push(ch);
if (isRightBracket(ch)) {
if (stack.empty()) return false;
char top = stack.pop();
if (bracketsMatch(top, ch)) return false;
}
}
return true;
}
private boolean isLeftBracket(char ch) {
return leftBrackets.contains(ch);
}
private boolean isRightBracket(char ch) {
return rightBrackets.contains(ch);
}
private boolean bracketsMatch(char left, char right) {
return leftBrackets.indexOf(left) == rightBrackets.indexOf(right);
}

Build a Stack

import Stack.Stack;
public class Main {
public static void main(String[] args) {
Stack stack = new Stack();
stack.push(1);
stack.push(2);
stack.push(3);
stack.push(4);
stack.push(5);
int res = stack.pop();
System.out.println(res);
System.out.println(stack);
}
}
package Stack;
import java.util.Arrays;
import java.util.EmptyStackException;
public class Stack {
private int[] items;
private int count = 0;
public Stack() {
items = new int[10];
}
public void push(int item) {
if (count == items.length) throw new StackOverflowError();
items[count++] = item;
}
public int pop() {
if (count == 0) throw new EmptyStackException();
return items[--count];
}
public int peek() {
if (count == 0) throw new EmptyStackException();
return items[count - 1];
}
public boolean isEmpty() {
return count == 0;
}
@Override
public String toString() {
int[] content = Arrays.copyOfRange(items, 0, count);
return Arrays.toString(content);
}
}

Queues

What can use for

  1. resources management
  2. printers
  3. operating systems
  4. web serbers
  5. live support systems

Feature: FIFO (First in First out)

Operations

  1. enqueue O(1) PriorityQueue: enqueue O(n)
  2. dequeue O(1)
  3. peek O(1)
  4. isEmpty O(1)
  5. isFull O(1)

Interview Question

  1. reverse a queue. (only allow using addremoveisEmpty)
public void reverse(Queue<Integer> queue) {
Stack<Integer> stack = new Stack<>();
while (!queue.isEmpty())
stack.push(queue.remove());
while (!stack.isEmpty())
queue.add(stack.pop());
}
  1. using two stack build a queue
package Queue;
import java.util.Stack;
public class StackQueue {
private Stack<Integer> enqueue = new Stack<>();
private Stack<Integer> dequeue = new Stack<>();
public void add(int item) {
enqueue.add(item);
}
public int remove() {
if (isEmpty()) throw new IllegalStateException();
moveEnqueueStackToDequeueStack();
return dequeue.pop();
}
public int peek() {
if (isEmpty()) throw new IllegalStateException();
moveEnqueueStackToDequeueStack();
return dequeue.peek();
}
private void moveEnqueueStackToDequeueStack() {
if (dequeue.isEmpty())
while (!enqueue.isEmpty())
dequeue.add(enqueue.pop());
}
private boolean isEmpty() {
return enqueue.isEmpty() && dequeue.isEmpty();
}
}

Build a Queue

package Queue;
import java.util.Arrays;
public class ArrayQueue {
private int[] items = new int[5];
private int front = 0;
private int rear = 0;
private int count;
public void enqueue(int item) {
if (isFull()) throw new IllegalStateException();
items[rear] = item;
rear = (rear + 1) % items.length;
count++;
}
public int dequeue() {
int item = items[front];
items[front++] = 0;
front = (front + 1) % items.length;
count--;
return item;
}
public int peek() {
return items[front];
}
public boolean isEmpty() {
return count == 0;
}
public boolean isFull() {
return count == items.length;
}
@Override
public String toString() {
return Arrays.toString(items);
}
}

Build a Priority Queue (Default: min Heap)

package Queue;
import java.util.Arrays;
public class PriorityQueue {
private int[] items = new int[5];
private int count;
public void add(int item) {
if (isFull()) throw new IllegalStateException();
if (isEmpty()) {
items[count++] =
item;
return;
}
int i = shiftItemsToInsert(item);
items[i] = item;
count++;
}
private int shiftItemsToInsert(int item) {
int i;
for (i = count - 1; i >= 0; i--) {
if (item < items[i])
items[i + 1] = items[i];
else
break;
}
return i + 1;
}
public int remove() {
if (isEmpty()) throw new IllegalStateException();
return items[--count];
}
private boolean isEmpty() {
return count == 0;
}
private boolean isFull() {
return count == items.length;
}
@Override
public String toString() {
return Arrays.toString(items);
}
}

Hash Tables

What can use for

  1. Spell checkers
  2. Dictionaries
  3. Compilers
  4. Code editors

Operations

  1. Insert O(1)
  2. Lookup O(1)
  3. Delete O(1)

Interview Question

  1. Find the first none repeated character.

    eg. “A Green Apple” -> ‘G’

public static char findTheFirstNoneRepeatedCharacter(String str) {
str = str.toLowerCase();
Map<Character, Integer> dic = new HashMap<>();
char[] chars = str.toCharArray();
for (char ch : chars) {
if (!dic.containsKey(ch)) dic.put(ch, 1);
else dic.put(ch, dic.get(ch) + 1);
}
for (char ch : chars)
if (dic.get(ch) == 1) return ch;
return ' ';
}
public static char findTheFirstNoneRepeatedCharacter2(String str) {
if (str == null || str.trim() == "") return ' ';
String copy = str.toLowerCase();
Set<Character> repeated = new HashSet<>();
int left = 0, right = 1;
while (right < copy.length() && left < right) {
if (copy.charAt(left) == ' ') left++;
if (copy.charAt(left) != copy.charAt(right)) right++;
else repeated.add(copy.charAt(left++));
}
return left < copy.length()
&& !repeated.contains(copy.charAt(left))
? copy.charAt(left)
: ' ';
}
  1. Find the first repeated character.

    eg. “green apple” -> ‘e’

public static char findTheFirstRepeatedChar(String str) {
Set<Character> repeated = new HashSet<>();
Set<Character> noneRepeated = new HashSet<>();
char[] chars = str.toLowerCase().toCharArray();
for (char ch : chars) {
if (!noneRepeated.contains(ch)) noneRepeated.add(ch);
else repeated.add(ch);
}
for (char ch : chars)
if (repeated.contains(ch)) return ch;
return ' ';
}

Hash Function

  1. “1234” -> 10
  2. If the array size is 5, then mod the result by 5, and we get 0;
  3. “1234” -> 0;

Collisions

When input two different keys, but we get the same address.

​ eg. Key1->O->address<-O<-Key2

Solution:

  1. Channing: eg. Address: ????->Key1->Key2
  2. Open Addressing:
    1. Linear Probing: (hash(key) + i) % table_size
    2. Quadratic Probing: (hash(key) + i^2) % table_size
    3. Double Hashing:
      1. hash2(key) = prime - (key % prime);
      2. index = (hash1(key) + i * hash2(key)) % table_size;

Build a Hash Table

import HashTable.HashTable;
public class Main {
public static void main(String[] args) {
HashTable dic = new HashTable();
dic.put(6, "b");
dic.put(1, "a");
System.out.println(dic.get(1));
}
}
package HashTable;
import java.util.LinkedList;
public class HashTable {
private class Entry {
private int key;
private String value;
public Entry(int key, String value) {
this.key = key;
this.value = value;
}
}
private LinkedList<Entry>[] entries = new LinkedList[5];
public void put(int key, String value) {
Entry entry = getEntry(key);
if (entry != null) {
entry.value = value;
return;
}
getOrCreateBucket(key).add(new Entry(key, value));
}
private int hash(int key) {
return key % entries.length;
}
public String get(int key) {
Entry entry = getEntry(key);
return entry == null ? null : entry.value;
}
public void remove(int key) {
Entry entry = getEntry(key);
if (entry == null) throw new IllegalStateException();
getBucket(key).remove(entry);
}
private Entry getEntry(int key) {
int index = hash(key);
LinkedList<Entry> bucket = entries[index];
if (bucket != null)
for (Entry entry : bucket)
if (entry.key == key)
return entry;
return null;
}
private LinkedList<Entry> getBucket(int key) {
return entries[hash(key)];
}
private LinkedList<Entry> getOrCreateBucket(int key) {
int index = hash(key);
LinkedList<Entry> bucket = entries[index];
if (bucket == null) entries[index] = new LinkedList<>();
return bucket;
}
}

最后

以上就是舒服豆芽为你收集整理的数据结构学习笔记(一) 基础数据结构Date Structure Note Part.1的全部内容,希望文章能够帮你解决数据结构学习笔记(一) 基础数据结构Date Structure Note Part.1所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(42)

评论列表共有 0 条评论

立即
投稿
返回
顶部