掌握常见的内部排序方法(插入排序,冒泡排序,选择排序,快速排序,堆排序,希尔排序,归并排序,基数排序等)。
数组高级以及Arrays(掌握)
排序方法 | 空间复杂度 | 时间复杂度 | 稳定性 | |
插 入 排 序 | 直接插入排序 | O(1) | 平均O(n2) 最坏O(n2) 最好O(n) | 稳定 |
折半插入排序 | O(1) | 平均O(nlogn) 最坏O(n2) | 稳定 | |
希尔排序 | O(1) | 平均O(n2) | 不稳定 | |
交 换 排 序 | 冒泡排序 | O(1) | 平均O(n2) 最坏O(n2) 最好O(n) | 稳定 |
快速排序 | 平均O(nlogn) 最坏O(n) | 平均O(nlogn) 最坏O(n2) 平均O(nlogn) | 不稳定 | |
选 择 排 序 | 简单选择排序 | O(1) | 始终O(n2) | 不稳定 |
堆排序 | O(1) | 平均O(nlogn) 建堆O(n) 调整O(logn) | 不稳定 | |
归并排序 | O(n) | O(nlogn) | 稳定 | |
基数排序 | O(d(n+r)) | O(d(n+r)) | 稳定 |
(1)排序
A:冒泡排序
相邻元素两两比较,大的往后放,第一次完毕,最大值出现在了最大索引处。同理,其他的元素就可以排好。
public static void bubbleSort(int[] arr) {
for(int x=0; x<arr.length-1; x++) {
for(int y=0; y<arr.length-1-x; y++) {
if(arr[y] > arr[y+1]) {
int temp = arr[y];
arr[y] = arr[y+1];
arr[y+1] = temp;
}
}
}
}
B:选择排序
把0索引的元素,和索引1以后的元素都进行比较,第一次完毕,最小值出现在了0索引。同理,其他的元素就可以排好。
public static void selectSort(int[] arr) {
for(int x=0; x<arr.length-1; x++) {
for(int y=x+1; y<arr.length; y++) {
if(arr[y] < arr[x]) {
int temp = arr[x];
arr[x] = arr[y];
arr[y] = temp;
}
}
}
}
C.插入排序算法:
public static void insertSort(int[] arr) {
for (int i = 1; i < arr.length; i++) {
if(arr[i]<arr[i-1]){
arr[0]=arr[i];
for(int j=i-1;arr[0]<arr[j];j--)//只要arr[i]大的都后移,找到arr[i]合适的插入位置
arr[j+1]=arr[j];
arr[j+1]=arr[0];
}
}
}
D希尔排序:
/*
* 希尔排序:先取一个小于n的整数d1作为第一个增量,
* 把文件的全部记录分成(n除以d1)个组。所有距离为d1的倍数的记录放在同一个组中。
* 先在各组内进行直接插入排序;然后,取第二个增量d2<d1重复上述的分组和排序,
* 直至所取的增量dt=1(dt<dt-l<…<d2<d1),即所有记录放在同一组中进行直接插入排序为止。
*/
public class ShellSort {
public static void sort(int[] data) {
for (int i = data.length / 2; i > 2; i /= 2) {//设置增量
for (int j = 0; j < i; j++) {
insertSort(data, j, i);
}
}
insertSort(data, 0, 1);
}
private static void insertSort(int[] data, int start, int inc) {
for (int i = start + inc; i < data.length; i += inc) {
for (int j = i; (j >= inc) && (data[j] < data[j - inc]); j -= inc){
SortTest.swap(data, j, j - inc);
}
}
}
}
E.快速排序:
Void Quicksort(int A[],int low,int high){
If(low<high){
Int pivotpos= partion(A, low ,high);//获取枢轴数位置
Quicksort(A, low,pivotpos-1);
Quicksort(A,pivotpos-1,high)
}
}
Int partion(int A[],int low ,int high){
Int pivot=Alow];
While(low<high){
While(low<high&&A[high]>=pivot) high--;//从枢轴小的左移
A[low]=A[high];
While(low<high&&A[low] <=pivot) low++;//从枢轴大的右移
A[high] =A[low];
A[low]=pivot; //枢轴最后存放的位置
return low;
}
}
F:归并排序:
public static int[] sort(int[] a,int low,int high){
int mid = (low+high)/2;
if(low<high){
sort(a,low,mid);//分成两个子序列,分别递归排序
sort(a,mid+1,high);
//左右归并
merge(a,low,mid,high);
}
return a;
}
//将两个有序表合并成一个有序表
public static void merge(int[] a, int low, int mid, int high) {
int[] temp = new int[high-low+1];//定义一个数组
int i= low;
int j = mid+1;
int k=0;
// 把较小的数先移到新数组中
while(i<=mid && j<=high){
if(a[i]<a[j]){
temp[k++] = a[i++];
}else{
temp[k++] = a[j++];
}
}
// 把左边剩余的数移入数组
while(i<=mid){
temp[k++] = a[i++];
}
// 把右边边剩余的数移入数组
while(j<=high){
temp[k++] = a[j++];
}
// 把新数组中的数覆盖nums数组
for(int x=0;x<temp.length;x++){
a[x+low] = temp[x];//原数组从low开始的
}
}
G:堆排序
//构建大根堆:将array看成完全二叉树的顺序存储结构
private int[] buildMaxHeap(int[] array){
//从最后一个节点array.length-1的父节点(array.length-1)/2开始,直到根节点0,反复调整堆
for(int i=(array.length-1)/2;i>=0;i--){
adjustDownToUp(array, i,array.length);
}
return array;
}
//将元素array[k]自下往上逐步调整树形结构
private void adjustDownToUp(int[] array,int k,int length){
int temp = array[k];
for(int i=2*k; i<length; i=2*i){ //i为初始化为节点k的左孩子,沿节点较大的子节点向下调整
if(i<length && array[i]<array[i+1]){ //取节点较大的子节点的下标
i++; //如果节点的右孩子>左孩子,则取右孩子节点的下标
}
if(temp>=array[i]){ //根节点 >=左右子女中关键字较大者,调整结束
break;
}else{ //根节点 <左右子女中关键字较大者
array[k] = array[i]; //将左右子结点中较大值array[i]调整到双亲节点上
k = i; //【关键】修改k值,以便继续向下调整
}
}
array[k] = temp; //被调整的结点的值放人最终位置
}
//堆排序
public int[] heapSort(int[] array){
array = buildMaxHeap(array); //初始建堆,array[0]为第一趟值最大的元素
for(int i=array.length-1;i>1;i--){
int temp = array[0]; //将堆顶元素和堆低元素交换,即得到当前最大元素正确的排序位置
array[0] = array[i];
array[i] = temp;
adjustDownToUp(array, 0,i-1); //整理,将剩余的元素整理成堆
}
return array;
}
(2)查找
A:基本查找
针对数组无序的情况
public static int getIndex(int[] arr,int value) {
int index = -1;
for(int x=0; x<arr.length; x++) {
if(arr[x] == value) {
index = x;
break;
}
}
return index;
}
B:二分查找(折半查找)
针对数组有序的情况(千万不要先排序,在查找)
public static int binarySearch(int[] arr,int value) {
int min = 0;
int max = arr.length-1;
int mid = (min+max)/2;
while(arr[mid] != value) {
if(arr[mid] > value) {
max = mid - 1;
}else if(arr[mid] < value) {
min = mid + 1;
}
if(min > max) {
return -1;
}
mid = (min+max)/2;
}
return mid;
}