学习数据结构与算法的第一天
文章目录
- 前言
- 第一部分 语言基础
- 基础
- 数组
- 数组的定义
- 数组的声明
- 初始化
- 动态:`int[] arr = new int[5];`
- 遍历数组
- java.util.Arrays类
- List(链表)
- List集合实例化
- 步骤:
- 常用方法
- List集合特点
- 排序
- 数组排序
- 集合排序
- Set集合(集合)
- Set的定义
- 特点:
- HashSet类
- 定义:
- 常用方法
- Map(键值对集合)
- Map集合实例化
- 步骤
- 特点:
- 常用方法
- Stack(栈)
- Stack的实例化
- 步骤:
- 特点:
- 常用方法
- Queue(队列)
- 队列的实例化
- 步骤:
- 特点:
- 常用方法
- 例题
- 数位排序
- 顺子日期
- 小明和完美序列
- 总结
前言
概述:
今天从恩师那里受赠一本C语言版本的数据结构,
万分感动,在此立誓,誓要学好数据结构,掌握好算法,争取做出一番成就,绝不辜负恩师的期望。
以下是本篇文章正文内容
第一部分 语言基础
基础
数组
数组的定义
用来存储固定大小的同类型元素
特点:
1.本身就是引用数据类型,但数组中的元素可以是任意数据类型
2.数组会在内部开辟一整块连续的空间,占据的大小取决于数组的长度和数组中的元素类型
3.数组中的元素在内存了是依次紧密连续的
4.数组一旦初始化完成,那么数组的长度就不能修改
5.可以直接通过下标的方式调用指定位置的元素-数组名中引用的是这块连续空间的首地址
6.数组的索引是从0开始的
数组的声明
一维数组 int[] arr; 二维数组 int[][] arr;
初始化
静态:int[] arr = new int[]{1,2,3,4,5,6};
动态:int[] arr = new int[5];
遍历数组
一维数组 for循环for(int i = 0; i < arr.length; i++) 或 for(int k : arr)
二维数组 两层for循环
java.util.Arrays类
可以方便操作数组,提供的所有方法都是静态的
Arrays.fill对数组进行赋值 Arrays.sort对数组进行排序(默认升序)
List(链表)
List集合实例化
步骤:
1.导入java.util包
2.通过ArrayList类创造一个List对象
3.格式:List list = new List<>();
常用方法
ArrayList是一个可以动态修改的数组,于普通数组的区别是没有固定大小的限制,我们可以添加或删除元素
1.add(Object element): 像列表末尾添加指定元素
2.size(): 返回列表中的元素个数
3.get(int index): 返回列表中指定位置的元素,index从0开始
4.isEmpty(): 判断列表是否为空,为空返回true,负否则返回false
5.contains(): 如果列表包含指定元素,则返回true
6.remove(int index): 移除列表中指定位置的元素,并返回被删除的元素
List集合特点
1.元素的添加顺序于取出顺序是一致的,并且可以重复
2.每个元素都有其对应的舒徐索引(从0开始)
3.可以根据喜好存取容器中的元素
排序
数组排序
Arrays.sort(int[] arr)对数组arr进行排序(默认升序)
Integer[] arr = {1,2,3,4,5,1,5,6,2};
//升序
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
//降序
Arrays.sort(arr, new Comparator<Integer>(){
@Override
public int compare(Integer o1, Integer o2){
return o2 - o1;
}
});
System.out.println(Arrays.toString(arr));
//第二种模式,上面的简写
Integer[] arr = {1,2,3,4,5,1,5,6,2};
//升序
Arrays.sort(arr, (a,b)->a-b);
System.out.println(Arrays.toString(arr));
//降序
Arrays.sort(arr, (a,b)->b-a);
System.out.println(Arrays.toString(arr));
集合排序
Collections.sort(List<> arr)
ArrayList<Integer> list = new ArrayList<>();
list.add(1);
list.add(4);
list.add(3);
list.add(4);
list.add(5);
list.add(4);
//升序
Collections.sort(list);
System.out.println(list);
//降序
Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});
System.out.println(list);
//第二种模式,上面的简写
ArrayList<Integer> list = new ArrayList<>();
list.add(1);
list.add(4);
list.add(3);
list.add(4);
list.add(5);
list.add(4);
//升序
Collections.sort(list, (a,b)->a-b);
System.out.println(list);
//降序
Collections.sort(list, (a,b)->b-a);
System.out.println(list);
Set集合(集合)
Set的定义
是一个不允许出现重复元素,并且无序的集合,主要有HashSet类
在判断重复元素的时候,Set集合会调用hashCode()和equal()的方法来实现
注重独一无二的性质,该体系集合可以知道某物是否已经存在于集合中,不会存储重复的元素
用于存储无序的元素,值不能重复
特点:
1.可以用来去重
2.元素无序
HashSet类
定义:
Set<Integer> set = new HashSet<>();
Set<String> set = new HashSet<>();
1.实现了Set接口
2.无序,疾病和记录插入地方顺序
3.不允许有重复元素的集合
4.谓语java.util包里面,需要引入
常用方法
Set<Integer> set = new HashSet<>();
boolean a = set.add(1);
boolean b = set.add(1);
System.out.println(a);//true
System.out.println(b);//false
Set<Integer> set = new HashSet<>();
boolean a = set.add(1);
boolean b = set.add(1);
System.out.println(set.size());//1
boolean c = set.add(2);
System.out.println(set.size());//2
System.out.println(a+" "+b); //true false
System.out.println(a+" "+c); //true true
Set<Integer> set = new HashSet<>();
set.add(1);
boolean a = set.remove(1);
boolean b = set.remove(5);
System.out.println(a+" "+b);//true false
Set<Integer> set = new HashSet<>();
set.add(1);
boolean a = set.contains(1);
boolean b = set.contains(5);
System.out.println(a+" "+b);//true false
Set<Integer> set = new HashSet<>();
set.add(1);
set.add(2);
set.add(3);
System.out.println(set.size());//3
set.clear();
System.out.println(set.size());//0
Map(键值对集合)
Map集合实例化
步骤
1.导包,导入java.util.Map
2.通过HashMap实现类创造对象
3.语法格式:
Map<引用数据类型,引用数据类型> map = new HashMap<>();
特点:
1.HashMap是一个散列表,它存储的内容师键值对(key-value)映射。
2.HashMap实现了Map接口,根据键的HashMap值存储数据,具有很快的访问速度,最多允许一条记录的键为null,不支持线程同步
3.HashMap是无序的,既不会记录插入的顺序
常用方法
HashMap<Integer,Integer> map = new HashMap<>();
map.put(key, value);//在 Map 中添加一对键值对,如果 key 已存在则会覆盖原有的 value 值
map.get(key);//根据 key 获取 value,如果 key 不存在则返回 null。
int size = map.size();//获取 Map 的大小(即键值对的数量)
Set<map.Entry<String, Integer>> entrySet = map.entrySet();
//作用是为了遍历Map集合
//返回 Map 中所有键值对组成的 Set 集合,其中每个元素都是一个 Map.Entry 对象,包含 key 和 value 两部分。
// 遍历 entrySet,获取每个键值对并处理
for (Map.Entry<String, Integer> entry : entrySet) {
String key = entry.getKey();
Integer value = entry.getValue();
// 处理键值对
System.out.println("Key: " + key + ", Value: " + value);
}
int value = map.getOrDefault(key,defaultVaule);
//如果存在第一个参数(key)对应的Value,那么九江Value赋值给value,反之将defaulValue赋给value
Stack(栈)
Stack的实例化
步骤:
1.导包,导入java.util.Stack
2.实例化对象,格式:
Stack stack = new Stack<>();
特点:
先进后出
常用方法
Stack<Object> stack = new Stack<>();
stack.push(Object element); // 向栈中压入元素
stack.pop(); // 从栈中弹出(移除)并返回栈顶元素
stack.peek(); // 返回栈顶元素,但不弹出(移除)
stack.isEmpty(); // 检查栈是否为空
int element = stack.get(index); // 获取索引为1的元素,即栈顶元素下面的元素
element = stack.elementAt(index); // 获取索引为2的元素,即栈顶元素下面的元素又下面的元素
int size = stack.size(); // 获取栈中元素的个数
// 在栈中查找元素o的位置(从栈顶往下数),如果,没有这个元素,则返回1
int position = stack.search(Object o);
Queue(队列)
队列的实例化
步骤:
1.导包,导入java.util.Queue;
2.通过LinkList类创造对象
Queue queue = new LinkedList<>();
特点:
先进先出
常用方法
queue.add(Objects element);//添加元素
queue.poll(); //取出元素
queue.peek(); //获取头部元素,不取出
queue.isEmpty(); //判断队列是否为空
//将元素添加到队列的末尾,并返回 true。如果队列已满,该方法会立即返回 false。
queue.offer(Objects o);
//移除并返回队列的头部元素。如果队列为空,该方法会抛出 NoSuchElementException 异常
queue.remove();
//element():返回队列的头部元素,但不会将其移除。如果队列为空,该方法会抛出 NoSuchElementException 异常。
queue.element();
//移除队列中的所有元素。
queue.clear();
例题
数位排序
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
int[][] arr = new int[n][2];
for (int i = 0; i < n; i++){
arr[i][0] = i+1;
String s = arr[i][0]+"";
for (int k = 0; k < s.length(); k++){
arr[i][1] += s.charAt(k) - '0';
}
}
Arrays.sort(arr, (o1,o2)->(o1[1] == o2[1]?o1[0]-o2[0]:o1[1]-o2[1]));
System.out.println(arr[m-1][0]);
}
}
顺子日期
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
HashMap<Integer,Integer> map = new HashMap<>();
map.put(1,31);
map.put(2,29);
map.put(3,31);
map.put(4,30);
map.put(5,31);
map.put(6,30);
map.put(7,31);
map.put(8,31);
map.put(9,30);
map.put(10,31);
map.put(11,30);
map.put(12,31);
int count = 0;
for (int i = 1; i <= 12; i++){
for (int k = 1; k <= map.get(i); k++){
String month = String.format("%02d", i);
String day = String.format("%02d", k);
String str = "2022"+month+day;
if (str.indexOf("012")!=-1||str.indexOf("123")!=-1||str.indexOf("234")!=-1||str.indexOf("345")!=-1||str.indexOf("456")!=-1||str.indexOf("567")!=-1||str.indexOf("678")!=-1||str.indexOf("789")!=-1){
count++;
}
}
}
System.out.println(count);
}
}
小明和完美序列
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] arr = new int[n];
for (int i = 0; i < n; i++)
arr[i] = sc.nextInt();
Arrays.sort(arr);
int ans = 1; // 连续的长度
int count = 0;//要删除的个数
HashMap<Integer, Integer> map = new HashMap<>();
int temp = arr[0];
for (int i = 1; i < n; i++){
int m = arr[i];
if (m == temp){
ans++;
}else {
map.put(temp, ans);
ans = 1;
}
temp = m;
}
map.put(temp, ans);
ans = 1;
for (Map.Entry<Integer, Integer> entry : map.entrySet()){
Integer k = entry.getKey();//数
Integer v = entry.getValue();//长度
if (k > v) count += v;
else if(k < v) count += v - k;
}
System.out.println(count);
}
}
总结
这里对文章进行总结:
以上就是今天要讲的内容,本文仅仅是万里长征的第一步,以后面临的困难还有很多,希望我能坚持下来,温故而知新,克服万难排除艰险,去争取胜利!
与诸君共勉,请各位监督。