Python
- 字符串: 单引号或者双引号
- 数字: int float complex
- list [] 可以存不同类型数据的数组
- tuple () 不可更改的列表
- dict {k:v} 可以自定义的索引列表
- set {} 无序不重复
数据结构
数据结构 : 其实就是存储数据和表⽰数据的⽅式。数据结构内容⽐较多,细细的学起来也是相对费功夫 的,不可能达到⼀蹴⽽就。我们将常⻅的数据结构:堆栈、队列、数组、链表和红⿊树 这⼏种给⼤家介 绍⼀下,作为数据结构的⼊⻔,了解⼀下它们的特点即可。
栈:stack,⼜称堆栈,
它是运算受限的线性表,其限制是仅允许在表的⼀端进⾏插⼊和删除操作, 不允许在其他任何位置进⾏添加、查找、删除等操作。 简单的说:采⽤该结构的集合,对元素的存取有如下的特点 先进后出(即,存进去的元素,要在后它后⾯的元素依次取出后,才能取出该元素)。例如,⼦弹 压进弹夹,先压进去的⼦弹在下⾯,后压进去的⼦弹在上⾯,当开枪时,先弹出上⾯的⼦弹,然后 才能弹出下⾯的⼦弹。 栈的⼊⼝、出⼝的都是栈的顶端位置。
这⾥两个名词需要注意: 压栈:就是存元素。即,把元素存储到栈的顶端位置,栈中已有元素依次向栈底⽅向移动⼀个位 置。弹栈:就是取元素。即,把栈的顶端位置元素取出,栈中已有元素依次向栈顶⽅向移动⼀个位置。
队列队列:queue,简称队,
它同堆栈⼀样,也是⼀种运算受限的线性表,其限制是仅允许在表的⼀端进 ⾏插⼊,⽽在表的另⼀端进⾏取出并删除。 简单的说,采⽤该结构的集合,对元素的存取有如下的特点: 先进先出(即,存进去的元素,要在后它前⾯的元素依次取出后,才能取出该元素)。例如, ⼩⽕⻋过⼭洞,⻋头先进去,⻋尾后进去;⻋头先出来,⻋尾后出来。 队列的⼊⼝、出⼝各占⼀侧。例如,下图中的左侧为⼊⼝,右侧为出⼝。
数组数组:Array,
是有序的元素序列,数组是在内存中开辟⼀段连续的空间,并在此空间存放元素。就像 是⼀排出租屋,有100个房间,从001到100每个房间都有固定编号,通过编号就可以快速找到租房 ⼦的⼈。 简单的说,采⽤该结构的集合,对元素的存取有如下的特点: 查找元素快:通过索引,可以快速访问指定位置的元素
特点: 查询块, 增删慢
链表
链表:linked list,由⼀系列结点node(链表中每⼀个元素称为结点)组成,结点可以在运⾏时动态⽣ 成。每个结点包括两个部分:⼀个是存储数据元素的数据域,另⼀个是存储下⼀个结点地址的指针域。我们常说的链表结构有单向链表与双向链表,那么这⾥给⼤家介绍的是单向链表。
简单的说,采⽤该结构的集合,对元素的存取有如下的特点: 多个结点之间,通过地址进⾏连接。例如,多个⼈⼿拉⼿,每个⼈使⽤⾃⼰的右⼿拉住下个⼈ 的左⼿,依次类推,这样多个⼈就连在⼀起了。 查找元素慢:想查找某个元素,需要通过连接的节点,依次向后查找指定元素。 增删元素快:只需要修改链接下⼀个元素的地址值即可
public class Test {
public static void main(String[] args) {
Collection<Integer> list = new ArrayList<>();
list.add(111);
list.add(222);
list.add(333);
Iterator<Integer> iterator = list.iterator();
while (iterator.hasNext()){
Integer num = iterator.next();
System.out.print(num + "\t");
}
for (int i = 0; i < list.size(); i++) {
}
for(Integer num: list){
System.out.print(num + "\t");
}
}
}
使用链表实现栈
上节课
使用链表实现队列
package com.qcx.algo.day10;
public class LinkedListQueue<E> implements Queue<E>{
private class Node{
public E e;
public Node next;
public Node(E e, Node next) {
this.e = e;
this.next = next;
}
public Node(E e) {
this(e, null);
}
public Node() {
this(null, null);
}
@Override
public String toString() {
return e.toString();
}
}
private Node head, tail;
private int size;
public LinkedListQueue(){
head = null;
tail = null;
size = 0;
}
@Override
public int getSize() {
return size;
}
@Override
public boolean isEmpty() {
return size==0;
}
@Override
public void enqueue(E e) {
if (tail == null){
tail = new Node(e);
head = tail;
}else{
tail.next = new Node(e);
tail = tail.next;
}
size++;
}
@Override
public E dequeue() {
if (isEmpty())
throw new IllegalArgumentException("出队元素为空");
Node retNode = head;
head = head.next;
retNode.next = null;
if (head == null)
tail = null;
size --;
return retNode.e;
}
@Override
public E getFront() {
if (isEmpty())
throw new IllegalArgumentException("出队元素为空");
return head.e;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("Queue Front");
Node cur = head;
while (cur !=null){
sb.append(cur + "->");
cur = cur.next;
}
sb.append("Null tail");
return sb.toString();
}
public static void main(String[] args) {
LinkedListQueue<Integer> queue = new LinkedListQueue<>();
for (int i = 0; i < 10; i++) {
queue.enqueue(i);
System.out.println(queue);
if(i%3==2){
queue.dequeue();
System.out.println(queue);
}
}
}
}
链表复杂度分析
添加 O(n)
删除 O(n)
修改O(n)
查询O(n)
但是只对链表的表头进行(增/删/查)操作是Q(1)
package com.qcx.algo.day10;
import java.util.ArrayList;
import java.util.LinkedList;
public class Main {
public static void main(String[] args) {
Array<Integer> array = new Array<>();
LinkedList<Integer> list = new LinkedList<>();
// ArrayList<Integer> array = new ArrayList<>();
// LinkedList<Integer> list = new LinkedList<>();
int n = 10000000;
System.out.println("n = " + n);
long startTime = System.nanoTime();
for (int i = 0; i < n; i++) {
array.addFirst(i);
}
long endTime = System.nanoTime();
double time = (endTime-startTime)/1000000000.0;
System.out.println("Array time = " + time + " s");
startTime = System.nanoTime();
for (int i = 0; i < n; i++) {
list.addFirst(i);
}
endTime = System.nanoTime();
time = (endTime-startTime)/1000000000.0;
System.out.println("LinkedList time = " + time + " s");
}
}
递归
package com.qcx.algo.day10;
public class Test1 {
public static void main(String[] args) {
// 递归方法 方法自己会调用自己
System.out.println(fun1(5));
System.out.println(fun1(100));
System.out.println(fun2(30));
System.out.println(fun2(3));
}
// 1~ 100 累加和
public static int fun1(int n){
if (n == 1)
return 1;
return fun1(n-1) + n;
}
// 累积
public static int fun2(int n){
if (n == 1)
return 1;
return fun2(n-1) *n;
}
// 1, 1, 2, 3, 5, 8
// [1, 2, 3, 4, 5] 求数组的和
}
```