简单排序:插入排序、选择排序、
冒泡排序 分治排序:快速排序、归并排序
分配排序:桶排序、基数排序
树状排序:堆排序
其他:计数排序、希尔排序
稳定排序:如果 a 原本在 b 的前面,且 a == b,排序之后 a 仍然在 b 的前面,则为稳定排序。
非稳定排序:如果 a 原本在 b 的前面,且 a == b,排序之后 a 可能不在 b 的前面,则为非稳定排序。
原地排序:原地排序就是指在排序过程中不申请多余的存储空间,只利用原来存储待排数据的存储空间进行比较和交换的数据排序。
非原地排序:需要利用额外的数组来辅助排序。
时间复杂度:一个算法执行所消耗的时间。
空间复杂度:运行完一个算法所需的内存大小。
/** insertSort * 插入排序法 * @param arr * @return */
func insertSort(arr []int) {// //判断数组是否为空或者长度是否大于2if len(arr) < 2 {return}//循环遍历数组for i := 1; i < len(arr); i++ {//定义变量保存要插入的值tem := arr[i]k := i - 1for k >= 0 && arr[k] > tem {arr[k+1] = arr[k]k--}//元素插入arr[k+1] = tem}return
}// selectSort 选择排序 时间复杂度可能很高
func selectSort(arr []int) {n := len(arr)for i := 0; i < n-1; i++ {m := ifor j := i + 1; j < n; j++ {if arr[m] > arr[j] {m = j}}//交换temp := arr[i]arr[i] = arr[m]arr[m] = temp}
}// bubbleSort 冒泡排序算法
func bubbleSort(arr []int) {if len(arr) < 2 {return}flag := true//加一个标志位,记录上一次是否发生了交换,如果是,我们则进行下一轮,如果没有,说明已经冒泡好了for i := 1; i < len(arr) && flag; i++ {//控制次数,第几趟排序,只需要n-1趟,有交换时进行,只有flag=false就说明上一次一个元素都没有进行交换flag = false//假定未交换for j := 0; j < len(arr)-i; j++ {if arr[j] > arr[j+1] {temp := arr[j]arr[j] = arr[j+1]arr[j+1] = tempflag = true}}}
}// quickSort 快速排序算法
func quickSort(arr []int, left, right int) []int {if left < right {//获取基点元素所处的位置mid := partition(arr, left, right)//进行分割arr = quickSort(arr, left, mid-1)arr = quickSort(arr, mid+1, right)}return arr
}
func partition(arr []int, left, right int) int {//选取基点元素pivot := arr[left]i := left + 1j := rightfor {// 向右找到第一个小于等于 pivot 的元素位置for i <= j && arr[i] <= pivot {i++}// 向左找到第一个大于等于 pivot 的元素位置for i <= j && arr[j] >= pivot {j--}if i >= j {break}//交换两个元素的位置,使得左边的元素不大于pivot,右边的不小于pivottemp := arr[i]arr[i] = arr[j]arr[j] = temp}arr[left] = arr[j]// 使中轴元素处于有序的位置arr[j] = pivotreturn j
}// 堆排序
func heapSort(arr []int) {//1.构建大顶堆for i := len(arr)/2 - 1; i >= 0; i-- {//从第一个非叶子结点从下至上,从右至左调整结构sift(arr, i, len(arr))}//2.调整堆结构+交换堆顶元素与末尾元素for i := len(arr) - 1; i > 0; i-- {//现在的数组第一个就是根结点,最小值所在,进行交换,把它放到最右边temp := arr[i]arr[i] = arr[0]arr[0] = temp//重新建立堆sift(arr, 0, i)//重新对堆进行调整}
}/**建立堆的方法私有方法,只允许被堆排序调用@param arr 要排序数组@param parent 当前的双亲节点@param len 数组长度*/
func sift(arr []int, parent, len int) {value := arr[parent]//先取出当前元素ifor child := 2*parent + 1; child < len; child = child*2 + 1 {//从parent结点的左子结点开始,也就是2*parent+1处开始if child+1 < len && (arr[child] < arr[child+1]) {//如果左子结点小于右子结点,child指向右子结点child++//右孩子如果比左孩子大,我们就将现在的孩子换到右孩子}//判断是否符合大顶堆的特性, 如果右孩子大于双亲,自然左孩子也大于双亲,符合//如果子节点大于父节点,将子节点值赋给父节点(不用进行交换)if value < arr[child] {arr[parent] = arr[child]parent = child} else {//如果不是,说明已经符合我们的要求了。break}}arr[parent] = value//将value值放到最终的位置
}