public class Demo1 {
public static void main(String[] args) {
int[] arr = {4,5,5,6,8,9,3,2,1,7};
/*
* 选择排序
* */
printArray(arr);
selectSort(arr);
printArray(arr);
/*
* 冒泡排序
* */
printArray(arr);
bubbleSort(arr);
printArray(arr);
/*
* 插入排序
* */
printArray(arr);
insertSort1(arr);
insertSort2(arr);
printArray(arr);
}
//打印数组
public static void printArray(int[] arr) {
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
//交换元素
private static void swap(int[] arr, int i, int j) {
int tmp = arr[j];
arr[j] = arr[i];
arr[i] = tmp;
}
//选择排序
public static void selectSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
int N = arr.length;
for (int i = 0; i < N; i++) {
int minValueIndex = i;
for (int j = i + 1; j < N; j++) {
minValueIndex = arr[j] < arr[minValueIndex] ? j : minValueIndex;
}
swap(arr, i, minValueIndex);
}
}
//冒泡排序
public static void bubbleSort(int[] arr){
if(arr==null || arr.length<2){
return;
}
int N= arr.length;
for (int end = N-1;end>=0;end--){
for (int second =1;second<=end;second++){
if(arr[second-1]>arr[second]){
swap(arr,second-1,second);
}
}
}
}
//插入排序(基础版)
public static void insertSort1(int[] arr){
if(arr==null || arr.length<2){
return;
}
int N = arr.length;
for (int end = 1;end<N;end++){
int newNumIndex = end;
while (newNumIndex - 1 >= 0 && arr[newNumIndex - 1] > arr[newNumIndex]) {
swap(arr,newNumIndex-1,newNumIndex);
newNumIndex--;
}
}
}
//插入排序(优化版)
public static void insertSort2(int[] arr){
if(arr==null || arr.length<2){
return;
}
int N = arr.length;
for (int end = 1;end<N;end++){
for (int pre = end -1;pre >= 0 && arr[pre] > arr[pre+1];pre--){
swap(arr,pre,pre+1);
}
}
}
}
2.对数器
public class Demo3 {
public static void main(String[] args) {
/*
* 对数器:校验当前的排序算法是否正确
* */
int maxLen = 5;
int maxValue = 1000;
int testTime = 10000;
for (int i = 0; i < testTime; i++) {
int[] arr1 = lenRandomValueRandom(maxLen,maxValue);
int[] tmp = copyArray(arr1);
selectSort(arr1);
if(!isSorted(arr1)){
for (int j = 0; j < tmp.length; j++) {
System.out.print(tmp[j]+" ");
}
System.out.println();
System.out.println("选择排序错了");
}
}
}
//随机生成一个长度maxLen以内、数字maxValue以内的数组
public static int[] lenRandomValueRandom(int maxLen,int maxValue){
int len = (int)(Math.random()*maxLen);
int[] ans = new int[len];
for (int i = 0; i < ans.length; i++) {
ans[i] = (int)(Math.random()*maxValue);
}
return ans;
}
//拷贝一个新数组
public static int[] copyArray(int[] arr){
int[] ans = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
ans[i] = arr[i];
}
return ans;
}
//验证是否排序
public static boolean isSorted(int[] arr){
if(arr.length<2){
return true;
}
int max = arr[0];
for (int i = 0; i < arr.length; i++) {
if(max>arr[i]){
return false;
}
max = Math.max(max,arr[i]);
}
return true;
}
//选择排序
public static void selectSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
int N = arr.length;
for (int i = 0; i < N; i++) {
int minValueIndex = i;
for (int j = i + 1; j < N; j++) {
minValueIndex = arr[j] < arr[minValueIndex] ? j : minValueIndex;
}
swap(arr, i, minValueIndex);
}
}
//交换元素
private static void swap(int[] arr, int i, int j) {
int tmp = arr[j];
arr[j] = arr[i];
arr[i] = tmp;
}
}
3.二分法
public class Demo4 {
public static void main(String[] args) {
/*
*二分法
* */
int[] arr = {1, 3, 6, 8, 8, 9, 16, 20};
//二分法:验证有序数组arr元素是否包含数字num
System.out.println(find(arr, 8));
System.out.println(find(arr, 100));
//二分法:找到有序数组arr元素>=num的最左边元素的下标
System.out.println(mostLeftNoLessNumIndex(arr, 8));
System.out.println(mostLeftNoLessNumIndex(arr, 100));
//二分法:找到有序数组arr元素<=num的最右边元素的下标
System.out.println(mostRightNoMoreNumIndex(arr, 8));
System.out.println(mostRightNoMoreNumIndex(arr, 0));
//二分法:arr整体无序且相邻的元素不相等,求局部最小值
int maxLen = 10;
int maxValue = 200;
int testTime = 1000000;
System.out.println("测试开始");
for (int i = 0; i < testTime; i++) {
int[] arr2 = randomArray(maxLen, maxValue);
int ans = oneMInIndex(arr2);
if (!check(arr2, ans)) {
printArray(arr2);
System.out.println(ans);
break;
}
}
System.out.println("测试结束");
}
//二分法:验证有序数组arr元素是否包含数字num
public static boolean find(int[] arr, int num) {
if (arr == null || arr.length == 0) {
return false;
}
int L = 0;
int R = arr.length - 1;
while (L <= R) {
int mid = (L + R) / 2;
if (arr[mid] == num) {
return true;
} else if (arr[mid] < num) {
L = mid + 1;
} else {
R = mid - 1;
}
}
return false;
}
//二分法:找到有序数组arr元素>=num的最左边元素的下标
public static int mostLeftNoLessNumIndex(int[] arr, int num) {
if (arr == null || arr.length == 0) {
return -1;
}
int L = 0;
int R = arr.length - 1;
int ans = -1;
while (L <= R) {
int mid = (L + R) / 2;
if (arr[mid] >= num) {
ans = mid;
R = mid - 1;
} else {
L = mid + 1;
}
}
return ans;
}
//二分法:找到有序数组arr元素<=num的最右边元素的下标
public static int mostRightNoMoreNumIndex(int[] arr, int num) {
if (arr == null || arr.length == 0) {
return -1;
}
int L = 0;
int R = arr.length - 1;
int ans = -1;
while (L <= R) {
int mid = (L + R) / 2;
if (arr[mid] <= num) {
ans = mid;
L = mid + 1;
} else {
R = mid - 1;
}
}
return ans;
}
//生成随机数组,且相邻数不相等
public static int[] randomArray(int maxLen, int maxValue) {
int len = (int) (Math.random() * maxLen);
int[] arr = new int[len];
if (len > 0) {
arr[0] = (int) (Math.random() * maxValue);
for (int i = 1; i < len; i++) {
do {
arr[i] = (int) (Math.random() * maxValue);
} while (arr[i] == arr[i - 1]);
}
}
return arr;
}
//二分法:arr整体无序且相邻的元素不相等,求局部最小值
public static int oneMInIndex(int[] arr) {
if (arr == null || arr.length == 0) {
return -1;
}
int N = arr.length;
if (N == 1) {
return 0;
}
if (arr[0] < arr[1]) {
return 0;
}
if (arr[N - 1] < arr[N - 2]) {
return N - 1;
}
int L = 0;
int R = N - 1;
//至少有三个数
while (L < R - 1) {
int mid = (L + R) / 2;
if (arr[mid] < arr[mid - 1] && arr[mid] < arr[mid + 1]) {
return mid;
} else {
if (arr[mid] > arr[mid - 1]) {
R = mid - 1;
} else {
L = mid + 1;
}
}
}
return arr[L] < arr[R] ? L : R;
}
//校验局部最小值
public static boolean check(int[] arr, int minIndex) {
if (arr.length == 0) {
return minIndex == -1;
}
int left = minIndex - 1;
int right = minIndex + 1;
boolean leftBigger = left >= 0 ? arr[left] > arr[minIndex] : true;
boolean rightBigger = right < arr.length ? arr[right] > arr[minIndex] : true;
return leftBigger && rightBigger;
}
//打印数组
public static void printArray(int[] arr) {
for (int num : arr) {
System.out.print(num + " ");
}
System.out.println();
}
}
4.单向链表、双向链表
public class Demo6 {
public static void main(String[] args) {
/*
* 单向链表
* */
//构造单向链表
Node n1 = new Node(1);
n1.next = new Node(2);
n1.next.next = new Node(3);
// while (n1 != null){
// System.out.print(n1.value+" ");
// n1 = n1.next;
// }
// System.out.println();
//反转单项链表
Node n2 = reverseLinkedList(n1);
//打印反转的单项链表
while (n2 != null){
System.out.print(n2.value+" ");
n2 = n2.next;
}
System.out.println();
/*
* 双向链表
* */
}
//单向链表反转
public static Node reverseLinkedList(Node head) {
Node pre = null;
Node next = null;
while (head != null) {
next = head.next;
head.next = pre;
pre = head;
head = next;
}
return pre;
}
//单向链表类
public static class Node {
public int value;
public Node next;
public Node(int data) {
value = data;
}
}
//双向链表反转
public static DoubleNode reverseDoubleList(DoubleNode head){
DoubleNode pre = null;
DoubleNode next = null;
while (head != null){
next = head.next;
head.next = pre;
head.last = next;
pre = head;
head= next;
}
return pre;
}
//双向链表类
public static class DoubleNode {
public int value;
public DoubleNode last;
public DoubleNode next;
public DoubleNode(int data) {
value = data;
}
}
}
5.队列、栈
public class Demo7 {
public static void main(String[] args) {
/*
* 队列:单向链表实现
* */
/*
* 栈:单向链表实现
* */
}
//队列类
public static class MyQueue<V>{
private Node<V> head;
private Node<V> tail;
private int size;
public MyQueue(){
head = null;
tail = null;
size = 0;
}
public boolean isEmpty(){
return size == 0;
}
public int size(){
return size;
}
//插入
public void offer(V value){
Node<V> cur = new Node<>(value);
if(tail == null){
head = cur;
tail = cur;
}else {
tail.next = cur;
tail = cur;
}
size++;
}
//弹出
public V poll(){
V ans = null;
if(head != null){
ans = head.value;
head = head.next;
size--;
}
if(head == null){
tail = null;
}
return ans;
}
//查询
public V peek(){
V ans = null;
if(head != null){
ans = head.value;
}
return ans;
}
}
//栈类
public static class MyStack<V>{
private Node<V> head;
private int size;
public MyStack(){
head = null;
size = 0;
}
public boolean isEmpty(){
return size == 0;
}
public int size(){
return size;
}
//插入
public void push(V value){
Node<V> cur = new Node<>(value);
if(head == null){
head = cur;
}else {
cur.next = head;
head = cur;
}
size++;
}
//弹出
public V pop(){
V ans = null;
if(head != null){
ans = head.value;
head = head.next;
size--;
}
return ans;
}
//查询
public V peek(){
return head != null ? head.value : null;
}
}
//单向链表类
public static class Node<V> {
public V value;
public Node<V> next;
public Node(V data) {
value = data;
}
}
}
6.位图
public class Demo8 {
public static void main(String[] args) {
/*
* 位图
* */
//int a = 170;
//等效表达
//System.out.println(a >> 6);
//System.out.println(a / 64);
//等效表达
//System.out.println(a % 64);
//System.out.println(a & 63);
//位图测试
BitMap bitMap = new BitMap(100);
bitMap.add(64);
System.out.println(bitMap.contains(64));
bitMap.delete(64);
System.out.println(bitMap.contains(64));
}
/*
* 位图类:可以高效存储数据。
* 一个long(64字节)可以表示0~63,两个long(128字节)可以表示0~63、64~127,对应字节位置写1即可
* */
public static class BitMap{
private long[] bits;
public BitMap(int max){
bits = new long[(max + 64) >> 6];
}
public void add(int num){
bits[num >> 6] |= (1L << (num & 63));
}
public void delete(int num){
bits[num >> 6] &= ~(1L << (num & 63));
}
public boolean contains(int num){
return (bits[num >> 6] & (1L << (num & 63))) != 0;
}
}
}
7.位运算(实现加减乘除)
package com.demo.algorithm.primary;
public class Demo9 {
public static void main(String[] args) {
/*
* 异或 ^ 不同为1
* 与 & 同1为1
* 带符号右移 >> 右移空出来的位置用符号位补
* 不带符号右移 >>> 右移空出来的位置用0补
* */
/*
* 用位运算实现 + - * /
* */
System.out.println(add(5,2)); //加
System.out.println(negNum(2)); //取反
System.out.println(minus(5,2)); //减
System.out.println(multi(5,2)); //乘
System.out.println(isNeg(5)); //判断是否为负数
System.out.println(div(5,2)); //除
}
//加
public static int add(int a, int b) {
int sum = a;
while (b != 0){
sum = a ^ b; //无进位相加信息
b = (a & b) << 1; //进位信息-> b -> b'
a = sum; //a -> a‘
}
return sum;
}
//取相反数
public static int negNum(int n){
return add(~n,1);
}
//减
public static int minus(int a,int b){
return add(a,negNum(b));
}
//乘
public static int multi(int a,int b){
int res = 0;
while (b != 0){
if((b & 1) != 0){
res = add(res,a);
}
a <<= 1; //带符号左移1位
b >>>= 1; //不带符号右移1位
}
return res;
}
//判断是否为负数
public static boolean isNeg(int n){
return n < 0;
}
//除
public static int div(int a,int b){
int x = isNeg(a) ? negNum(a) : a;
int y = isNeg(b) ? negNum(b) : b;
int res = 0;
//x / y
for (int i = 30;i >= 0;i = minus(i,1)){
if((x >> i) >= y){
res |= (1 << i);
x = minus(x,y << i);
}
}
return isNeg(a) ^ isNeg(b) ? negNum(res) : res; //^可以表示不等
}
//除(考虑极小值)
public static int divide(int a,int b){
if(a == Integer.MIN_VALUE && b == Integer.MIN_VALUE){
return 1;
} else if (b == Integer.MIN_VALUE) {
return 0;
}else if(a == Integer.MIN_VALUE){
if(b == negNum(1)){
return Integer.MAX_VALUE;
}else {
/*
* a / b
* (a + 1) / b == c
* a - (c * b) == d
* d / b == e
* c + e
* */
int ans = div(add(a,1),b);
return add(ans,div(minus(a,multi(ans,b)),b));
}
}else {
return div(a,b);
}
}
}
8.比较器
public class Demo10 {
public static void main(String[] args) {
/*
* 比较器:自定义排序
* */
Student s1 = new Student("张三", 3, 25);
Student s2 = new Student("李四", 7, 29);
Student s3 = new Student("王五", 2, 18);
//数组
Student[] students = {s1,s2,s3};
print(students);
System.out.println("========");
Arrays.sort(students,new IdComparator());
print(students);
System.out.println("================");
//集合
ArrayList<Student> arrayList = new ArrayList<>();
arrayList.add(s1);
arrayList.add(s2);
arrayList.add(s3);
print(arrayList);
System.out.println("========");
arrayList.sort(new IdComparator());
print(arrayList);
System.out.println("================");
//优先级队列(内部结构是堆)
PriorityQueue<Student> heap = new PriorityQueue<>(new IdComparator());
heap.add(s1);
heap.add(s2);
heap.add(s3);
while (!heap.isEmpty()){
Student s = heap.poll();
System.out.println(s);
}
//TreeSet
TreeSet<Student> treeSet = new TreeSet<>(new IdComparator());
}
//自定义比较器(按id正序排列)
public static class IdComparator implements Comparator<Student>{
@Override
//如果返回负数,第一个参数在前
//如果返回正数,第二个参数在前
//如果返回0,认为谁放在前面无所谓
public int compare(Student o1, Student o2) {
return o1.id - o2.id;
}
}
//学生类
public static class Student{
public String name;
public int id;
public int age;
public Student(String name, int id, int age) {
this.name = name;
this.id = id;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", id=" + id +
", age=" + age +
'}';
}
}
//打印数组
public static <V> void print(V[] vs){
for (V v : vs){
System.out.println(v);
}
}
//打印集合
public static <V> void print(Collection<V> vs){
for (V v : vs){
System.out.println(v);
}
}
}
9.二叉树
public class Demo11 {
public static void main(String[] args) {
/*
* 二叉树
* 先序:头左右
* 中序:左头右
* 后序:左右头
* */
}
//二叉树类
public static class Node{
public int value;
public Node left;
public Node right;
public Node(int v){
value = v;
}
}
//递归序(每个节点走3次)
public static void f(Node head){
if(head == null){
return;
}
//1 在此打印节点为头序
f(head.left);
//2 在此打印节点为中序
f(head.right);
//3 在此打印节点为后序
}
//判断二叉树是否结构相同
public static boolean isSameTree(Node p,Node q){
if(p == null ^ q == null){
return false;
}
if(p == null && q == null){
return true;
}
return p.value == q.value && isSameTree(p.left,q.left) && isSameTree(p.right,q.right);
}
//判断是否为镜面树
public static boolean isSymmetric(Node root){
return isMirror(root,root);
}
public static boolean isMirror(Node h1,Node h2){
if(h1 == null ^ h2 == null){
return false;
}
if(h1 == null && h2 == null){
return true;
}
return h1.value == h2.value && isMirror(h1.left,h2.right) && isMirror(h1.right,h2.left);
}
//返回一棵树的最大深度
public static int maxDepth(Node root){
if(root == null){
return 0;
}
return Math.max(maxDepth(root.left),maxDepth(root.right)) + 1;
}
//用先序数组pre[L1...R1]和中序数组in[L2...R2]重建一棵树
public static Node buildTree(int[] pre,int[] in){
if(pre == null || in == null || pre.length != in.length){
return null;
}
HashMap<Integer, Integer> valueIndexMap = new HashMap<>();
for (int i = 0; i < in.length; i++) {
valueIndexMap.put(in[i],i);
}
return g(pre,0,pre.length - 1,in,0,in.length - 1,valueIndexMap);
}
public static Node g(int[] pre,int L1,int R1,int[] in,int L2,int R2,
HashMap<Integer,Integer> valueIndexMap){
if(L1 > R1){
return null;
}
Node head = new Node(pre[L1]);
if(L1 == R1){
return head;
}
int find = valueIndexMap.get(pre[L1]);
head.left = g(pre,L1 + 1,L1 + find - L2,in,L2,find - 1,valueIndexMap);
head.right = g(pre,L1 + find - L2 + 1,R1,in,find + 1,R2,valueIndexMap);
return head;
}
//二叉树按层遍历并收集节点
public List<List<Integer>> levelOrderBottom(Node root){
List<List<Integer>> ans = new LinkedList<>();
if(root == null){
return ans;
}
Queue<Node> queue = new LinkedList<>();
queue.add(root);
while (!queue.isEmpty()){
int size = queue.size(); //控制同层节点数量
List<Integer> curAns = new LinkedList<>();
for (int i = 0; i < size; i++) {
Node curNode = queue.poll();
curAns.add(curNode.value);
if(curNode.left != null){
queue.add(curNode.left);
}
if(curNode.right != null){
queue.add(curNode.right);
}
}
ans.add(curAns);
}
return ans;
}
//判断是否为搜索二叉树:中序遍历从小到大(任意节点均为搜索二叉树,且左树的max<x<右树的min)
public static class Info{
public boolean isBST;
public int max;
public int min;
public Info(boolean is,int ma,int mi){
isBST = is;
max = ma;
min = mi;
}
}
public static Info process(Node x){
if (x == null){
return null;
}
Info leftInfo = process(x.left);
Info rightInfo = process(x.right);
int max = x.value;
int min = x.value;
if(leftInfo != null){
max = Math.max(leftInfo.max,max);
min = Math.min(leftInfo.min,min);
}
if(rightInfo != null){
max = Math.max(rightInfo.max,max);
min = Math.min(rightInfo.min,min);
}
// //方式1
// boolean isBST = true;
// if(leftInfo != null && !leftInfo.isBST){
// isBST = false;
// }
// if(rightInfo != null && !rightInfo.isBST){
// isBST = false;
// }
// //left Max < x < right min
// boolean leftMaxLessX = leftInfo == null ? true : (leftInfo.max < x.value);
// boolean rightMinMoreX = rightInfo == null ? true : (rightInfo.min > x.value);
// if(!leftMaxLessX || !rightMinMoreX){
// isBST = false;
// }
//方式2
boolean isBST = false;
boolean leftIsBST = leftInfo == null ? true : leftInfo.isBST;
boolean rightIsBST = rightInfo == null ? true : rightInfo.isBST;
boolean leftMaxLessX = leftInfo == null ? true : (leftInfo.max < x.value);
boolean rightMinMoreX = rightInfo == null ? true : (rightInfo.min > x.value);
if(leftIsBST && rightIsBST && leftMaxLessX && rightMinMoreX){
isBST = true;
}
return new Info(isBST,max,min);
}
//能否组成路径和:存在根节点到叶节点累加值等于指定的某个数
public static boolean isSum = false;
public static boolean hasPathSum(Node root,int sum){
if(root == null){
return false;
}
isSum = false;
process2(root,0,sum);
return isSum;
}
public static void process2(Node x,int preSum,int sum){
//x是叶节点
if(x.left == null && x.right == null){
if(x.value + preSum == sum){
isSum = true;
}
}
//x是非叶节点
preSum += x.value;
if(x.left != null){
process2(x.left,preSum,sum);
}
if(x.right != null){
process2(x.right,preSum,sum);
}
}
//收集达标路径和
public static List<List<Integer>> pathSum(Node root,int sum){
List<List<Integer>> ans = new ArrayList<>();
if(root == null){
return ans;
}
ArrayList<Integer> path = new ArrayList<>();
process3(root,path,0,sum,ans);
return ans;
}
public static void process3(Node x,List<Integer> path,int preSum,int sum,List<List<Integer>> ans){
if(x.left == null && x.right == null){
if(preSum + x.value == sum){
path.add(x.value);
ans.add(copy(path));
path.remove(path.size() - 1);
}
return;
}
//x为非叶节点
path.add(x.value);
preSum += x.value;
if(x.left != null){
process3(x.left,path,preSum,sum,ans);
}
if(x.right != null){
process3(x.right,path,preSum,sum,ans);
}
path.remove(path.size() - 1);
}
//拷贝集合
public static <T> List<T> copy(List<T> path){
ArrayList<T> ans = new ArrayList<>(path);
return ans;
}
}
10.归并排序、快速排序
public class Demo13 {
public static void main(String[] args) {
/*
* 归并排序
* */
/*
* 快速排序
* */
int[] arr = {7,1,3,5,4,5,1,4,2,4,2,3};
// splitNum(arr); //1 3 1 2 2 3 7 4 5 4 4 5 (以原数组最后一位元素为界限,<=在左,>在右)
// splitNum2(arr); //2 1 2 1 3 3 4 4 4 5 7 5 (以原数组最后一位元素为界限,<在左,=在中,>在右)
quickSort(arr); //1 1 2 2 3 3 4 4 4 5 5 7 (从小到大排序)
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
/*
* 归并排序
* */
//递归实现
public static void mergeSort1(int[] arr){
if(arr == null || arr.length < 2){
return;
}
process(arr,0,arr.length-1);
}
//arr[L...R]范围上,请让这个范围的数有序
public static void process(int[] arr,int L,int R){
if(L == R){
return;
}
//int mid = (L + R) / 2
int mid = L + ((R - L) >> 1);
process(arr,L,mid); //保证左边有序
process(arr,mid + 1,R); //保证右边有序
merge(arr,L,mid,R); //保证左右一起有序
}
public static void merge(int[] arr,int L,int M,int R){
int[] help = new int[R - L + 1];
int i = 0;
int p1 = L;
int p2 = M + 1;
while (p1 <= M && p2 <= R){
help[i++] = arr[p1] <= arr[p2] ? arr[p1++] : arr[p2++];
}
while (p1 <= M){
help[i++] = arr[p1++];
}
while (p2 <= R){
help[i++] = arr[p2++];
}
for (int j = 0; j < help.length; j++) {
arr[L+j] = help[j];
}
}
/*
* 快速排序
* */
public static void splitNum(int[] arr){
int lessEqualR = -1;
int index = 0;
int N = arr.length;
while (index < N){
if(arr[index] <= arr[N - 1]){
swap(arr,++lessEqualR,index++);
}else {
index++;
}
}
}
public static void splitNum2(int[] arr){
int N = arr.length;
int lessR = -1;
int MoreL = N - 1;
int index = 0;
while (index < MoreL){
if(arr[index] < arr[N -1]){
swap(arr,++lessR,index++);
} else if (arr[index] > arr[N - 1]) {
swap(arr,--MoreL,index);
}else {
index++;
}
}
swap(arr,MoreL,N -1);
}
//arr[L...R]范围上,拿arr[R]做划分值
//L...R < = >
//返回=区间的开始下标和结束下标
public static int[] partition(int[] arr,int L,int R){
int lessR = L - 1;
int moreL = R;
int index = L;
while (index < moreL){
if(arr[index] < arr[R]){
swap(arr,++lessR,index++);
} else if (arr[index] > arr[R]) {
swap(arr,--moreL,index);
}else {
index++;
}
}
swap(arr,moreL,R);
return new int[]{lessR + 1,moreL};
}
public static void quickSort(int[] arr){
if(arr == null || arr.length < 2){
return;
}
quickSortProcess(arr,0,arr.length - 1);
}
public static void quickSortProcess(int[] arr,int L,int R){
if(L >= R){
return;
}
//L < R
int[] equalE = partition(arr,L,R);
//equal[0]等于区域第一个数
//equal[1]等于区域最后一个数
quickSortProcess(arr,L,equalE[0] - 1);
quickSortProcess(arr,equalE[1] + 1,R);
}
public static void swap(int[] arr,int i,int j){
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}