算法¶
快排¶
public static void quickSort(int arr[], int left, int right) {
if (left < right) {
int partitionIndex = partition(arr, left, right);
quickSort(arr, left, partitionIndex-1);
quickSort(arr, partitionIndex+1, right);
}
}
private static int partition(int arr[], int left, int right) {
int key = arr[right];
int i = left - 1;
for (int j = left; j < right; j++) {
if (arr[j] <= key) {
i++;
swap(arr, i, j);
}
}
swap(arr, i+1, right);
return i+1;
}
public static void swap(int[] arr, int i, int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
归并排序¶
public void mergeSort(int[] arr, int left, int right) {
int mid = (left + right) / 2; // 中间下标
if (left < right) {
mergeSort(arr, left, mid); // 递归拆分左边
mergeSort(arr, mid + 1, right); // 递归拆分右边
sort(arr, left, mid, right); // 合并左右
}
}
public void sort(int[] arr, int left, int mid, int right) {
int[] temp = new int[right - left + 1]; // 临时数组,用来保存每次合并年之后的结果
int i = left;
int j = mid + 1;
int k = 0; // 临时数组的初始下标
while (i <= mid && j <= right) {
if (arr[i] <= arr[j]) {
temp[k++] = arr[i++];
} else {
temp[k++] = arr[j++];
}
}
while (i <= mid) {
temp[k++] = arr[i++];
}
while (j <= right) {
temp[k++] = arr[j++];
}
for (int m = 0; m < temp.length; m++) {
arr[m + left] = temp[m];
}
}
堆排序¶
public static void heapSort(int[] nums) {
if (nums == null) {
return;
}
int len = nums.length;
// 初始化大顶堆(从最后一个非叶节点开始,从左到右,由下到上)
for (int i = len / 2 - 1; i >= 0; i--) {
adjustHeap(nums, i, len);
}
// 将顶节点和最后一个节点互换位置,再将剩下的堆进行调整
for (int j = len - 1; j > 0; j--) {
swap(nums, 0, j);
adjustHeap(nums, 0, j);
}
}
// 整理树让其变成堆
public static void adjustHeap(int[] arr, int i, int j) {
int temp = arr[i];// 定义一个变量保存开始的结点
// k就是该结点的左子结点下标
for (int k = 2 * i + 1; k < j; k = 2 * k + 1) {
// 比较左右两个子结点的大小,k始终记录两者中较大值的下标
if (k + 1 < j && arr[k] < arr[k + 1]) {
k++;
}
// 经子结点中的较大值和当前的结点比较,比较结果的较大值放在当前结点位置
if (arr[k] > temp) {
arr[i] = arr[k];
i = k;
} else { // 说明已经是大顶堆
break;
}
}
arr[i] = temp;
}
public static void swap(int[] arr, int num1, int num2) {
int temp = arr[num1];
arr[num1] = arr[num2];
arr[num2] = temp;
}
两个队列实现栈¶
public class StackWithTwoQueue {
ArrayDeque<Integer> queue;
ArrayDeque<Integer> help;
public StackWithTwoQueue(){
queue = new ArrayDeque<>();
help = new ArrayDeque<>();
}
public void push(int i){
queue.add(i);
}
public int pop(){
if (queue.isEmpty()){
throw new RuntimeException("stack is empty");
}
while (queue.size() > 1){
help.add(queue.poll());
}
int res = queue.poll();
swap();
return res;
}
public void swap(){
ArrayDeque<Integer> temp = queue;
queue = help;
help = temp;
}
}
两个栈实现队列¶
public class QueueWithTwoStack {
ArrayDeque<Integer> stack;
ArrayDeque<Integer> help;
public QueueWithTwoStack(){
stack = new ArrayDeque<>();
help = new ArrayDeque<>();
}
public void push(int i){
stack.push(i);
}
public int pop(){
if (help.isEmpty()){
if (stack.isEmpty()){
return -1;
}
while (!stack.isEmpty()){
help.add(stack.pop());
}
}
return help.pop();
}
}
BST¶
public static void insert(int data) {
Node newNode = new Node();
newNode.val = data;
if(root == null) {
//如果是第一个节点,也就是根节点为null,直接创建一个新的节点即可
root = newNode;
} else {
Node cur = root;
//current节点的父节点
Node parent;
//循环查找插入的位置
while(true) {
parent = cur;
//如果插入的值小于当前节点的值,从左子树查找
if(data < cur.val) {
cur = cur.leftChild;
//直到当前节点为null
if(cur == null) {
//设置当前节点的父节点的左子节点为新创建的节点
parent.leftChild = newNode;
return;
}
}
//如果插入的值大于当前节点的值,从右子树查找
else {
cur = cur.rightChild;
//直到当前节点为null
if(cur == null) {
//设置当前节点的父节点的右子节点为新创建的节点
parent.rightChild = newNode;
return;
}
}
}
}
}