常用数据结构-JAVA-C++-Python

前言:总结下常用数据结构,按照JAVA、C++、Python顺序依次对比

JAVA\C++\Python差异

日常语法差异

0、Python的真假使用True或False,首字母大写
1、python使用缩进来划分语句块
2、python每个条件或循环判断等后面要使用冒号 :
3、在Python中没有switch – case语句
4、Python 中用 elif 代替了 else if
5、Python的异常处理是try: exception xxx: else:
6、Python读取的输入是字符串,即读入整数也是字符串,需要强转才是整数类型

多条件判断

java和c++复合条件的区别不大,只不过java使用null、c++使用NULL
python 使用 and or not

函数

python定义def
普通函数调用则没太大区别
类中方法内部调用使用self.xxx

面向对象–类

注:面向对象python区别较大,下面突出说明
1、python类用class声明
2、类中方法的第一个参数为self,self代表类的实例,可以理解为this,而非类。self.__class__则指向类

3、类有一个名为 __init__() 的特殊方法(构造方法),该方法在类实例化时会自动调用
4、__private_attrs:两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问。在类内部的方法中使用时 self.__private_attrs
5、__private_method:两个下划线开头,声明该方法为私有方法,只能在类的内部调用 ,不能在类的外部调用。self.__private_methods

6、python支持多继承
7、Python同样支持运算符重载

常用数据结构差异

注:python的数据结构较为特殊,甚至有些太灵活。

Java有一些较好的工具类,如Arrays、Collections、String、Random

        Arrays.sort();

		Arrays.fill(); // 2参数
        Arrays.asList(); // 对应的讲链表转化为数组需要先开辟空间
        Arrays.toString();
        
        Arrays.copyOf(); // 2参数
        System.arraycopy(); // 5参数
        
	Collections.reverse(arraylist);
	Collections.binarySearch(list,key); // 二分查找,在不需要自定义二分场合很方便

String.format("%08d", number);

数组array或列表

注:链表可认为动态数组

java

1、基本类型和引用类型数组,固定大小数组

2、动态数组,注:里面只能是引用
ArrayList<>、LinkedList<>

        new ArrayList<>();
        new LinkedList<>();

C++

array 固定大小数组,需给定容量大小
vector 动态数组

    array<int, 10> myarry;

    vector<int> vector;
    vector.push_back();

Python

注:python数组可分为可变的列表与不可变的元组,方法基本相似

列表 [ ]
元组 ( )

映射或字典

java

        new HashMap<>();
        new TreeMap<>();
        new LinkedHashMap<>(); // 需要有序的情况下会用

C++

一个底层红黑树,一个hash

#include 
#include 
    map<int, int> map;
    unordered_map<int, int> hashMap;

Python

注:python字典就是映射,表示 { },注意一下遍历方式与java的区别

dict = {'a': 71, 'b':72, 'c':73}

for k, v in dict.items(): # 这里k,v之间需要,分隔
    print(k + " " + str(v))

for k in dict.keys():
    print(k + " " + str(dict[k]))

for v in dict.values():
    print(str(v))

字符串

注:这里面方法很多,需要好好注意

java

        new String();
        new StringBuilder();
        new StringBuffer();

C++

#include 
    string str = "hello world";
    cout<<str<<endl;
    const char* cstr = str.c_str(); // 必须加const

集合

java

        new HashSet<>();
        new TreeSet<>();

C++

#include 
#include 
    set<int> set;
    unordered_set<int> hashSet;

Python

java

注:链表作为栈的方法很多,头尾都可以充当栈底。使用时非常容易弄混

        Stack stack = new Stack<Integer>;
        LinkedList<Integer> stack2 = new LinkedList<>(); // 链表充当栈

stack.push(-1);
Integer i = stack.pop();
Integer i = stack.peek();//looks at 

        // 当做栈使用,队头作为栈顶,只用下面方法啊
        stack2.push(1); // This method is equivalent to addFirst
        stack2.peek(); // the head (first element) of this list.
        stack2.pop(); // This method is equivalent to removeFirst().
        
        // 当做栈使用,队尾作为栈顶,只用下面的方法
        stack2.addLast(1);
        stack2.peekLast();
        stack2.pollLast();

C++

#include 
	stack<int> stack;

Python

注:python的栈直接用列表充当即可

队列

注:队列有单向和双向之分,还有优先队列这种使用少,一旦使用就非常方便。

java

注:
1、两种当做队列、leetcode用linkedList很多
2、add() peek() remove() poll() size(),每样两种,但是会有区别,有一种抛异常

        Queue<Integer> queue = new ArrayDeque<>(); 
        // implements Deque 实现了队列接口
        Queue<Integer> queue2 = new LinkedList<>(); 
        // implements List, Deque实现了两个接口,因为是双向链表,相当于双向队列
        
        queue.peek(); // 查看队头
        queue.poll(); // 队头出队,空返回null不会抛异常
        queue.remove(); // 队头出队
        queue.add(1); // 队尾入队

// 优先队列,默认最小值在前,其余不需要有序。可以自定义排序规则
	PriorityQueue<Integer> queue = new PriorityQueue<>();

C++

注:队列有单向和双向之分

#include 
#include 
    deque<int> deque; // 双向队列
    deque.push_back(1);
    deque.push_front(1);
    deque.front();
    deque.back();
    deque.pop_front();
    deque.pop_back();
    
    queue<int> queue; // 单向队列
    queue.push(1); // 队尾入
    queue.front(); // 队头
    queue.pop(); // 队头出

Python

补充kmp算法

注:后续移到其他位置,并未完全清楚
KMP算法—终于全部弄懂了
KMP算法详解-彻底清楚了(转载+部分原创)

class Solution {
    public static void main(String[] args) {
        String pattern = "abab";
        int[] next = getNext(pattern);
        int[] nextOptimal = getNextOptimal(pattern);
        System.out.println(Arrays.toString(next));
        System.out.println(Arrays.toString(nextOptimal));
        System.out.println("****************************");
        String s = "abacbcdhiabab";
        int kmp = KMP(s, pattern);
        System.out.println(kmp);
    }

    public static int KMP(String s, String pattern) {
        char[] t = s.toCharArray();
        char[] p = pattern.toCharArray();
        int i = 0; // 主串的位置
        int j = 0; // 模式串的位置
        int[] next = getNext(pattern);
        while (i < t.length && j < p.length) {
            if (j == -1 || t[i] == p[j]) { // 当j为-1时,要移动的是i,当然j也要归0
                i++;
                j++;
            } else {
                // i不需要回溯了
                // i = i - j + 1;
                j = next[j]; // j回到指定位置
            }
        }
        if (j == p.length) {
            return i - j; // 模式字符串走到末尾表明完全匹配上
        } else {
            return -1;
        }
    }

	// 未优化
    public static int[] getNext(String ps) {
        char[] p = ps.toCharArray();
        int[] next = new int[p.length];
        next[0] = -1;
        int j = 0;
        int k = -1;
        while (j < p.length - 1) {
            if (k == -1 || p[j] == p[k]) {
                next[++j] = ++k;
            } else {
                k = next[k];
            }
        }
        return next;
    }

	// 优化后
    public static int[] getNextOptimal(String ps) {
        char[] p = ps.toCharArray();
        int[] next = new int[p.length];
        next[0] = -1;
        int j = 0;
        int k = -1;
        while (j < p.length - 1) {
            if (k == -1 || p[j] == p[k]) {
                if (p[++j] == p[++k]) { // 当两个字符相等时要跳过
                    next[j] = next[k];
                } else {
                    next[j] = k;
                }
            } else {
                k = next[k];
            }
        }
        return next;
    }
}

你可能感兴趣的:(常用数据结构-JAVA-C++-Python)