31-Java数据结构与算法实战-qianfeng-笔记
文章目录
一、数组(最大值 最小值算法)
①:二维数组
二维数组示例:JAVA中没有真正的多维数组,多维数组的表示方式是数组中的元素还是数组。
一起来参加屌丝程序员大赛吧,有3个班级各3名学员参赛,
记录每个学员的成绩,并计算每个班的平均分。
/**
二维数组示例:JAVA中没有真正的多维数组,多维数组的表示方式是数组中的元素还是数组。
一起来参加屌丝程序员大赛吧,有3个班级各3名学员参赛,
记录每个学员的成绩,并计算每个班的平均分。
*/
public class ArrayDemo {
public static void main(String[] args) {
int[][] scores = {{78,98,88},{87,96,85},{67,78,89}};
int classLen = scores.length;
for (int i = 0; i < classLen; i++) {
int classNum = scores[i].length;
int sum = 0;
for (int j = 0; j < classNum; j++) {
sum += scores[i][j];
}
int avg = sum / classNum;
System.out.println("第"+ (i+1) +"个班级平均分为:"+ avg);
}
}
}
②:数列中最大值最小值算法
/**
* 求最大值和最小值
*/
public class MaxAndMin {
public static void main(String[] args) {
int[] num = {78,26,656,123,7489,21,3};
System.out.println("最大值为:" + max(num));
System.out.println("最小值为:" + min(num));
}
// 求数列中的最大值
public static int max(int[] num){
int max = num[0];
for (int i = 0; i < num.length; i++) {
if (num[i] > max){
max = num[i] + max;
num[i] = max - num[i];
max = max - num[i];
}
}
return max;
}
// 求数列中的最小值
public static int min(int[] num){
int min = num[0];
for (int i = 0; i < num.length; i++) {
if (num[i] < min){
min = num[i] + min;
num[i] = min - num[i];
min = min - num[i];
}
}
return min;
}
}
二、排序算法
①:冒泡排序算法
/**
冒泡排序算法
冒泡排序算法的运作如下:(从后住前)
比较相邻的元素。如果第一个比第二个大,就交换他们两个。
对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数
针对所有的元素重复以上的步聚,除了最后一个。
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
相同元素的前后顺序并没有改变,所以冒泡排序是一种稳定排序算法。
*/
public class Sort {
public static void main(String[] args) {
int[] nums = {34,4,67,56,56,456,89};
// 冒泡排序
for (int i = 0; i < nums.length - 1; i++) { // 控制轮数
for (int j = 0; j < nums.length -1 - i; j++) { // 比较次数
if (nums[j] > nums[j+1]){
nums[j] = nums[j] + nums[j+1];
nums[j+1] = nums[j] - nums[j+1];
nums[j] = nums[j] - nums[j+1];
}
}
}
System.out.println(Arrays.toString(nums));
}
}
②:选择排序算法
/**
选择排序算法
每一趟从待排序的数据元素中选出最小(或最大)的一个元素,
顺序放在己排好序的数列的最后,直到全部待排序的数据元素排完。
选择排序是不稳定的排序方法。
*/
public static void sortDemo2(){
int[] nums = {34,4,67,56,56,456,89};
int minIndex = 0; // 用于记录每次比较的最小值下标
for (int i = 0; i < nums.length - 1; i++) {
minIndex = i; // 每轮假设一个最小值下标
for (int j = i + 1; j < nums.length; j++) {
if (nums[minIndex] > nums[j]){
minIndex = j;
}
}
// 判断需要交换的下标是否为自己
if (minIndex != i){
nums[i] = nums[i] + nums[minIndex];
nums[minIndex] = nums[i] - nums[minIndex];
nums[i] = nums[i] - nums[minIndex];
}
}
System.out.println(Arrays.toString(nums));
}
③:插入排序算法
/**
直接插入排序算法
(从后向前找到合适位置后插汀)
基本思想:每步将一个待排序的记录,按其顺序码大小插入到前面已经排序的字序列的合适位置(从后向前找到
合适位置后),直到全部插入排序完为止。
*/
public static void sortDemo3(){
int[] nums = {34,4,67,56,56,456,89};
for (int i = 1; i < nums.length; i++) {
int temp = nums[i];
int j = 0;
for (j = i -1; j>=0; j--){
if (nums[j] > temp){
nums[j+1] = nums[j];
}else {
break;
}
}
if (nums[j+1]!=temp){
nums[j+1] = temp;
}
}
System.out.println(Arrays.toString(nums));
}
三、二分查找算法
/**
二分法查找(折半查找):前提是在已经好序的数组中,通过将待查找的元素与中间索引值对应的元素进行比
较,若大于中间素引值对应的元素,去右半部分
查找,否则,去左半部分查找。依此类推。直到找到为止;找不到返回一个负数。
* @param nums
* @param key
* @return
*/
public static int searchDemo1(int[] nums, int key){
int start = 0;
int end = nums.length - 1;
while (start <= end){
int middle = (start + end) / 2;
if (nums[middle] < key){
start = middle;
}else if (nums[middle] > key){
end = middle;
}else {
return middle;
}
}
return -1;
}
public static void main(String[] args) {
int[] nums = {34,4,67,56,56,456,89};
// 1.调用刚刚写的排序算法先进行排序
int[] nums2 = sortDemo2(nums);
System.out.println(Arrays.toString(nums2));
// 2.调用二分查找算法
int i = searchDemo1(nums2, 89);
System.out.println(i);
}
四、随机生成多个不重复值算法
①:双色球模拟
import org.junit.jupiter.api.Test;
import java.util.Arrays;
import java.util.Random;
import java.util.Scanner;
/**
模拟双色球综合案例
1、用户选择是机选还是手选号码
2、接收用户选号(6红,1蓝
3、生成系统号码(6红,1蓝
4、比较系统号码和用户号码,记录个数
5、验证是否中奖
6、系统号码排序
7、公布结果
*/
public class RandomDemo {
private static Scanner input = new Scanner(System.in);
private static Random random = new Random();
public static void main(String[] args) {
// 定义相关的变量
int[] userRedBall = new int[6]; // 用户选择的红球号码
int[] sysRedBall = new int[6]; // 系统生成的红球号码
int userBlueBall = 0; // 用户选择的篮球
int sysBlueBall = 0; // 系统生成的篮球
int redCount = 0; //记录用户选择正确的红球数
int blueCount = 0; // 记录用户选择正确的篮球数
// 1.准备33个红球号码
int[] redBall = new int[33]; // 用于存储1-33的红球号码
for (int i = 0; i < redBall.length; i++) {
redBall[i] = i + 1;
}
// 2. 游戏开始,系统提示
System.out.println("双色球游戏开始,good luck!");
System.out.println("请问您是要机选还是手选号码(1:机选,2:手选)");
boolean flag = true;
while (flag) {
int isAuto = input.nextInt();
switch (isAuto) {
case 1:
// 机选
computerSelection(redBall, userRedBall); // 机选红球
userBlueBall = random.nextInt(16) + 1; // 机选篮球
flag = false;
break;
case 2:
// 手选
System.out.println("********您需要选择6个红球号码********");
for (int i = 0; i < userRedBall.length; i++) {
System.out.println("请在(1-33)之间选择第" + (i + 1) + "个红球号码,不可重复选择!");
userRedBall[i] = input.nextInt();
}
System.out.println("请在(1-16)之间选择第1个蓝球号码!");
userBlueBall = input.nextInt();
flag = false;
break;
default:
System.out.println("您输入的数字有误!请重新输入~");
System.out.println();
System.out.println("请问您是要机选还是手选号码(1:机选,2:手选)");
}
}
// 系统随机生成号码
// 红球
computerSelection(redBall, sysRedBall);
// 篮球
sysBlueBall = random.nextInt(16) + 1;
// 统计结果
// 统计红球
for (int i = 0; i < userRedBall.length; i++) {
for (int j = 0; j < sysRedBall.length - redCount; j++) {
if (userRedBall[i] == sysRedBall[j]) {
int temp = sysRedBall[j];
sysRedBall[j] = sysRedBall[sysRedBall.length - 1 - redCount];
sysRedBall[sysRedBall.length - 1 - redCount] = temp;
redCount++;
break;
}
}
}
// 统计篮球
if (userBlueBall == sysBlueBall) {
blueCount = 1;
}
// 公布系统号码
System.out.println("本期中将红球号码为:");
sort(sysRedBall);
System.out.println(Arrays.toString(sysRedBall));
System.out.println("本期中将蓝球号码为:" + sysBlueBall);
// 公布用户选择的号码
System.out.println("您选择的将红球号码为:");
sort(userRedBall);
System.out.println(Arrays.toString(userRedBall));
System.out.println("您选择的蓝球号码为:" + userBlueBall);
System.out.println("买双色球,造福你我他!谢谢!");
// 验证是否中奖
if (blueCount == 0 && redCount <= 3) {
System.out.println("谢谢惠顾!");
} else if (blueCount == 1 && redCount < 3) {
System.out.println("中了六等奖,5块钱!");
} else if ((blueCount == 1 && redCount == 3) || (blueCount == 0 && redCount == 4)) {
System.out.println("中了五等奖,10块钱!");
} else if ((blueCount == 1 && redCount == 4) || (blueCount == 0 && redCount == 5)) {
System.out.println("中了四等奖,200块钱!");
} else if (blueCount == 1 && redCount == 5) {
System.out.println("中了三等奖,3000块钱!");
} else if (blueCount == 0 && redCount == 6) {
System.out.println("中了二等奖,150W!");
} else if (blueCount == 1 && redCount == 6) {
System.out.println("中了一等奖,500W!");
} else {
System.out.println("系统有误,中将无效!");
}
}
// 选择排序
public static void sort(int[] ball){
int minIndex = 0;
for (int i = 0; i < ball.length - 1; i++) {
minIndex = i;
for (int j = 0; j < ball.length; j++) {
if (ball[minIndex] > ball[j]){
minIndex = j;
}
}
if (minIndex != i){
ball[i] = ball[i] + ball[minIndex];
ball[minIndex] = ball[i] - ball[minIndex];
ball[i] = ball[i] - ball[minIndex];
}
}
}
// 需要随机生成6个1-33之间不重复的数(算法)并存入到userRedBall
public static void computerSelection(int[] redBall, int[] userRedBall){
int index = -1;
for (int i = 0; i < userRedBall.length; i++) {
index = random.nextInt(redBall.length - i);
userRedBall[i] = redBall[index];
int temp = redBall[index];
redBall[index] = redBall[redBall.length - 1 - i];
redBall[redBall.length - 1 - i] = temp;
}
}
}
五、动态数组
①:创建Chicken类
package com.example.d4_ArrayObject;
// 小鸡对象(数据对象)
public class Chicken {
private int id;
private String name;
private int age;
public Chicken() {
}
public Chicken(int id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Chicken{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
②:创建ChickenManager类
package com.example.d4_ArrayObject;
import java.util.Arrays;
// 小鸡管理
public class ChickenManager {
private Chicken[] cs = null;
private int count = 0; //记录当前数组的元素的个数
public ChickenManager(int size){
if (size > 0){
cs = new Chicken[size];
}else {
cs = new Chicken[5];
}
}
// 添加
public void add(Chicken chicken){
if (count < cs.length){
cs[count] = chicken;
count++;
}else{
// 将数组扩充原来的一倍
int newLen = cs.length * 2;
cs = Arrays.copyOf(cs,newLen);
cs[count] = chicken;
}
}
// 删除
public void delete(int id){
for (int i = 0; i <= count; i++) {
if (cs[i].getId() == id) {
// 找到了要删除的对象,把对象之后的对象前移动一位
for (int j = i; j < count - 1; j++) {
cs[j] = cs[j + 1];
}
// 把最后一个对象赋值为空
cs[count - 1] = null;
count--;
break;
}
}
}
// 更新
public void update(Chicken chicken){
Chicken temp = find(chicken.getId());
if (temp != null){
temp.setName(chicken.getName());
temp.setAge(chicken.getAge());
}
}
// 查找
public Chicken find(int id){
for (int i = 0; i <= count; i++) {
if (cs[i].getId() == id){
return cs[i];
}
}
return null;
}
// 输出所有
public void printAll(){
System.out.println(Arrays.toString(cs));
}
// 返回数组的长度
public int ArraySize(){
return cs.length;
}
}
③:Test类
package com.example.d4_ArrayObject;
public class Test {
public static void main(String[] args) {
ChickenManager cm = new ChickenManager(5);
cm.add(new Chicken(1,"小小",10));
cm.add(new Chicken(2,"小二",8));
cm.add(new Chicken(3,"小三",9));
cm.add(new Chicken(4,"小红",3));
cm.add(new Chicken(5,"小黑",2));
cm.add(new Chicken(6,"小黑",5));
System.out.println("数组的长度为:"+ cm.ArraySize());
System.out.println(cm.find(1));
cm.printAll();
cm.update(new Chicken(1,"大大",20));
System.out.println(cm.find(1));
}
}
六、递归算法
package com.example.d4_ArrayObject;
public class Test2 {
public static void main(String[] args) {
int result = jieCheng(5);
System.out.println(result);
}
public static int jieCheng(int num){
if (num == 1)return 1;
return num * jieCheng(num -1);
}
}
七、数据结构之链表
package com.example.d5_linked;
public class Test1 {
public static void main(String[] args) {
NodeManager nm = new NodeManager();
nm.add(5);
nm.add(4);
nm.add(3);
nm.add(2);
nm.add(1);
nm.print();
System.out.println("******************");
nm.insert(0,10);
nm.print();
}
}
class NodeManager{
private Node root;
private int currentIndex;
public void add(int data){
if (root == null){
root = new Node(data);
}else {
root.addNode(data);
}
}
public void del(int data){
if (root.getData() == data){
if (root.next != null){
root = root.next;
}else {
root = null;
}
}else {
root.delNode(data);
}
}
public void print(){
if (root != null){
System.out.print(root.getData() +"-->");
root.printAllNode();
System.out.println();
}
}
public boolean find(int data){
if (root == null)return false;
if (root.getData() == data){
return true;
}else{
return root.findNode(data);
}
}
public boolean update(int oldData, int newData){
if (root == null) return false;
if (root.getData() == oldData){
root.setData(newData);
return true;
}else {
return root.updateNede(oldData,newData);
}
}
public boolean insert(int index, int data){
if (index < 0 )return false;
currentIndex = 0;
if (index == currentIndex){
Node newNode = new Node(data);
newNode.next = root;
root = newNode;
return true;
} else {
return root.insertNode(index, data);
}
}
private class Node{
private int data;
private Node next;
public Node(int data){
this.data =data;
}
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
// 添加节点
public void addNode(int data){
if (this.next == null){
this.next = new Node(data);
}else {
this.next.addNode(data);
}
}
// 删除节点
public void delNode(int data){
if (this.next != null){
if (this.next.getData() == data){
this.next = this.next.next;
}else {
this.next.delNode(data);
}
}
}
// 输出所有节点
public void printAllNode(){
if (this.next != null){
System.out.print(this.next.data + (this.next.next != null ?"-->":""));
this.next.printAllNode();
}
}
// 查找节点是否存在
public boolean findNode(int data){
if (this.next != null){
if (this.next.getData() == data){
return true;
}else {
return this.next.findNode(data);
}
}
return false;
}
// 修改节点
public boolean updateNede(int oldDate, int newDate){
if (this.next != null){
if (this.next.getData() == oldDate){
this.next.setData(newDate);
return true;
}else {
return this.next.updateNede(oldDate, newDate);
}
}
return false;
}
// 插入节点 前插
public boolean insertNode(int index, int data){
currentIndex++;
if (index ==currentIndex){
Node newNode = new Node(data);
newNode.next = this.next;
// this.next = newNode;
return true;
}else {
return this.next.insertNode(index, data);
}
}
}
}
八、数据结构值二叉树实现原理
package com.example.d5_linked;
public class BinaryTree {
private Node root;
// 添加节点
public boolean add(int data){
if (root == null){
root = new Node(data);
return true;
}else {
return root.addNode(data);
}
}
// 输出节点
public void print(){
root.printNode();
}
private class Node{
private int data;
private Node left;
private Node right;
public Node(int data) {
this.data = data;
}
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
public boolean addNode(int data) {
if (this.data > data){
if (this.left == null){
this.left = new Node(data);
return true;
}else {
return this.left.addNode(data);
}
}else {
if (this.right == null){
this.right = new Node(data);
return true;
}else{
return this.right.addNode(data);
}
}
}
// 中序遍历
public void printNode() {
if (this.left != null){
this.left.printNode();
}
System.out.print(this.getData() + (this.right==null&&this.left!=null?"":"-->"));
if (this.right != null){
this.right.printNode();
}
}
}
}
package com.example.d5_linked;
public class BinaryTreeDemo {
public static void main(String[] args) {
BinaryTree bt = new BinaryTree();
bt.add(8);
bt.add(3);
bt.add(10);
bt.add(1);
bt.add(6);
bt.add(14);
bt.add(4);
bt.add(7);
bt.add(13);
bt.print();
}
}
九、ArrayList-与Vector源码分析及比较
十、LinkedList:实现类与源码分析
十一、HashMap源码分析与哈希表实现原理
十二、队列与栈