链表
C++代码示例
cpp
#include <list>
int main() {
std::list<int> list;
list.push_front(1);
list.push_back(2);
std::list<int>::iterator it = list.begin();
while (it != list.end())
{
std::cout << *it++ << std::endl;
}
return 0;
}
Java代码示例
cpp
import java.util.LinkedList;
import java.util.ListIterator;
public class Test {
public static void main(String[] args) {
LinkedList<Integer> linkedList = new LinkedList<>();
linkedList.addFirst(1);
linkedList.addLast(2);
ListIterator<Integer> it = linkedList.listIterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
}
区别
C++使用带头双向循环链表。源码中只有一个头节点变量。
Java在jdk1.6之前使用带头双向循环链表,从1.7开始使用不带头双向不循环链表。
Java为什么要这么设计呢?
1、 first / last有更清晰的链头、链尾概念,代码看起来更容易明白。
2、 first / last方式能节省new一个headerEntry。(实例化headerEntry是为了让后面的方法更加统一,否则会多很多header的空校验)
3、 在链头/尾进行插入/删除操作,first /last方式更加快捷。
**个人理解:**Java这样设计效率与带头的并没有明显区别,仅在实现与C++选用了不同的方式。
堆
C++代码示例
cpp
#include <queue>
#include <vector>
int main() {
// 默认大根堆,比较仿函数默认为less,正好和直觉反了,比较特殊
// 模板类型默认展开:std::priority_queue<int,std::vector<int>,std::less<int>>
std::priority_queue<int> maxQ;
maxQ.push(1);
maxQ.push(2);
std::cout << maxQ.top() << std::endl; // 2
// 小根堆,比较仿函数传greater
std::priority_queue<int,std::vector<int>,std::greater<int>> minQ;
minQ.push(1);
minQ.push(2);
std::cout << minQ.top() << std::endl; // 1
return 0;
}
Java代码示例
java
import java.util.Comparator;
import java.util.PriorityQueue;
public class Test {
public static void main(String[] args) {
// 默认小根堆
PriorityQueue<Integer> minQ = new PriorityQueue<>();
minQ.offer(1);
minQ.offer(2);
System.out.println(minQ.peek()); // 1
// 大根堆,传一个相反比较器
Comparator<Integer> reverseCmp = new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2.compareTo(o1);
}
};
PriorityQueue<Integer> maxQ = new PriorityQueue<>(reverseCmp);
// lambda简写:maxQ = new PriorityQueue<>(Comparator.reverseOrder());
maxQ.offer(1);
maxQ.offer(2);
System.out.println(maxQ.peek()); // 2
}
}
区别
C++默认使用大根堆。
Java默认使用小根堆。