排序算法思想

这篇博客详细介绍了各种排序算法,包括冒泡排序、选择排序、插入排序这些O(n^2)级别的算法,然后逐步过渡到效率更高的O(nlogn)算法,如堆排序、归并排序(重点讲解)、希尔排序和快速排序。最后,作者提到了线性时间复杂度的O(n)排序算法,如桶排序、基数排序和计数排序。
摘要由CSDN通过智能技术生成

不是吧?o(n^2)的算法你也要讲?

1.冒泡排序

辅助记忆:
i∈[0,N-1) // 循环N-1遍
j∈[0,N-1-i) // 每遍循环要处理的无序部分
swap(j,j+1) // 两两排序(升序/降序)


// c++
void bubble_sort(T arr[], int len) {
   
	int i, j;
	for (i = 0; i < len - 1; i++)
		for (j = 0; j < len - 1 - i; j++)
			if (arr[j] > arr[j + 1])
				swap(arr[j], arr[j + 1]);
}

2.选择排序

  1. 把当前位置记作最小
  2. 扫描后面所有数,找到最小下标
  3. 交换最小值与当前值的位置
// c++
void selection_sort(std::vector<T>& arr) {
   
	for (int i = 0; i < arr.size() - 1; i++) {
   
		int min = i;
		for (int j = i + 1; j < arr.size(); j++)
			if (arr[j] < arr[min])
				min = j;
		std::swap(arr[i], arr[min]);
	}
}

3.插入排序(我最喜欢的n^2算法)

  1. 你想象一个序列
  2. 找到最小的,放在第一位
  3. 找到次小的,放在第二位,以此类推
void insert_sort(std::vector<T>& arr) {
   
	for (int i = 0; i < arr.size(); i++) {
   
		for (int j = i + 1; j < arr.size()-1; j++) {
   
			std::swap(arr[i], arr[j]);
		}
	}	
}

我终于可以讲o(nlogn)的了

// 以下算法均使用 Java 与 c++编写

1.堆排序

// java
package 数据结构与算法;

import java.util.Arrays;

// 堆的性质
// 大顶堆:父节点 > 子节点
// 小顶堆:父节点 < 子节点 

// 升序排列大顶堆
// 降序排列小顶堆
// 联想堆排序,快排?
public class 树_堆结构 {
   
	// 测试
	public static void main(String[] args) {
   
		int[] arr = {
    9, 6, 8, 7, 0, 1, 10, 4, 2 };

		int start = (arr.length - 1) / 2;
		heapSort(arr);
		System.out.println(Arrays.toString(arr));
	}
	// 堆排序, 这里我默认大顶堆 & 当然你可以通过继承来写
	public static void heapSort(int[] arr) {
   
		// 开始位置是最后一个非叶子节点, 即最后一个节点的父节点
		int start = (arr.length - 1) / 2;
		// 调整为大顶堆
		for (int i = start; i >= 0; i--) {
   
			maxHeap(arr, arr.length, i);
		}
		// 把数组中第0个和堆中最后一个数交换位置, 再把前面的调整为大顶堆
		for (int i = arr.length - 1; i > 0; i--) {
   
			// swap
			int temp = arr[0];
			arr[0] = arr[i];
			arr[i] = temp;
			maxHeap(arr, i, 0);
		}
	}
	/**
		1. 由数组构建大小顶堆(树)
		2. 很简单 : 左子节点取 2*index + 1 右子节点取 2*index + 2
	*/
	// 大顶堆
	public static void maxHeap(int[] arr, int size, int index) {
   
		// 左子节点
		int leftNode = 2 * index + 1;
		// 右子节点
		int rightNode = 2 * index + 2;
		int max = index;
		// 和两个节点对比找出最大的节点
		if (leftNode < size && arr[leftNode] > arr[max]) {
   
			max = leftNode;
		}
		if (rightNode < size && arr[rightNode] > arr[max]) {
   
			max = rightNode;
		}

		// 交换位置 swap
		if (max != index) {
   
			int temp = arr[index];
			arr[index] = arr[max];
			arr[max] = temp;
			// 交换后可能会排好的堆 !注意max
			maxHeap(arr, size, max);
		}
	}
	
	// 小顶堆
	public static void minHeap(int[] arr, int size, int index) {
   

		// 左子节点
		int leftNode = 2 * index + 1;

		// 右子节点
		int rightNode = 2 * index + 2;
		int min = index;
		// 和两个节点对比找出最大的节点
		if (leftNode < size && arr[leftNode] < arr[min]) {
   
			min = leftNode;
		}

		if (rightNode < size && arr[rightNode] < arr[min]) {
   
			min = rightNode;
		}

		// 交换位置 swap
		if (min != index) {
   
			int temp = arr[index];
			arr[index] = arr[min];
			arr[min] = temp;
			// 交换后可能会排好的堆 !注意min
			minHeap(arr, size, min);
		}
	}
	
	// 闲得没事干的重写
	public static void minHeap(int p, int[] arr
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值