插入排序

直接插入

void insertSort(vector<int>& nums) {
	for (int i = 1; i < nums.size(); ++i) {
		int j = i;
		while (j >= 1 && nums[j] < nums[j - 1]) {
			swap(nums[j], nums[j - 1]);
			--j;
		}
	}
}

折半插入

void binaryInsertSort(vector<int>& nums) {
	for (int i = 1; i < nums.size(); ++i) {
		int key = nums[i];
		int low = 0, high = i - 1;
		while (low <= high) {
			int mid = low + (high - low) / 2;
			if (nums[mid] >= key) {
				high = mid - 1;
			}
			else {
				low = mid + 1;
			}
		}
		for (int k = i - 1; k >= low; --k)  {
			nums[k + 1] = nums[k];
		}
		nums[low] = key;
	}
}

希尔排序

void shellSort(vector<int>& nums) {
	int n = nums.size();
	for (int dk = n / 2; dk >= 1; dk /= 2) {
		for (int i = dk; i < n; ++i) {
			int j = i;
			while (j >= dk && nums[j] < nums[j - dk]) {
				swap(nums[j], nums[j - dk]);
				j -= dk;
			}
		}
	}
}

冒泡排序

void bubbleSort(vector<int>& nums) {
	for (int i = nums.size() - 1; i > 0; --i) {
		for (int j = 0; j < i; ++j) {
			if (nums[j] > nums[j + 1]) {
				swap(nums[j], nums[j + 1]);
			}
		}
	}
}

快速排序

int partition(vector<int>& nums, int left, int right) {
    // 设定随机pivot
	int randIdx = rand() % (right - left + 1) + left;
	swap(nums[left], nums[randIdx]);
	int pivot = nums[left];
	while (left < right) {
		while (left < right && nums[right] >= pivot) --right;
		nums[left] = nums[right];
		while (left < right && nums[left] <= pivot) ++left;
		nums[right] = nums[left];
	}
	nums[left] = pivot;
	return left;
}

void recurSort(vector<int>& nums, int left, int right) {
	if (left > right) return;
	int p = partition(nums, left, right);
	recurSort(nums, left, p - 1);
	recurSort(nums, p + 1, right);
}

void quickSort(vector<int>& nums) {
	srand((unsigned)time(nullptr));
	recurSort(nums, 0, nums.size() - 1);
}

简单选择排序

void selectSort(vector<int>& nums) {
	for (int i = 0; i < nums.size(); ++i) {
		int minIdx = i;
		for (int j = i + 1; j < nums.size(); ++j) {
			if (nums[minIdx] > nums[j]) {
				minIdx = j;
			}
		}
		swap(nums[i], nums[minIdx]);
	}
}

堆排序

void headAjust(vector<int>& nums, int i, int len) {
	while (i * 2 + 1 <= len) {
		int left = i * 2 + 1, right = i * 2 + 2;
		int largest = i;
		if (left <= len && nums[left] > nums[i]) {
			largest = left;
		}
		if (right <= len && nums[right] > nums[largest]) {
			largest = right;
		}
		if (largest == i) break;
		swap(nums[i], nums[largest]);
		i = largest;
	}
}

void heapSort(vector<int>& nums) {
    // 构建最大堆
	int len = nums.size() - 1;
	for (int i = len / 2; i >= 0; --i) {
		headAjust(nums, i, len);
	}
	for (int i = len; i > 0; --i) {
		swap(nums[i], nums[0]);
		headAjust(nums, 0, --len);
	}
}

归并排序

void merge(vector<int>& nums, int low, int mid, int high) {
	vector<int> numsCpy(high - low + 1);
	int p1 = low, p2 = mid + 1, p3 = 0;
	while (p1 <= mid && p2 <= high) {
		if (nums[p1] <= nums[p2]) {
			numsCpy[p3++] = nums[p1++];
		}
		else {
			numsCpy[p3++] = nums[p2++];
		}
	}
	while (p1 <= mid) numsCpy[p3++] = nums[p1++];
	while (p2 <= high) numsCpy[p3++] = nums[p2++];
	for (int i = 0; i < numsCpy.size(); ++i) {
		nums[low++] = numsCpy[i];
	}
}

void recurSort(vector<int>& nums, int low, int high) {
	if (low >= high) return;
	int mid = low + (high - low) / 2;
	recurSort(nums, low, mid);
	recurSort(nums, mid + 1, high);
	merge(nums, low, mid, high);
}

void mergeSort(vector<int>& nums) {
	recurSort(nums, 0, nums.size() - 1);
}

基数排序

// 本排序算法仅适用于整数排序
void countingSort(vector<int>& nums, int exp) {
	int n = nums.size();
	vector<int> output(n);
	vector<int> count(10, 0);
	for (int i = 0; i < n; ++i) {
		int digit = (nums[i] / exp) % 10;
		++count[digit];
	}
	for (int i = 1; i < 10; ++i) {
		count[i] += count[i - 1];
	}
	for (int i = n - 1; i >= 0; --i) {
		int digit = (nums[i] / exp) % 10;
		output[count[digit] - 1] = nums[i];
		--count[digit];
	}
	for (int i = 0; i < n; ++i) {
		nums[i] = output[i];
	}
}

void radixSort(vector<int>& nums) {
	int n = nums.size();
	vector<int> positiveNums;
	vector<int> negativeNums;
	for (int i = 0; i < n; ++i) {
		if (nums[i] >= 0) {
			positiveNums.emplace_back(nums[i]);
		}
		else {
			negativeNums.emplace_back(-1 * nums[i]);
		}
	}
	if (!positiveNums.empty()) {
		int maxVal = *max_element(positiveNums.begin(), positiveNums.end());
		for (int exp = 1; maxVal / exp > 0; exp *= 10) {
			countingSort(positiveNums, exp);
		}
	}
	if (!negativeNums.empty()) {
		int maxVal = *max_element(negativeNums.begin(), negativeNums.end());
		for (int exp = 1; maxVal / exp > 0; exp *= 10) {
			countingSort(negativeNums, exp);
		}
	}
	for (int i = 0; i < n; ++i) {
		if (i < negativeNums.size()) {
			nums[i] = -1 * negativeNums[negativeNums.size() - i - 1];
		}
		else {
			nums[i] = positiveNums[i - negativeNums.size()];
		}
	}
}