数据结构与算法学习| 青训营笔记

81 阅读2分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的的第1篇笔记。

经典排序算法

插入排序

思想:把 n 个待排序的元素看成为一个有序表和一个无序表,开始时有序表中只包含一个元素,无序表中包含有 n-1 个元素,排序过程中每次从无序表中取出第一个元素,把它的排序码依次与有序表元素的排序码进行比较,将它插入到有序表中的适当位置,使之成为新的有序表。

缺点:平均和最坏情况的时间复杂度高达O(n^2)

优点:最好情况时间复杂度为O(n)

代码如下

package main                                                                                                                                                                                                                                

import (                                                                                                                  
 "fmt"                                                                                                             
)                                                                                                                                                                                                                                           
func insertionSort(num []int) {                                                                                              
 for i := 1; i < len(num); i++ {                                                                                           
 	for j := i; j > 0; j-- {                                                                                                  
 		if (num[j] < num[j-1]) {                                                                                                  
 			num[j], num[j - 1] = num[j - 1], num[j]                                                                           
 		} else if (num[j] > num[j - 1]) {                                                                                         
 			break
         }                                                                                                                 
     }                                                                                                                 
 }                                                                                                                 
}                                                                                                                                                                                                                                           
func main() {                                                                                                             
 a := [...] int {1,84,25,48,74,2,94,51,58,51,65,47}                                                          
 insertionSort(a[:])                                                                                                      
 fmt.Println(a)                                                                                                    
}                

快速排序

快速排序是一种划分交换排序,采用了分治的策略(通常称为分治法),基本思想是:

  1. 数据集中,选取一个元素作为'基准'(pivot)。
  2. 所有小于'基准'的元素,都移到'基准'的左边;所有大于'基准'的元素,都移到'基准'的右边。
  3. 对'基准'左边和右边的两个子集,不断重复第一步和第二步,直到所有子集只剩下一个元素为止。

代码如下


package main
 
import (
	"fmt"
)
 
func QuickSort(arr []int) {
	size := len(arr)
	quickSortUtil(arr, 0, size-1)
}
 
func quickSortUtil(arr []int, lower int, upper int) {
	if upper <= lower {
		return
	}
	pivot := arr[lower]
	start := lower
	stop := upper
	for lower < upper {
		for arr[lower] <= pivot && lower < upper {
			lower++
		}
		for arr[upper] > pivot && lower <= upper {
			upper--
		}
		if lower < upper {
			swap(arr, upper, lower)
		}
	}
	swap(arr, upper, start)            
	quickSortUtil(arr, start, upper-1) 
	quickSortUtil(arr, upper+1, stop)  
}
func swap(arr []int, first int, second int) {
	arr[first], arr[second] = arr[second], arr[first]
}
func main() {
	data := []int{9, 2, 5, 1, 7, 3, 6, 4, 8}
	QuickSort(data)
	fmt.Println(data)
}

堆排

利用堆的性质形成的排序方法

  1. 构造一个大根堆
  2. 将根节点(最大元素)交换到最后一个位置,调整整个堆,如此反复
package main

import "fmt"


func HeapSort(cha1n chan<-[]int, nums []int) {
	Hepify(nums, len(nums)) 	
	for i := len(nums) - 1; i >= 0; i-- {
		nums[i],nums[0] = nums[0],nums[i]		
		Hepify(nums, i) 
	}

	cha1n<-nums
}

func Hepify(nums []int, unsortCapacity int) {
	for i := (unsortCapacity / 2) - 1; i >= 0; i-- {		
		leftIndex  := 2*i + 1
		if leftIndex < unsortCapacity && nums[i] < nums[leftIndex] {
			nums[i],nums[leftIndex] = nums[leftIndex], nums[i]		
		} 
		rightIndex := 2*i + 2
		if rightIndex < unsortCapacity && nums[i] < nums[rightIndex] {
			nums[i],nums[rightIndex] = nums[rightIndex], nums[i]	
		}
	}
}
func main() {
	defer fmt.Println("heap sort complete")
	cha1n := make(chan []int)
	var array = []int{10, 2, 7, 9, 4, 11}
	go HeapSort(cha1n, array)
	fmt.Println(<-cha1n)
}

总结

在学习中 我了解到算法的重要,以后的学习算法的过程中不仅只是看理论 要着重于写。在设计算法的时候要根据不同情况选择不同的策略,取长补短。