最近身边的朋友都在聊算法,突然想把几个大学接触到的排序算法思路整理一下(大学那会儿只能理解,还没办法编程实现)。
- 快速排序算法gim
通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
1.设定两个指针变量(下标为0,length-1),指向数组左右两边,且数组一个值作为指标(划分左右的参照)
2.从右边high指向的值和tmp比较,high小则值复制给low,low向前移一位,且一下次从low位置开始比较,大于等于则high指针向左移一位,继续比较
3.此时比较low指针和指标的大小,如果low指向值大于指标值(23),将low复制给high指向值,high向左移一位。如果low指向值小于指标值(23),low向右移动一位。直到low=high,将指标值赋给low指向的数组下标。结束一次的排序
4.一次排序过后,会出现以指标值为基准,左边小于指标值,右边大于指标值(左右两边为无序,需要递归排序)
实现代码:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class QuickSort {
public static void main(String[] args) {
int[] nums = {55,34,45,76,87,45,23,23,45,3,23,2,2,2,34,56,7,8,90,54,3,98,4,2,223,5,54,223};
System.out.println("begin :nums:" + Arrays.toString(nums));
//第一次排序取整个数组,下标从0到数组最后
nums = quickSort(nums,0 , nums.length - 1);
System.out.println(" end :nums:" + Arrays.toString(nums));
}
/**
* desc:快速排序
* @param nums
* @return
*/
public static int[] quickSort(int[] nums, int low, int high){
//当要排序的数组左下标和又下标重合时,表示长度为1,不做排序
if(low >= high)
return nums;
int low_ = low , high_ = high;
//将数组第一位作为临时变量(即划分左小又大的对比指标)
int tmp = nums[low];
//控制和指标对比的元素索引方向(low or high)
boolean isLeft = false;
//下标重合时,退出比较
while(low < high){
//数组左边和指标的大小比较
if(isLeft){
//数组左指针指向的值小于指标值,指针向后移一位,继续比较
if(nums[low] < tmp){
low ++;
continue;
}else{
//左指针值大于指标值,复制到右指针的位置,然后改变方向从比较指标右边的值
nums[high--] = nums[low];
isLeft = !isLeft;
continue;
}
}else{//数组右边和指标的大小比较
//右指针值大于指标值,右指针向左移动一位
if(nums[high] >= tmp){
high --;
continue;
}else{//右指针小于指标值,将右指针值复制给左指针,并改变方向,比较指标左边部分的值
nums[low] = nums[high];
isLeft = !isLeft;
continue;
}
}
}
//比较完后发现low下标对应的值有重复,将指标值复制给low对应的下标
nums[low] = tmp;
//第一次排序后,以指标为基准,左小右大(左右部分无序,需要在排序)
//当左边的数组大于2个数的时候,对左边进行递归排序
if(low > 2){
//对数组的最左边到指标左边一位部分进行递归排序(指标左边部分的排序)
quickSort(nums,low_ , low - 1);
}
if(low < nums.length - 2){
//对指标右边一位到数组最右边部分进行递归排序(指标右边部分的排序)
quickSort(nums,low + 1,high_);
}
return nums;
}
}
- 选择排序
选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到全部待排序的数据元素排完。 选择排序是不稳定的排序方法
1.指针(index)指向数组最左边,将指针指向元素和index+1元素一次进行比较,如果元素小于指针元素,互换位置(5比31小互换位置)
2.比较比较元素小标右移动(下标+1),和指针(index)继续比较,小于指针元素的互换位置,一轮比较之后,会出现一个最小值为指针指向值,指针右移一位(index+1),进入下一轮指针和其右边的数组大小比较。
3.当指针执行数组最后一个元素时,排序结束
代码实现:
package com.lirong.sort;
import java.util.Arrays;
/**
* desc:SelectionSort
* author:lirong
* data:2019/05/09
*/
public class SelectionSort {
public static void main(String[] args) {
int[] nums = {12,34,34,4554,76,7688,45,34,234,232,342,3,23,12,1223,324,432,2};
System.out.println("begin:" + Arrays.toString(nums));
selectionSort(nums);
System.out.println("end:" + Arrays.toString(nums));
}
/**
* desc:选择排序
* @return
*/
public static int[] selectionSort(int[] nums){
//指针第一次指向数组最左边边元素
int index = 0, tmp ;
//当指针移动到数组最右边,排序结束
while(index < nums.length - 1){
//遍历指针右边的元素,比指针指向的元素小的,互换位置,每次遍历完,指针向左移一位
for(int i = index + 1 ; i < nums.length ; i++){
if(nums[index] > nums[i]){
tmp = nums[i];
nums[i] = nums[index];
nums[index] = tmp;
}
}
//每次遍历之后,会出现一个最小的元素
index ++;
}
return nums;
}
}
三、冒泡排序
它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果他们的顺序(如从大到小、首字母从A到Z)错误就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素列已经排序完成
- 指针指向数组最后一个元素,让其与前一个元素比较。如果前一个元素大于指针元素,则交换位置。否则指针向前移一位(3比8小,不做交换)
- 指针向前移一位,继续做比较(71比3大,互换位置)
- 以此比较下去,最后出现在数组最左边会是一个最小的元素(如图)
- 进入第二轮比较,指针仍旧从最末尾开始比较(此时比较到左边第二个元素时停止(因为最左边元素(既下标为0的元素) 已经是数组中最小的,不需要比较了))。
Ps:当从右到左一轮比较下来,都没有发生过数据交换,说明数组已经是有序的,直接推出排序即可.
插入排序
思想:将索引指向的值与前面已经有序的值进行比较(从最右边,最大的值开始)。如果该值比索引值大,将他赋值给他后一位值,对比值向左移一位。直到对比的值小于索引值,将索引值赋值给对比值的上一位(上一位已经赋值给了他的再上一位)。
示例:
1,。索引刚开始指向下标为1的,从索引左边数组最右边(下标设为j)开始比较(第一次左边数组只有一个元素,将索引值(3)存入tmp)==如果对比值大,对比值赋值给他的后一位。然后对比值下标减一(第一次j=0,减一后为-1,结束循环)。然后将tmp的值赋给j+1
- 此时数组如图2.索引右移一位,指向2,开始新一轮的比较(此时j=1,如图3).比较索引值tmp(2)和j=1的值(7),对比值大,将对比值赋值给他后一位,如图4。
- 对比值下标减一,继续比较(3>tmp=2),将对比值(3)赋值给他后一位,如图5.
- 对比值下标减一(此时j--=-1<0),结束循环.
- 最后将tmp赋值给j++=0
- 一轮插入结束,索引值向右移一位,继续比较
代码实现:
package com.lirong.sort;
import java.util.Arrays;
/**
* author:lirong
* data:2019/5/14
* desc:insertion soort
*/
public class InsertionSort {
public static void main(String[] args) {
int[] nums = {55,34,45,76,87,45,23,23,45,3,23,2,2,2,34,56,7,8,90,54,3,98,4,2,223,5,54,223};
System.out.println("begin :nums:" + Arrays.toString(nums));
//第一次排序取整个数组,下标从0到数组最后
nums = insertionSort(nums);
System.out.println(" end :nums:" + Arrays.toString(nums));
}
/**
* desc:插入排序
* @param nums
* @return
*/
public static int[] insertionSort(int[] nums){
for(int index = 1 ; index < nums.length ; index++){
//保存索引值
int tmp = nums[index];
//比较值从索引值左边第一个开始
int j = index - 1;
for(; j >= 0; j--){
//当比较值大于索引值,将比较值赋值给比较值后一直
if(nums[j] > tmp){
nums[j+1] = nums[j];
}else{//当检索到比索引值小的元素的时候,将索引值放到比较值后一位(即j+1的位置)
break;
}
}
nums[j + 1] = tmp;
}
return nums;
}
}