クイックソート ( O(N*logN) )
ON*log(N) と同じ時間計算量でより効率的です。
基本的な考え方は次のとおりです。
1. 最初に、基数としてシーケンスから番号を取得します。
2. パーティショニング プロセスでは、この数値よりも大きいすべての数値がその右側に配置され、それ以下のすべての数値がその左側に配置されます。
3. 次に、左右の間隔に対して 2 番目の手順を繰り返し、各間隔に 1 つの数値のみが含まれるようにします。
#include<bits/stdc++.h>
using namespace std;
//对于数组的传参,可以按照int arr[],也可以int *arr,这两种方法都是传入的地址,
//因此在函数中对数组的操作,会改变原有数组的值,
void quick_sort(int arr[],int begin,int end){
if ( begin<end) {
//挖走begin位置的数,这个位置的数会有别的数来填补
int i = begin, j = end, x = arr[begin];
//倒叙找到第一个小于x的数然后填入begin的坑
//这个时候j的位置就出现了一个新的坑,这个位置需要一个比基数大的数填
while (i < j && arr[j] >=x) j--;
if (i < j)arr[i++] = arr[j];
//从左到右找到第一个大于x的数,然后填补j位置的坑
while (i < j && arr[i] <= x)i++;
if (i < j)arr[j--] = arr[i];
arr[i] = x;
//分治,将i的左右两边再次快排
quick_sort(arr,begin,i-1);
quick_sort(arr,i+1,end);
}
}
int main() {
int arr[9] = {
1,1,34,5,7,8,9,0,11};
quick_sort(arr,0,8);
for (int i:arr) {
cout << i << endl;
}
return 0;
}
//结果:
//0
//1
//1
//5
//7
//8
//9
//11
//34
選択ソート (O(N^2))
基本的な考え方:
毎回、並べ替えられていないシーケンスから最小の数値を見つけて、並べ替えられたシーケンスの最後に挿入します
void SelectSort(int arr[],int lenght) {
int index = 0;
while (index!=lenght) {
int x = 1e9, temp = 0;
for (int i = index; i <lenght;i++) {
if (arr[i]<=x) {
temp = i;
x = arr[i];
}
}
swap(arr[index],arr[temp]);
index++;
}
}
マージソート (O(N*logN))
アイデアの分割と征服の
写真のデモ
//归并排序
//分治,分到长度为2的最小单元,让这个单元有序,然后在从下往上开始有序
void Merge(vector<int> &arr ,int front,int mid,int end) {
//注意拷贝的区间。
vector<int> left(arr.begin()+front, arr.begin() + mid+1 );//拷贝左半部分
vector<int> right(arr.begin() + mid + 1,arr.begin()+end+1);//拷贝右半部分
//在尾部插入一个编译器允许的int类型最大值。
left.insert(left.end(),numeric_limits<int>::max());
right.insert(right.end(),numeric_limits<int>::max());
int leftindex = 0, rightindex = 0;
for (int i = front; i <= end;i++) {
if (left[leftindex] < right[rightindex])arr[i] = left[leftindex++];
else arr[i] = right[rightindex++];
}
}
//归并排序
void MergeSort(vector<int> &arr,int front,int end) {
if (front >= end) return;
int mid = (front + end) /2;
MergeSort(arr,front,mid);
MergeSort(arr,mid+1,end);
Merge(arr,front,mid,end);
}