给你一个整数数组 nums
,请你将该数组升序排列。
主要有 冒泡 简单选择 直接插入 希尔 堆 归并 快速排序七种
多种方法,其中要求空间内存时,可优先使用堆排序
直接插入排序,,,在接近有序的情况下,表现优异
稳定性来讲,归并排序
从数据量来看,数据量越小,简单排序方式越合适
反之。数据量大,则采用快排
class Solution {
public int[] sortArray(int[] nums) {
//简单选择排序 超时 如果在交换成本较高的排序任务中,就可以使用「选择排序」 交换次数最少。
int len = nums.length;
for(int i = 0;i<len -1;i++){
int minIndex = i;
for(int j=i+1;j<len;j++){
if(nums[j]< nums[minIndex]){
minIndex = j;
}
}
swap(nums,minIndex,i);
}
return nums;
}
private void swap(int[] nums ,int i,int j){
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
class Solution {
public int[] sortArray(int[] nums) {
//直接插入排序 稳定排序,在接近有序的情况下,表现优异
int len = nums.length;
for(int i = 1;i<len;i++){
int temp = nums[i];
int j = i;
while(j>0 && nums[j-1]>temp){
nums[j] = nums[j-1];
j--;
}
nums[j]=temp;
}
return nums;
}
}
class Solution {
public int[] sortArray(int[] nums) {
//归并排序 借助了额外空间,可以实现「稳定排序」
int len =nums.length;
int [] temp=new int [len];
mergeSort(nums,0,len-1,temp);
return nums;
}
//
private void mergeSort(int []nums,int left,int right,int []temp){
if(left < right){
int middle = left+(right-left)/2;
mergeSort(nums,left,middle,temp);
mergeSort(nums,middle+1,right,temp);
merge(nums,left,middle,right,temp);
}
}
//合并
private void merge(int []nums, int left,int middle,int right,int []temp){
//左半区第一个未排序的元素
int i = left;
//右半区第一个未排序的元素
int j = middle+1;
//临时数组元素的下标
int k = left;
// 合并
while(i <= middle && j <=right){
if(nums[i] <= nums[j]){
// 左半区第一个剩余元素更小
temp[k++] = nums[i++];
}else{
// 右半区第一个剩余元素更小
temp[k++] =nums[j++];
}
}
// 合并左半区剩余元素
while(i<=middle){
temp[k++] =nums[i++];
}
// 合并右半区剩余元素
while(j <=right){
temp[k++] =nums[j++];
}
//把临时数组中合并的元素复制回原来的数组
while(left <=right){
nums[left] =temp [left];
left++;
}
}
}
class Solution {
public int[] sortArray(int[] nums) {
/**
* 列表大小等于或小于该大小,将优先于 quickSort 使用插入排序
*/
int len = nums.length;
qSort(nums,0,len-1);
return nums;
}
//递归划分
private void qSort(int[]nums,int low,int high){
if(low < high){
int mid = partition(nums,low,high);
qSort(nums,low,mid-1);
qSort(nums,mid+1,high);
}
}
//快速排序
private int partition(int nums[],int low,int high){
int pivot =nums[ high];
int i = low;
for(int j = low;j<high;j++){
//如果比pivot小,则移到pivot前面
if(pivot > nums[j]){
swap(nums,j,i);
i++;
}
}
// 此时,i指向的元素一定大于等于pivot
swap(nums,i,high);
return i;
}
private void swap(int nums[],int i,int j){
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
class Solution {
public int[] sortArray(int[] nums) {
/**
* 归并排序
*/
int len = nums.length;
qSort(nums,0,len-1);
return nums;
}
//递归划分
private void qSort(int[]nums,int low,int high){
if(low < high){
int mid = partition(nums,low,high);
qSort(nums,low,mid-1);
qSort(nums,mid+1,high);
}
}
//快速排序
private int partition(int nums[],int low,int high){
int pivot =nums[ high];
int i = low;
for(int j = low;j<high;j++){
//如果比pivot小,则移到pivot前面
if(pivot > nums[j]){
swap(nums,j,i);
i++;
}
}
// 此时,i指向的元素一定大于等于pivot
swap(nums,i,high);
return i;
}
private void swap(int nums[],int i,int j){
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
class Solution {
// 堆排序
public int[] sortArray(int[] nums) {
int len = nums.length;
//建堆
// i的父节点的下标为(i-1)/2 其左子女为2*i+1;;;;右子女2*i+2
for(int i = (len-1)/2;i>=0;i--){
heapify(nums,len,i);
}
//排序
for(int j =len-1;j>0;j--){
swap(nums,j,0);
heapify(nums,j,0);
}
return nums;
}
// 维护堆的性质
void heapify(int nums[],int len,int i){
int largest = i;
int lson = 2*i+1;
int rson = 2*i+2;
if(lson < len && nums[largest] <nums[lson]){
largest = lson;
}
if(rson <len &&nums[largest] < nums[rson]){
largest =rson;
}
if(largest != i){
swap(nums,largest,i);
heapify(nums,len,largest);
}
}
private void swap(int nums[],int j,int i){
int temp=nums[j];
nums[j]=nums[i];
nums[i]=temp;
}
}