前两天面试,开始没有进行笔试,谈着谈着面试官突然说,请写一个冒泡排序,难怪当时进来的时候他手上拿着一支笔,说着将我的简历朝背面铺开,当时心里小小慌了一下,因为我算法不算好,而且很久没有复习算法基础知识,拿起笔那一刻,强行叫自己不要慌,然后开始回忆冒泡的步骤,大概3分钟的样子,写出来了,写完之后心想,回去之后还是得好好巩固基础,不进则退。
import java.util.Arrays;
public class Sort {
public static void main(String[] args) {
int [] a = {1,100,234,44,3,2,4,5};
// bubbleSort(a,a.length+1);
// selectionSort(a,a.length);
// insertionSort(a,a.length);
// quickSort(a,0,a.length-1);
// mergeSort(a,a.length);
duisort(a);
System.out.println(Arrays.toString(a));
}
//冒泡排序
public static int[] bubbleSort(int[] A, int n) {
for (int i=0;i<A.length;i++){
for (int j=i+1;j<A.length;j++){
if (A[i] > A[j]){
int tmp = A[i];
A[i] = A[j];
A[j] = tmp;
}
}
}
return A;
}
//选择排序
public static int[] selectionSort(int[] A, int n) {
for (int i = 0; i < n - 1; i++) {
int index = i;
// 找出最小值得元素下标
for (int j = i + 1; j < n; j++) {
if (A[j] < A[index]) {
index = j;
}
}
int tmp = A[index];
A[index] = A[i];
A[i] = tmp;
}
return A;
}
//插入排序
public static int[] insertionSort(int[] A, int n) {
int i, j, temp;
for(i = 1; i < A.length; i++){
temp = A[i];
for(j = i; j > 0 && temp < A[j-1]; j--){
A[j] = A[j-1]; // j 是每次腾出的位置
}
A[j] = temp;
}
return A;
}
//快速排序
public static void quickSort(int[] A, int left, int right) {
if (left < right) {
// 一次划分
int mid = partion(A, left, right);
quickSort(A, 0, mid - 1);
quickSort(A, mid + 1, right);
}
}
public static void swap(int[] A, int l, int r) {
int tmp = A[l];
A[l] = A[r];
A[r] = tmp;
}
public static int partion(int[] a, int left, int right) {
// 轴值,默认选取数组的第一个数字
while (left < right) {
while (left < right && a[left] <= a[right]) {
right--;
}
if (left<right){
swap(a, left, right);
}
while (left < right && a[left] <= a[right]) {
left++;
}
if (left<right){
swap(a, left, right);
}
}
return left;
}
//归并排序
public static int[] mergeSort(int[] A, int n) {
sort(A, 0, n - 1);
return A;
}
public static void sort(int[] A, int left, int right) {
if (left < right) {
int mid = (left + right) / 2;
sort(A, left, mid);
sort(A, mid + 1, right);
merge(A, left, mid, right);
}
}
public static void merge(int[] A, int left, int mid, int right) {
// 临时数组
int n = right - left + 1;
int[] tmpArr = new int[n];
int l = left;
int r = mid + 1;
int t = 0;// 临时数组下标元素
// 比较两子序列元素的大小
while (l <= mid && r <= right) {
if (A[l] < A[r]) {
tmpArr[t++] = A[l++];
} else {
tmpArr[t++] = A[r++];
}
}
// 剩余的加入临时数组
while (l <= mid) {
tmpArr[t++] = A[l++];
}
// 剩余的加入临时数组
while (r <= right) {
tmpArr[t++] = A[r++];
}
// 把临时数组元素放回原数组
for (int i = 0; i < t; i++) {
A[left + i] = tmpArr[i];
}
}
//堆排序
public static void duisort(int[] a) {
int len = a.length;
for (int i = 0; i < len - 1; i++) {
// 建堆
buildHeap(a, len - 1 - i);
// 交换堆顶元素和最后一个元素
swap(a, 0, len - 1 - i);
}
}
public static void buildHeap(int[] a, int lastIndex) {
// 从最后一个节点的父节点开始
for (int i = (lastIndex - 1) / 2; i >= 0; i--) {
// 当前节点存在子节点
while (i * 2 + 1 <= lastIndex) {
// 左节点下标值
int l = i * 2 + 1;
// 右结点下标值
int r = i * 2 + 2;
// 默认左节点为最大值
int biggerIndex = l;
// 存在右结点
if (l < lastIndex) {
// 右结点的值比左节点大
if (a[r] > a[l]) {
biggerIndex = r;
}
}
// 当前节点的值比孩子节点的最小值小,交换
if (a[i] < a[biggerIndex]) {
swap(a, i, biggerIndex);
// 把最大值下标赋给当前节点,进入下一次while循环判断
i = biggerIndex;
} else {
break;
}
}
}
}
}