(一)算法基础
1 基本概念
- 链表:插入数据的时间复杂度为O(1),查找元素的时间复杂度为O(N);
- 栈:栈是限制插入和删除元素操作只能在栈顶上进行的表,因而称为先入后出表,提供push、pop和top操作,其中,对空栈执行pop和top视为一个错误;
- 队列:队列与栈不同,插入在一端进行,删除在另一端进行,因而称为先入先出表,提供enqueue和dequeue操作,其中,对空队执行dequeue视为一个错误;
- 二叉树:一颗树的每个节点不能多于两个节点的树称为二叉树,此外,如果限制对于树中的每个节点x,它的左子树的所有项的值小于x中项的值,它的右子树的所有项的值大于x中项的值,则改二叉树称为二叉查找树或者二叉搜索树。
2 实现
2.1 链表
用途:辅助实现其他算法
实现:LinkedList通过双向链表实现,增删效率高而查找效率低,常用的增删查改方法如下:
- 添加元素
public void add(int index, E element); 向指定位置插入元素 public boolean add(E e); 尾部添加元素并返回是否成功
- 删除元素
public E remove(int index); 删除指定位置的元素并返回该元素 public boolean remove(Object o); 删除某一元素,返回是否成功 public void clear(); 清空链表
- 查找元素
public boolean contains(Object o),判断是否含有某一元素; public E get(int index),返回指定位置的元素;
- 更改元素
public E set(int index, E element),设置指定位置的元素;
2.2 栈
用途:辅助实现其他算法
实现:Java中的内置栈位于java.util.Stack,其中,常用方法以及Demo如下:
/**************************************************************************************/
public E push(E item); 入栈 public E pop(); 出栈 public E peek(); 查看栈顶元素 public boolean empty(); 判断栈是否为空 public int search(Object o); 判断元素是否存在栈中,如果不存在则返回-1,存在则返回出栈的次序(从1开始) /***************************************************************************************/ class Demo { public static void main(String[] args) { Stack<String> stack = new Stack<String>(); // 入栈 stack.push("22"); stack.push("11"); // 查看元素是否存在,不存在则返回-1,存在则返回出栈的次序(1,2,3...) System.out.println(stack.search("11")); System.out.println(stack.search("22")); System.out.println(stack.search("33")); // 出栈 while (!stack.isEmpty()) { System.out.println("下一个出栈的元素为:" + stack.peek()); System.out.println(stack.pop()); } } }
相关知识点:判断入栈与出栈顺序是否一致:
典型题目:输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的),经典实现方式是通过模拟入栈出栈过程,如下:
/** * 验证进栈与出栈顺序是否相同的方式:直接模拟进栈出栈过程 */ import java.util.*; public class Solution { public boolean IsPopOrder(int [] pushA,int [] popA) { ArrayList<Integer> arrayA = new ArrayList<Integer>(); for(int i=0,j=0;i<pushA.length;i++){ arrayA.add(pushA[i]); for(;popA[j]==arrayA.get(arrayA.size()-1) && j<popA.length;j++){ arrayA.remove(arrayA.size()-1); if(arrayA.isEmpty()){ break; } } } return arrayA.isEmpty(); } }
2.3 队列
用途:辅助实现其他算法
实现:JDK中,LinkedList类实现了Queue接口,可以当作Queue使用,其中,常用方法以及Demo如下:
/**************************************************************************************/ public E offer(E item); 入队 public E pop(); 出队 public E element(); 查看下一出队元素 public boolean isEmpty(); 判断队列是否为空 public boolean contains(Object o); 判断元素是否存在栈中,对于自定义类型需重载equals方法 /***************************************************************************************/ class Demo { public static void main(String[] args) { Queue<String> queue = new LinkedList<String>(); queue.offer("22"); queue.offer("11"); while(!queue.isEmpty()){ System.out.println("下一个出队的元素为:" + queue.element()); queue.poll(); } } }
2.4 优先队列
用途:排序
实现:Java中的内置优先队列位于java.util.PriorityQueue,其中,常用方法同普通队列,Demo如下:
class Example { private String data; private Integer index; public Example(Integer index, String data) { this.index = index; this.data = data; } public Integer getIndex() { return index; } @Override public String toString() { return "index:" + index + ", data:" + data; } } class IHello2 { public static void main(String[] args) { // 内置类型 Queue<Integer> queue = new PriorityQueue<Integer>((a1, a2) -> { // 要升序排列则这里应该返回-1,如果降序排列则应该返回1,这里很重要!!! if (a1 < a2) { return 1; } if (a1 > a2) { return -1; } return 0; }); queue.offer(11); queue.offer(2); queue.offer(33); while (!queue.isEmpty()) { System.out.println(queue.poll()); } // 自定义类型 Queue<Example> define = new PriorityQueue<Example>((a1, a2) -> { // 按Index的升序排列 if (a1.getIndex() > a2.getIndex()) { return 1; } if (a1.getIndex() < a2.getIndex()) { return -1; } return 0; }); define.offer(new Example(11,"huaiheng11")); define.offer(new Example(2,"huaiheng2")); define.offer(new Example(33,"huaiheng33")); while (!define.isEmpty()) { System.out.println(define.poll()); } } }
有疑问欢迎留言