一.算法
1.排序算法
A.选择排序
- 选择排序就是平常我们生活中最常用的排序算法
- 选定一个数和数组中其他所以数比较
public static void sortBySelect(int [] arr){
if(arr==null||arr.length==0){
return;
}
for(int i=0;i<arr.length-1;i++){
int min = i;
for(int j=i+1;j<arr.length;j++){
if(arr[j]<arr[min]){
min=j;
}
}
swap(arr,i,min);
}
}
public static void swap(int [] arr,int i,int j){
int temp = arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
B.冒泡排序
- 这里我们以从左到右升序为主
- 先相邻两个比较,若前面的比后面的大交换两个数…经过一轮循环,数组中最大的数就在最后的位置
public static void sortByBubbling(int []nums){
if(nums==null||nums.length==0){
return;
}
for(int i=0;i<nums.length-1;i++){
boolean flag = false;
for(int j=0;j<nums.length-i-1;j++){
if(nums[j]>nums[j+1]){
flag=true;
swap(nums,j,j+1);
}
}
if(!flag){
break;
}
}
for(int i=0;i<nums.length;i++){
System.out.println(nums[i]);
}
}
C.快速排序
public static void sortByQuick(int [] nums,int i,int j){
if(nums==null||nums.length==0){
return;
}
if(i<j){
int index = getIndex(nums,i,j);
sortByQuick(nums,i,index-1);
sortByQuick(nums,index+1,j);
}
}
public static int getIndex(int []nums,int i,int j){
int base = nums[i];
while(i<j){
while(i<j&&base<=nums[j]){
j--;
}
nums[i]=nums[j];
while(i<j&&base>=nums[i]){
i++;
}
nums[j]=nums[i];
}
nums[i]=base;
return i;
}
4.随机排序
public static void randomSort(int [] nums,int count){
for(int i=0;i<count;i++){
int index1=new Random().nextInt(nums.length);
int index2=new Random().nextInt(nums.length);
if(index1==index2){
continue;
}
int temp = nums[index1];
nums[index1]=nums[index2];
nums[index2]=temp;
}
}
2.素数问题
1.素数判断
public static boolean isPrime(int num){
if(num<2){
return false;
}
for(int i=2;i<=Math.sqrt(num);i++){
if(num%i==0){
return false;
}
}
return true;
}
2.线性筛
public static List<Integer> Prime(int max){
List<Integer> result = new ArrayList<>();
boolean [] flags = new boolean[max+1];
for(int i=0;i<=max;i++){
flags[i]=true;
}
flags[0]=flags[1]=false;
for(int i=2;i<=max;i++){
if(flags[i]){
for(int j=i*2;j<=max;j+=i){
flags[j]=false;
}
}
}
for(int i=2;i<=max;i++){
if(flags[i]){
result.add(i);
}
}
return result;
}
3.判断一个数是否为2的次幂
- 2的次幂转换成二进制哟弍特点:二进制只有一个1,后面跟了n个0
- 如果将这个数减去1后发现,仅有的那个1会变为0,而原来的那n个0会变为1
- 因此可以用与运算来判断
- 还有种傻一点的做法,对这个数取余和除运算
public static boolean isSecondPow(int num){
return (num&(num-1))==0;
}
4.年份问题
- 给你xxxx年y月z日星期天,问你13个月m天后是星期几,具体是什么时间
- 这其中夹杂了对闰年的考察
public static void yearByTime(int year,int month,int date,int gomonth,int godate){
int [] nowyearinfo = new int[2];
calDate(year,month,date,nowyearinfo);
int futureyear = year+(month+gomonth)/12;
int futuremonth = (month+gomonth)%12;
int futuredate = 0;
int [] months={31,28,31,30,31,30,31,31,30,31,30,31};
if((futureyear%4==0&&futureyear%100!=0)||(futureyear%400==0)) {
months[1]++;
}
futuredate = date+godate;
for(int i=futuremonth-1;futuredate>months[i];i++){
futuremonth++;
futuredate-=months[i];
}
System.out.println("未来年份为:"+futureyear+"年"+futuremonth+"月"+futuredate+"日");
}
private static void calDate(int year, int month, int date,int [] yearinfo) {
int [] months={31,28,31,30,31,30,31,31,30,31,30,31};
yearinfo[0] = date;
if((year%4==0&&year%100!=0)||(year%400==0)) {
months[1]++;
yearinfo[1]=366;
}
else{
yearinfo[1]=365;
}
for(int i=0;i<month-1;i++){
yearinfo[0]+=months[i];
}
}
5.二分法
private static int binarysearch(int [] nums,int key){
int left=0;
int right=nums.length-1;
while(left<=right){
int mid = (left+right)/2;
if(nums[mid]==key){
return mid;
}
else if(key>nums[mid]){
left=mid+1;
}else{
right=mid-1;
}
}
return -1;
}
6.字符串操作
1.字符串翻转
public static String reverse(String str){
if(str==null||str.length()<=1){
return str;
}
char [] array = str.toCharArray();
String newstr = "";
for(int i=array.length-1;i>=0;i--){
newstr+=array[i];
}
return newstr;
}
7.最大公约数和最小公倍数
public static int divisor(int a,int b){
if(a<b){
int temp = a;
a=b;
b=temp;
}
while(b!=0){
int temp = a%b;
a=b;
b=temp;
}
return a;
}
public static int multiple(int a,int b){
int temp = divisor(a,b);
return ((a*b)/temp);
}
二.数据结构
1.树
- 完美二叉树:所有非叶子结点,都有两个子节点,且每一层都被填满了
- (完)满二叉树:所有非叶子结点,都有两个子节点
- 完全二叉树:除了最后一层外的每一层必须被填满,且最后一层严格左对齐
- 平衡二叉树:左右子树深度绝对值相差小于2
A.二叉树
a.二叉树的遍历
public void firstOrder(TreeNode root){
if(root==null){
return;
}
System.out.println(root.data);
if(root.leftChild!=null){
firstOrder(root.leftChild);
}
if(root.rightChild!=null){
firstOrder(root.rightChild);
}
}
public void midOrder(TreeNode root){
if(root==null){
return;
}
if(root.leftChild!=null){
midOrder(root.leftChild);
}
System.out.println(root.data);
if(root.rightChild!=null){
midOrder(root.rightChild);
}
}
public void postOrder(TreeNode root){
if(root==null){
return;
}
if(root.leftChild!=null){
postOrder(root.leftChild);
}
if(root.rightChild!=null){
postOrder(root.rightChild);
}
System.out.println(root.data);
}
b.二叉树的最大深度
public int maxDepth(TreeNode root){
if(root==null){
return 0;
}
else{
return 1+Math.max(maxDepth(root.leftChild),maxDepth(root.rightChild));
}
}
c.二叉树的最小深度
public int minDepth(TreeNode root) {
if(root==null)
return 0;
else if(root.leftChild==null && root.rightChild==null)
return 1;
else if(root.leftChild!=null && root.rightChild!=null)
return 1+Math.min(minDepth(root.leftChild), minDepth(root.rightChild));
else {
if (root.leftChild != null)
return 1 + minDepth(root.leftChild);
else
return 1 + minDepth(root.rightChild);
}
}
d.查找某个数
public TreeNode find(TreeNode root,int key) {
TreeNode current = root;
while(current!=null){
if(current.data>key){
current=current.leftChild;
}else if(current.data<key){
current=current.rightChild;
}else{
return current;
}
}
return null;
}
e.插入
public void insert(TreeNode root,int val){
TreeNode newNode = new TreeNode(val);
if(root==null){
root = newNode;
}
else{
TreeNode current = root;
TreeNode parent;
while(current!=null){
parent = current;
if(current.data>val){
current=current.leftChild;
if(current==null){
parent.leftChild =newNode;
break;
}
}else{
current=current.rightChild;
if(current==null){
parent.rightChild=newNode;
break;
}
}
}
}
}
B.红黑树
红黑树基本概念