1. 选择排序
思路:每次选择一个最小(最大)的元素,放在第 i 个位置上(与位置 i 上的元素交换),i 的范围是[0,n-1]。
1.1 java
class Solution {
//选择排序,选择最小的元素与位置i(i=[0,n-1])交换
public int[] sortArray(int[] nums) {
int n = nums.length;
//选择n-1次,最后一次不用
for(int i = 0; i < n - 1; ++ i) {
int minIdx = i;//i~n-1中最小值的下标
for(int j = i + 1; j < n; ++ j) {
if(nums[j] < nums[minIdx]) {
minIdx = j;//更新最小值的下标
}
}
swap(nums, i, minIdx);//元素交换
}
return nums;
}
public void swap(int[] nums, int x, int y) {
int tmp = nums[x];
nums[x] = nums[y];
nums[y] = tmp;
}
}
1.2 go
func sortArray(nums []int) []int {
n := len(nums)
for i := 0; i < n - 1; i ++ {
minIdx := i
for j := i + 1; j < n; j ++ {
if nums[j] < nums[minIdx] {
minIdx = j
}
}
swap(nums, minIdx, i)
}
return nums
}
func swap(nums []int, x int, y int) {
tmp := nums[x]
nums[x] = nums[y]
nums[y] = tmp
}
1.3 时空复杂度
时间复杂度:O(n^2)
空间复杂度:O(1)
2. 插入排序
思路:每一次将一个数字插入一个有序数组里,成为一个长度更长的数组,有限次操作后,数组整体有序。
2.1 java
class Solution {
public int[] sortArray(int[] nums) {
int n = nums.length;
//找到nums[i]所在的位置
for(int i = 0; i < n; i ++) {
int tmp = nums[i];
int j = i;
//找到第一个不大于tmp(nums[i])的位置
while(j > 0 && nums[j - 1] > tmp) {
nums[j] = nums[j - 1];
j --;
}
nums[j] = tmp;
}
return nums;
}
}
2.2 go
func sortArray(nums []int) []int {
n := len(nums)
for i := 0; i < n; i ++ {
tmp := nums[i]
j := i
for j > 0 && nums[j - 1] > tmp {
nums[j] = nums[j - 1]
j --
}
nums[j] = tmp
}
return nums
}
2.3 时空复杂度
时间复杂度:O(n^2)
空间复杂度:O(1)
3. 快速排序
3.1 java
class Solution {
public int[] sortArray(int[] nums) {
randomizedQuicker(nums, 0, nums.length - 1);
return nums;
}
public void randomizedQuicker(int[] nums, int left, int right) {
if(left < right) {
int pos = randomizedPartition(nums, left, right);
randomizedQuicker(nums, left, pos - 1);
randomizedQuicker(nums, pos + 1, right);
}
}
public int randomizedPartition(int[] nums, int left, int right) {
//获取一个随机轴点
int i = new Random().nextInt(right - left + 1) + left;
swap(nums, i, right);
return partition(nums, left, right);
}
public void swap(int[] nums, int x, int y) {
int tmp = nums[x];
nums[x] = nums[y];
nums[y] = tmp;
}
public int partition(int[] nums, int left, int right) {
int pivot = nums[right];
int i = left - 1;
for(int j = left; j < right; ++ j) {
//[left, i]范围内的值都小于等于pivot
if(nums[j] <= pivot) {
i ++;
swap(nums, i, j);
}
}
swap(nums, i + 1, right);
return i + 1;
}
}
3.2 go
func sortArray(nums []int) []int {
randomizedQuickSort(nums, 0, len(nums) - 1)
return nums
}
func randomizedQuickSort(nums []int, left int, right int) {
if left < right {
pos := randomizedPartition(nums, left, right)
randomizedQuickSort(nums, left, pos - 1)
randomizedQuickSort(nums, pos + 1, right)
}
}
func randomizedPartition(nums []int, left int, right int) int {
i := rand.Intn(right - left + 1) + left
swap(nums, i, right)
return partition(nums, left, right)
}
func swap(nums []int, x int, y int) {
tmp := nums[x]
nums[x] = nums[y]
nums[y] = tmp
}
func partition(nums []int, left int, right int) int {
pivot := nums[right]
i := left - 1
for j := left; j < right; j ++ {
if nums[j] <= pivot {
i ++
swap(nums, i, j)
}
}
swap(nums, i + 1, right)
return i + 1
}
3.3 时空复杂度
时间复杂度:最坏O(n^2),最好和平均时间复杂度为O(nlogn)
空间复杂度:最坏是O(n),最好和平均是O(logn)
4. 堆排序
4.1 java
class Solution {
public int[] sortArray(int[] nums) {
heapSort(nums);
return nums;
}
public void heapSort(int[] nums) {
int len = nums.length - 1;
//建立大根堆
buildMaxHeap(nums, len);
for(int i = len; i >= 1; -- i) {
swap(nums, i, 0);
len --;
maxHeapify(nums, 0, len);
}
}
public void buildMaxHeap(int[] nums, int len) {
//对所有的非叶子节点进行比较,自底向上
for(int i = len/2; i >= 0; -- i){
maxHeapify(nums, i, len);
}
}
public void maxHeapify(int[] nums, int i, int len) {
while( (i<<1) + 1 <= len ) {
int lson = (i<<1) + 1;
int rson = (i<<1) + 2;
int large = i;
if(lson <= len && nums[i] < nums[lson]) {
large = lson;
}
if(rson <= len && nums[large] < nums[rson]) {
large = rson;
}
if(large == i) break;
swap(nums, i, large);
i = large;
}
}
public void swap(int[] nums, int x, int y) {
int tmp = nums[x];
nums[x] = nums[y];
nums[y] = tmp;
}
}
4.2 go
func sortArray(nums []int) []int {
heapSort(nums)
return nums
}
func heapSort(nums []int) {
len := len(nums)-1
buildMaxHep(nums, len)
for i := len; i >= 1; i -- {
swap(nums, i, 0)
len --;
maxHeapify(nums, 0, len);
}
}
func buildMaxHep(nums []int, len int) {
for i := len/2; i >= 0; i -- {
maxHeapify(nums, i, len);
}
}
func maxHeapify(nums []int, i int, len int) {
for (i<<1) + 1 <= len {
lson := (i<<1) + 1
rson := (i<<1) + 2
large := i
if lson <= len && nums[i] < nums[lson] {
large = lson
}
if rson <= len && nums[large] < nums[rson] {
large = rson
}
if i == large {
break
}
swap(nums, i, large)
i = large
}
}
func swap(nums []int, i int, j int) {
tmp := nums[i]
nums[i] = nums[j]
nums[j] = tmp
}
4.3 时空复杂度
时间复杂度:O(nlogn)
空间复杂度:O(1)
5. 归并排序
5.1 java
class Solution {
int[] tmp;
public int[] sortArray(int[] nums) {
tmp = new int[nums.length];
mergeSort(nums, 0, nums.length - 1);
return nums;
}
public void mergeSort(int[] nums, int left, int right) {
if (left >= right) return;
int mid = left + (right - left) / 2;
mergeSort(nums, left, mid);
mergeSort(nums, mid + 1, right);
int idx = 0;
int i = left, j = mid + 1;
while(i <= mid && j <= right) {
if(nums[i] < nums[j]) {
tmp[idx++] = nums[i++];
} else {
tmp[idx++] = nums[j++];
}
}
while(i<=mid){
tmp[idx++] = nums[i++];
}
while(j<=right) {
tmp[idx++] = nums[j++];
}
idx = 0;
for(int k = left; k <= right; ++ k) {
nums[k] = tmp[idx++];
}
}
}
5.2 go
var tmp []int
func sortArray(nums []int) []int {
tmp = make([]int, len(nums))
mergeSort(nums, 0, len(nums)-1)
return nums
}
func mergeSort(nums []int, left int, right int) {
if left >= right {
return
}
mid := left + (right-left)/2
mergeSort(nums, left, mid)
mergeSort(nums, mid+1, right)
i := left
j := mid + 1
idx := 0
for i <= mid && j <= right {
if nums[i] < nums[j] {
tmp[idx] = nums[i]
idx++
i ++
} else {
tmp[idx] = nums[j]
idx ++
j ++
}
}
for i <= mid {
tmp[idx] = nums[i]
idx ++
i ++
}
for j <= right {
tmp[idx] = nums[j]
idx ++
j ++
}
idx = 0
for k := left; k <= right; k ++ {
nums[k] = tmp[idx]
idx ++
}
}
5.3 时空复杂度
时间复杂度:O(nlogn)
空间复杂度:O(n)
6. 冒泡排序
6.1 java
class Solution {
public int[] sortArray(int[] nums) {
int n = nums.length;
for(int i = 0; i < n; ++ i){
for(int j = 0; j < n-i-1; ++ j) {
if(nums[j] > nums[j + 1]) {
swap(nums, j, j+1);
}
}
}
return nums;
}
public void swap(int[] nums, int x, int y) {
int tmp = nums[x];
nums[x] = nums[y];
nums[y] = tmp;
}
}
6.2 go
func sortArray(nums []int) []int {
n := len(nums)
for i := 0; i < n; i ++ {
for j := 0; j < n-i-1; j ++ {
if nums[j] > nums[j+1] {
swap(nums, j, j+1)
}
}
}
return nums
}
func swap(nums []int, x int, y int) {
tmp := nums[x]
nums[x] = nums[y]
nums[y] = tmp
}
6.3 时空复杂度
时间复杂度:O(n^2)
空间复杂度:O(1)
7. 计数排序
7.1 java
class Solution {
public int[] sortArray(int[] nums) {
int min = nums[0], max = nums[0];
int n = nums.length;
for(int i = 0; i < n; ++ i) {
min = Math.min(min, nums[i]);
max = Math.max(max, nums[i]);
}
int len = max - min + 1;
int[] cnt = new int[len];
for(int num : nums) {
cnt[num-min] ++;
}
int idx = 0;
for(int i = 0; i < len; ++ i) {
for(int j = cnt[i]; j > 0; j--) {
nums[idx++] = i + min;
}
}
return nums;
}
}
7.2 go
func Max(a,b int) int {
if a>b{
return a
}
return b
}
func Min(a,b int) int {
if a>b{
return b
}
return a
}
func sortArray(nums []int) []int {
maxs:=nums[0]
mins:=nums[0]
for _,v := range(nums){
maxs=Max(maxs,v)
mins=Min(mins,v)
}
cnts:=make([]int,maxs-mins+1)
for _,v :=range(nums){
cnts[v-mins]+=1
}
cnt:=0
for i,j :=range(cnts){
for ;j>0;j--{
nums[cnt]=i+mins
cnt+=1
}
}
return nums
}
7.3 时空复杂度
时间复杂度:O(n) n表示最小值到最大值的取值范围
空间复杂度:O(n) n表示最小值到最大值的取值范围