C++与Java数据结构设计的区别(持续更新中)

1. 链表

1.1 C++代码示例

#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; // 1; 2
	}
	return 0;
}

1.2 Java代码示例

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

1.3 区别

C++使用带头双向循环链表。源码中只有一个头节点变量。

Java在jdk1.6之前使用带头双向循环链表,从1.7开始使用不带头双向不循环链表。

Java为什么要这么设计呢?

1、  first / last有更清晰的链头、链尾概念,代码看起来更容易明白。

2、  first / last方式能节省new一个headerEntry。(实例化headerEntry是为了让后面的方法更加统一,否则会多很多header的空校验)

3、  在链头/尾进行插入/删除操作,first /last方式更加快捷。

2. 堆

2.1 C++代码示例

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

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

2.3 区别

C++默认使用大根堆。

Java默认使用小根堆。

3. 红黑树

3.1 C++代码示例

#include <set>
#include <map>
int main()
{
	// 默认正序
	std::set<int> set;
	set.insert(2);
	set.insert(1);
	std::set<int>::iterator sit = set.begin();
	while (sit != set.end())
	{
		std::cout << *sit++ << std::endl; // 1; 2
	}
	std::map<char, int> map;
	map['b'] = 2;
	map['a'] = 1;
	std::map<char, int>::iterator mit = map.begin();
	while (mit != map.end())
	{
		std::cout << mit->first << ":" << mit->second << std::endl; // a:1; b:2
		++mit;
	}
	// 逆序
	std::set<int, std::greater<int>> reverseSet;
	std::map<char, int, std::greater<int>> reverseMap;
	return 0;
}

3.2 Java代码示例

import java.util.Comparator;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;
import java.util.TreeSet;
public class Test {
    public static void main(String[] args) {
        // 默认正序
        TreeSet<Integer> treeSet = new TreeSet<>();
        treeSet.add(2);
        treeSet.add(1);
        Iterator<Integer> sit = treeSet.iterator();
        while (sit.hasNext()) {
            System.out.println(sit.next()); // 1; 2
        }
        TreeMap<Character, Integer> treeMap = new TreeMap<>();
        treeMap.put('b', 2);
        treeMap.put('a', 1);
        Iterator<Map.Entry<Character, Integer>> mit = treeMap.entrySet().iterator();
        while (mit.hasNext()) {
            Map.Entry<Character, Integer> entry = mit.next();
            System.out.println(entry.getKey() + ":" + entry.getValue()); // a:1; b:2
        }
        // 逆序
        TreeSet<Integer> reverseTreeSet = new TreeSet<>(Comparator.reverseOrder());
        TreeMap<Character,Integer> reverseTreeMap = new TreeMap<>(Comparator.reverseOrder());
    }
}

3.3 区别

C++的set和map都是通过同一个红黑树模板来实现的,相互是解耦的。

公共模板_Tree中封装了一个红黑树根节点。

Java的TreeSet是通过TreeMap来实现的。

TreeSet内部封装了一个TreeMap。

而TreeMap中才真正封装了红黑树的根节点。

4. 哈希表

4.1 C++代码示例

#include <unordered_set>
#include <unordered_map>
int main()
{
	std::unordered_set<int> set;
	set.insert(2);
	set.insert(1);
	std::unordered_set<int>::iterator sit = set.begin();
	while (sit != set.end()) {
		std::cout << *sit++ << std::endl;// 2; 1
	}
	std::unordered_map<char, int> map;
	map['b'] = 2;
	map['a'] = 1;
	std::unordered_map<char, int>::iterator mit = map.begin();
	while (mit != map.end()) {
		std::cout << mit->first << ":" << mit->second << std::endl; // b:2; a:1
		++mit;
	}
	return 0;
}

4.2 Java代码示例

import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
public class Test {
    public static void main(String[] args) {
        HashSet<Integer> hashSet = new HashSet<>();
        hashSet.add(2);
        hashSet.add(1);
        Iterator<Integer> sit = hashSet.iterator();
        while (sit.hasNext()) {
            System.out.println(sit.next()); // 1; 2
        }
        HashMap<Character, Integer> hashMap = new HashMap<>();
        hashMap.put('b', 2);
        hashMap.put('a', 1);
        Iterator<Map.Entry<Character, Integer>> mit = hashMap.entrySet().iterator();
        while (mit.hasNext()) {
            Map.Entry<Character, Integer> entry = mit.next();
            System.out.println(entry.getKey() + ":" + entry.getValue()); // a:1; b:2
        }
    }
}

4.3 区别

4.3.1 耦合度不同

C++的unordered_set和unordered_map是通过继承同一个_Hash哈希表来实现的,相互是解耦的。

Java的HashSet内部是通过HashMap来实现的。

HashMap内部通过哈希表来实现。

4.3.2 组成结构不同

C++是通过数组+链表实现。使用了双向链表,插入方式为头插。

Java是通过数组+链表+红黑树实现。并且使用自定义单链表,插入方式为尾插。

单链表使用尾插后,得到链表长度再判断是否要转红黑树,因此选用尾插更加方便。

仿函数

C++代码示例

Java代码示例

区别

Lambda

C++代码示例

Java代码示例

区别

迭代器

C++代码示例

Java代码示例

区别

  • 10
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值