学习目标:
列举了几种常见的排序算法选择排序:
// 选择排序
void SelectSort(int arr[], int len) {
for (int i = 0; i < len - 1; i++) {
int min = i; //记录最小值
for (int j = i + 1; j < len; j++) {
if (arr[min] > arr[j]) {
min = j;
}
}
if (min != i) {
swap(arr[min], arr[i]);
}
}
}
冒泡排序:
第一种写法:
void BubbleSort(int arr[], int len) {
for (int i = 0; i < len - 1; i++) {
bool flag = false; //标志
for (int j = len - 1; j > i; j--) {
if (arr[j - 1] > arr[j]) {
swap(arr[j - 1], arr[j]);
flag = true;
}
}
if (flag == false) //没有交换,则已完成排序
return;
}
}
第二种写法:
void BubbleSort(int arr[], int len) {
for (int i = 0; i < len - 1; i++) {
bool flag = false;
for (int j = 0; j < len - 1 - i; j++) { // 已排好序的
if (arr[j] > arr[j + 1]) {
swap(arr[j], arr[j + 1]);
flag = true;
}
}
if (flag == false)
return;
}
}
插入排序
不带哨兵
void InsertSort(int arr[], int len) {
for (int i = 1; i < len; i++) {
if (arr[i - 1] > arr[i]) {
int temp = arr[i];
int j = i - 1;
for (j; j >= 0 && arr[j] > temp; j--) {
arr[j + 1] = arr[j];
}
arr[j + 1] = temp; //
}
}
}
带哨兵
void InsertSort1(int arr[], int len) {
for (int i = 2; i <= len-1; i++) {
if (arr[i - 1] > arr[i]) {
arr[0] = arr[i]; //第一个元素当哨兵
int j = i - 1;
for (j; arr[j] > arr[0]; j--) { //不用每轮循环都判断j>=0
arr[j + 1] = arr[j];
}
arr[j + 1] = arr[0];
}
}
}
折半插入排序
插入排序的改进,用二分法搜索待插入的位置
void HalfInsertSort(int arr[], int len) {
for (int i = 1; i < len; i++) {
if (arr[i - 1] > arr[i]) {
int temp = arr[i];
int j = i - 1;
int low = 0;
int high = i - 1;
while (low <= high) {
int mid = (low + high) / 2;
if (arr[mid] > temp)
high = mid - 1;
else
low = mid + 1;
}
for (j; j >= high + 1; j--) {
arr[j + 1] = arr[j];
}
arr[j + 1] = temp;
}
}
}
希尔排序:
void ShellSort(int arr[], int len) {
for (int d = len / 2; d >= 1; d = d / 2) { //步长
for (int i = d ; i < len; i++) {
if (arr[i - d] > arr[i]) {
int temp = arr[i];
int j = i - d;
for (j; j >= 0 && arr[j] > temp; j -= d) {
arr[j + d] = arr[j];
}
arr[j + d] = temp;
}
}
}
}
快速排序:
int Partition(int arr[], int low, int high) {
int pivot = arr[low];
while (low < high) {
while (low < high && arr[high] >= pivot)
high--;
arr[low] = arr[high];
while (low < high && arr[low] < pivot)
low++;
arr[high] = arr[low];
}
arr[low] = pivot;
return low;
}
int RandomPartition(int arr[], int low, int high) {
int ran = rand() % (high - low + 1) + low;
swap(arr[low], arr[ran]); //随机选取
return Partition(arr, low, high);
}
void RandomQuickSort(int arr[], int low, int high) {
if (low < high) {
int pos = RandomPartition(arr, low, high);
RandomQuickSort(arr, low, pos - 1);
RandomQuickSort(arr, pos + 1, high);
}
}
归并排序:
int* temp = new int[20]; //辅助数组
void Merge(int arr[],int left,int mid,int right){
int i = left;
int j = mid + 1;
int k = left;
for (int q = left; q <= right; q++) {
temp[q] = arr[q];
}
while (i <= mid && j <= right) {
if (temp[i] <= temp[j])
arr[k++] = temp[i++];
else
arr[k++] = temp[j++];
}
while (i <= mid) {
arr[k++] = temp[i++];
}
while (j <= right) {
arr[k++] = temp[j++];
}
}
void MergeSort(int arr[], int left, int right) {
if (left < right) {
int middle = (left + right) / 2;
MergeSort(arr, left, middle);
MergeSort(arr, middle + 1, right);
Merge(arr, left, middle, right);
}
}
堆排序
void Adjust(int arr[], int index, int len) { //将index为根的子树调整为大根堆
int temp = arr[index];
for (int i = 2 * index+1; i < len; i = 2*i+1) {
if (i < len-1 && arr[i] < arr[i + 1]) {
i++;
}
if (temp >= arr[i])
break;
else {
arr[index] = arr[i];
index = i;
}
}
arr[index] = temp;
}
void HeapSort(int arr[], int len) {
for (int i = len / 2 - 1; i >= 0; i--) {
Adjust(arr, i, len); //构建大顶堆
}
for (int i = len - 1; i >= 1; i--) {
swap(arr[i], arr[0]); //堆底堆顶互换
Adjust(arr, 0, i); //重新构建大顶堆
}
}
计数排序
void CountSort1(int arr[], int len) {
int max = arr[0];
int min = arr[0];
for (int i = 1; i < len; i++) {
if (arr[i] > max)
max = arr[i];
if (arr[i] < min)
min = arr[i];
}
int *ret=new int [max-min+1](); //区间
for (int i = 0; i<len; i++) {
ret[arr[i]-min]++;
}
int count = 0; //计数
for (int i = 0; i < max - min + 1; i++) {
for (int j = ret[i]; j > 0; j--) {
arr[count++] = i+min;
}
}
}
基数排序
void Distribute(vector<int>& nums, vector<vector<int>>& rr,int p) {
for (int i = 0; i < nums.size(); i++) {
rr [9 + (int)(nums[i] / pow(10, p)) % 10] .emplace_back(nums[i]); //放到对应桶里
}
}
void Collect(vector<int>& nums, vector<vector<int>>& rr) {
int count = 0;
for (int i = 0; i < rr.size(); i++) {
for (int j = 0; j < rr[i].size(); j++) {
nums[count++] = rr[i][j]; //回收
}
rr[i].clear();
}
}
void RadixSort(vector<int>& nums) {
vector<vector<int> >res(19, vector<int>(0));//19个桶
int mx = abs(nums[0]);
for (int i = 1; i < nums.size(); i++) {
mx = max(mx, abs(nums[i])); //绝对值最大
}
int p = mx == 0 ? 0 : (log(mx) / log(10));
for (int i = 0; i <= p; i++) {
Distribute(nums, res,i);
Collect(nums, res);
}
}