https://juejin.im/post/5c355875518825262058198b
八大排序算法
冒泡排序
public class BubbleSort {
// 冒泡排序,a是数组,n表示数组大小
public static void bubbleSort(int[] a, int n) {
if (n <= 1) return;
for (int i = 0; i < n; ++i) {
// 提前退出标志位
boolean flag = false;
for (int j = 0; j < n - i - 1; ++j) {
if (a[j] > a[j+1]) { // 交换
int tmp = a[j];
a[j] = a[j+1];
a[j+1] = tmp;
// 此次冒泡有数据交换
flag = true;
}
}
if (!flag) break; // 没有数据交换,提前退出
}
}
}
复制代码
选择排序
public class SelectionSort {
// 选择排序,a表示数组,n表示数组大小
public static void selectionSort(int[] a, int n) {
if (n <= 1) return;
for (int i = 0; i < n - 1; ++i) {
// 查找最小值
int minIndex = i;
for (int j = i + 1; j < n; ++j) {
if (a[j] < a[minIndex]) {
minIndex = j;
}
}
// 交换
int tmp = a[i];
a[i] = a[minIndex];
a[minIndex] = tmp;
}
}
}
复制代码
插入排序、希尔排序
public class InsertionSortAdd {
public static void main(String[] args) {
int[] array = new int[]{4, 6, 5, 3, 7, 1, 2};
// int[] array = Arrays.copyOf(data, data.length);
// insertSort(array);
shellSort(array, 7,2);
shellSort(array, 7,1);
// insertSort(Arrays.copyOf(data, data.length));
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
}
//插入排序
public static void insertSort(int[] array, int n) {
if (n <= 1) return;
for (int i = 0; i < n; i++) {
int j = i;
int target = array[j];
while (j > 0 && target < array[j - 1]) {
array[j] = array[j - 1];
j--;
}
array[j] = target;
}
}
//shell排序
public static void shellSort(int[] array, int n, int step) {
if (n <= 1)return;
for (int k = 0; k < step; k++) {
for (int i = k + step; i < n; i = i + step) {
int j = i;
int target = array[j];
while (j > step -1 && target < array[j - step]) {
array[j] = array[j - step];
j = j - step;
}
array[j] = target;
}
}
}
}
复制代码
归并排序
public class MergeSort {
// 归并排序算法, a是数组,n表示数组大小
public static void mergeSort(int[] a, int n) {
mergeSortInternally(a, 0, n-1);
}
// 递归调用函数
private static void mergeSortInternally(int[] a, int p, int r) {
// 递归终止条件
if (p >= r) return;
// 取p到r之间的中间位置q,防止(p+r)的和超过int类型最大值
int q = p + (r - p)/2;
// 分治递归
mergeSortInternally(a, p, q);
mergeSortInternally(a, q+1, r);
// 将A[p...q]和A[q+1...r]合并为A[p...r]
merge(a, p, q, r);
}
private static void merge(int[] a, int p, int q, int r) {
int i = p;
int j = q+1;
int k = 0; // 初始化变量i, j, k
int[] tmp = new int[r-p+1]; // 申请一个大小跟a[p...r]一样的临时数组
while (i<=q && j<=r) {
if (a[i] <= a[j]) {
tmp[k++] = a[i++]; // i++等于i:=i+1
} else {
tmp[k++] = a[j++];
}
}
// 判断哪个子数组中有剩余的数据
int start = i;
int end = q;
if (j <= r) {
start = j;
end = r;
}
// 将剩余的数据拷贝到临时数组tmp
while (start <= end) {
tmp[k++] = a[start++];
}
// 将tmp中的数组拷贝回a[p...r]
for (i = 0; i <= r-p; ++i) {
a[p+i] = tmp[i];
}
}
}
复制代码
快速排序、找出第K大的值
public class QuickSort {
// 快速排序,a是数组,n表示数组的大小
public static void quickSort(int[] a, int n) {
quickSortInternally(a, 0, n-1);
}
// 快速排序递归函数,p,r为下标
private static void quickSortInternally(int[] a, int p, int r) {
if (p >= r) return;
int q = partition(a, p, r); // 获取分区点
quickSortInternally(a, p, q-1);
quickSortInternally(a, q+1, r);
}
//找出第K大的值
private static int search(int a[], int i, int j, int k) {
int m = partition(a, i, j);
if (k == m - i + 1) {
return a[m];
} else if (k < m - i + 1) {//前半段
return search(a, i, m - 1, k);
} else {//后半段
return search(a, m + 1, j, k - (m - i + 1));
}
}
private static int partition(int[] a, int p, int r) {
int pivot = a[r];
int i = p;
for(int j = p; j < r; ++j) {
if (a[j] < pivot) {
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
++i;
}
}
int tmp = a[i];
a[i] = a[r];
a[r] = tmp;
System.out.println("i=" + i);
return i;
}
}
复制代码
堆排序
package sort;
public class HeapSort {
//创建大顶堆
void maxHeapify(int array[], int start, int end) {
//父亲节点
int parent = start;
//左孩子节点
int child = parent * 2 + 1;
while (child <= end) {//如果子节点下标在可以调整的范围内就一直调整下去
//如果没有右孩子就不用比,有的话,比较两个儿子,选择最大的出来
if (child + 1 <= end && array[child] < array[child + 1]) {
child++;
}
if (array[parent] > array[child]) {
return;
} else {//父亲比儿子小,就要对整个子树进行调整
int temp = array[child];
array[child] = array[parent];
array[parent] = temp;
//递归下一层
parent = child;
child = child * 2 + 1;
}
}
}
void heapSort(int[] array, int len) {
//建堆, len/2-1最后一个非叶子节点
for (int i = len / 2 - 1; i >= 0; i--) {
maxHeapify(array, i, len - 1);
}
//排序,根节点和最后一个节点交换
//换完以后,取走根,重新建堆
//len-1,最后一个节点
for (int i = len - 1; i > 0; i--) {
int temp = array[0];
array[0] = array[i];
array[i] = temp;
maxHeapify(array, 0, i - 1);
}
}
}
复制代码
计数排序
package sort;
/**
* 计数排序
*
* Author: ZHENG
*/
public class CountingSort {
// 计数排序,a是数组,n是数组大小。假设数组中存储的都是非负整数。
public static void countingSort(int[] a, int n) {
if (n <= 1) return;
// 查找数组中数据的范围
int max = a[0];
for (int i = 1; i < n; ++i) {
if (max < a[i]) {
max = a[i];
}
}
// 申请一个计数数组c,下标大小[0,max]
int[] c = new int[max + 1];
for (int i = 0; i < max + 1; ++i) {
c[i] = 0;
}
// 计算每个元素的个数,放入c中
for (int i = 0; i < n; ++i) {
c[a[i]]++;
}
// 依次累加
for (int i = 1; i < max + 1; ++i) {
c[i] = c[i-1] + c[i];
}
// 临时数组r,存储排序之后的结果
int[] r = new int[n];
// 计算排序的关键步骤了,有点难理解
for (int i = n - 1; i >= 0; --i) {
int index = c[a[i]]-1;
r[index] = a[i];
c[a[i]]--;
}
// 将结果拷贝会a数组
for (int i = 0; i < n; ++i) {
a[i] = r[i];
}
}
}
复制代码
二分查找
public int bsearch(int[] a, int n, int value){
int low = 0;
int high = n - 1;
while(low < high){
int mid = low + (high - low)/2;
if(a[mid] == value){
return mid;
}else if(a[mid] < value){
low = mid + 1;
}else{
high = mid - 1;
}
}
return -1;
}
复制代码
3. 无重复字符的最长子串
public class FindMaxLengthSubString {
/**
* 查找最长不重复子序列
*
* @param s
* @return
*/
public static int lengthOfLongestSubstring(String s) {
int[] freq = new int[256];
int l = 0, r = s.length() - 1;//滑动窗口为s[l...r]
int res = 0;//最大子长度
while (l < s.length()) {
if (r + 1 < s.length() && freq[s.indexOf(r + 1)] == 0) {
r++;
freq[r]++;
} else {
freq[s.indexOf(l)]--;
l++;
}
res = Math.max(res, r - l + 1);
}
return res;
}
}
复制代码
链表
package linklist;
/**
* 1) 单链表反转
* 2) 链表中环的检测
* 3) 两个有序的链表合并
* 4) 删除链表倒数第n个结点
* 5) 求链表的中间结点
*
* Author: Zheng
*/
public class LinkedListAlgo {
// 单链表反转
public static Node reverseList(Node list){
Node headNode = null;
Node pCurrentNode = list;
Node preNode = null;
while (pCurrentNode != null){
Node next = pCurrentNode.next;
if (next == null){
headNode = pCurrentNode;
}
pCurrentNode.next = preNode;
preNode = pCurrentNode;
pCurrentNode = next;
}
return headNode;
}
// 检测环
public static boolean checkCircle(Node list) {
if (list == null) return false;
Node fast = list.next;
Node slow = list;
while (fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
if (slow == fast) return true;
}
return false;
}
// 有序链表合并
public static Node mergeSortedLists(Node la, Node lb) {
if (la == null) return lb;
if (lb == null) return la;
Node p = la;
Node q = lb;
Node head;
if (p.data < q.data) {
head = p;
p = p.next;
} else {
head = q;
q = q.next;
}
Node r = head;
while (p != null && q != null) {
if (p.data < q.data) {
r.next = p;
p = p.next;
} else {
r.next = q;
q = q.next;
}
r = r.next;
}
if (p != null) {
r.next = p;
} else {
r.next = q;
}
return head;
}
// 删除倒数第K个结点
public static Node deleteLastKth(Node list, int k) {
Node fast = list;
int i = 1;
while (fast != null && i < k) {
fast = fast.next;
++i;
}
if (fast == null) return list;
Node slow = list;
Node prev = null;
while (fast.next != null) {
fast = fast.next;
prev = slow;
slow = slow.next;
}
if (prev == null) {
list = list.next;
} else {
prev.next = prev.next.next;
}
return list;
}
// 求中间结点
public static Node findMiddleNode(Node list) {
if (list == null) return null;
Node fast = list;
Node slow = list;
while (fast.next != null && fast.next.next != null) {
fast = fast.next.next;
slow = slow.next;
}
return slow;
}
public static void printAll(Node list) {
Node p = list;
while (p != null) {
System.out.print(p.data + " ");
p = p.next;
}
System.out.println();
}
public static Node createNode(int value) {
return new Node(value, null);
}
public static class Node {
private int data;
private Node next;
public Node(int data, Node next) {
this.data = data;
this.next = next;
}
public int getData() {
return data;
}
}
}
复制代码
大整数相加
package interview;
public class BigIntAdd {
public static void main(String[] args) {
String n1 = "12345";
String n2 = "1234567";
System.out.println("result:" + bigIntAdd(n1, n2));
}
public static String bigIntAdd(String n1, String n2) {
StringBuffer result = new StringBuffer();
int len1 = n1.length();
int len2 = n2.length();
boolean overFlow = false;
int overNum = 0;
n1 = new StringBuffer(n1).reverse().toString();
n2 = new StringBuffer(n2).reverse().toString();
int maxLen = len1 > len2 ? len1 : len2;
if (len1 < len2) {
for (int i = len1; i < len2; i++) {
n1 += "0";
}
} else if (len1 > len2) {
for (int i = len2; i < len1; i++) {
n2 += "0";
}
}
//
for (int i = 0; i < maxLen; i++) {
int sum = Integer.parseInt(n1.charAt(i) + "")
+ Integer.parseInt(n2.charAt(i) + "") + overNum;
if (sum >= 10) {
if (i == maxLen - 1) {
overFlow = true;
}
overNum = 1;
result.append(sum - 10);
} else {
overNum = 0;
result.append(sum);
}
}
if (overFlow) {
result.append(overNum);
}
return result.reverse().toString();
}
}