排序算法整理

常见排序算法详解

整理一下常见的排序算法。

  • 插入排序
  • 合并排序
  • 冒泡排序
  • 堆排序
  • 快速排序
  • 选择排序

插入排序

插入排序就是从前往后,逐个元素向自己前方插入,保持从0位到检索位的元素有序,直到遍历至最后一个元素。

C++实现:

void InsertSort(int* A, int n)
{
	for (int i = 2;i < n;i++){
		int curr = A[i];
		int j = i-1;
		while (j > 0&&A[j] > curr){
			A[j+1] = A[j];
			j--;
		}
		A[j+1] = curr;
	}
}

算法复杂度:O\left ( n^2 \right )


合并排序

也叫归并排序,就是将要排序的数组分为多个子序列,让每个子序列有序,然后再把子序列合并。

C++实现:

void MergeSort(int* A, int begin, int end)
{
	int size = end - begin + 1;
	if (begin == end){
		return;
	}
	int mid = begin + size / 2;
	MergeSort(A, begin, mid-1);
	MergeSort(A, mid, end);
	int temp[size];
	int j1 = begin;
	int j2 = mid;
	for (int i = 0;i < size;i++){
		temp[i] = (j2 > end||(j1 < mid&&A[j1]<A[j2]))?A[j1++]:A[j2++]; 
	}
	for (int i = 0;i < size;i++){
		A[begin+i] = temp[i];
	}
}

算法时间复杂度:O\left (n \log n \right )


冒泡排序

每个数字像是冒泡一样,慢慢地向上冒。每次遍历数组,检查当前位和后一位的大小,如果顺序不对,则交换位次。当一次遍历中没有发生交换,代表排序结束。

C++实现:

void BubbleSort(int* A, int n)
{
	bool adjust = true;
	while (adjust){
		adjust = false;
		for (int i = 0;i < n-1;i++){
			if (A[i] > A[i+1]){
				int temp = A[i];
				A[i] = A[i+1];
				A[i+1] = temp;
				adjust = true;
			}
		}
	}
}

算法时间复杂度:O\left ( n^2 \right )


堆排序

堆排序就是使用大根堆(或小根堆)进行排序。大根堆是一棵完全二叉树,每个父节点的值都不小于其两个子节点。大根堆使用数组进行存储,节点n的左节点为2n+1,右节点为左节点+1。排序过程为,首先把A[1-n]初始化为大根堆,然后把A[1](堆顶,最大的元素)与A[n]交换。然后再把A[1-(n-1)]维护为大根堆。重复至大根堆大小减为1.

C++实现:

void HeapSort(int* A, int n)
{
	for (int i = n-1;i >= 0;i--){
		MaxHeapify(A, n, i);
	}
	
	for (int i = n-1;i > 0;i--){
		int temp = A[i];
		A[i] = A[0];
		A[0] = temp;
		MaxHeapify(A, i, 0);
	}
}

void MaxHeapify(int* A, int n, int pos)
{
	int lchild = pos*2+1;
	int rchild = lchild+1;
	if (rchild < n){
		if (A[pos] >= A[lchild]&&A[pos] >= A[rchild]){
			return;
		}
		else if (A[lchild] >= A[rchild]){
			int temp = A[pos];
			A[pos] = A[lchild];
			A[lchild] = temp;
			MaxHeapify(A, n, lchild);
		}
		else {
			int temp = A[pos];
			A[pos] = A[rchild];
			A[rchild] = temp;
			MaxHeapify(A, n, rchild);
		}
	}
	else if (lchild < n){
		if (A[pos] <= A[lchild]){
			int temp = A[pos];
			A[pos] = A[lchild];
			A[lchild] = temp;
			MaxHeapify(A, n, lchild);
		}
	}
	return;
}

算法时间复杂度:O\left ( n \log n \right )


快速排序

快排的思路是不断地通过一个基准值(通常是序列第一位)将序列分为比基准值大和比基准值小的两部分。然后再把子序列按同样方法处理,直到子序列大小为1.

C++实现:

void QuickSort(int* A, int begin, int end)
{
	if (begin >= end){
		return;
	}
	int l = begin+1, r = end;
	while(l < r){
		while(A[r]>=A[begin]&&l<r){
			r--;
		}
		while(A[l]<A[begin]&&l<r){
			l++;
		}
		swap(A[l], A[r]);
	}
	if (A[r] < A[begin]){
		swap(A[r], A[begin]);
	}
	else {
		r--;
	}
	QuickSort(A, begin, r-1);
	QuickSort(A, r+1, end);
}

算法时间复杂度:O(n\log n)


选择排序

选择排序就是每次从无序区遍历查出最小(大)的元素,放在有序区的末尾(首部)。(我感觉很脑残……)

C++实现:

void SelectSort(int* A, int n)
{
	for (int i = 0;i < n-1;i++){
		int min = A[i];
		int min_pos = i;
		for (int j = i+1;j < n;j++){
			if (A[j] < min){
				min_pos = j;
				min = A[j];
			}
		}
		swap(A[i], A[min_pos]);
	}
}

算法时间复杂度:O\left ( n^{2} \right )

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值