每次把最大的数移到后面
void bubbleSort(vector选择排序& vc,int n){ for(int i=0;i vc[j+1])swap(vc[j],vc[j+1]); } } }
每次把最小的数放到前面
void selectionSort(vector插入排序& vc,int n){ for(int i=0;i vc[j])index = j; } swap(vc[index],vc[i]); } }
插入到前面排序的末尾,大的数往后移
void insertionSort(vector希尔排序& vc,int n){ for(int i=1;i =0 && key < vc[j]){ vc[j+1] = vc[j]; j--; } vc[j+1] = key; } }
先将整个数组分成多块,使用插入排序对每块排序,然后将块大小增大块数量减少再每块排序,直到块数量为1
void shellSort(vector归并排序& vc,int n){ int h = 1; while(h < n / 3)h = h * 3 + 1; while(h >= 1){ for(int i = h;i = h && vc[j] < vc[j - h]){ swap(vc[j],vc[j-h]); j -= h; } } h /= 3; } }
基于分治,先分开,再合并
void merge(vector快速排序&vc,int l,int r,int mid){ vector tmp(r - l + 1); for(int k = l; k <= r; k++)tmp[k-l] = vc[k]; int i = l, j = mid + 1; for(int k = l; k <= r; k++){ if(i > mid){ vc[k] = tmp[j - l]; j++; } else if(j > r){ vc[k] = tmp[i - l]; i++; } else if(tmp[i - l] < tmp[j - l]){ vc[k] = tmp[i - l]; i++; } else{ vc[k] = tmp[j - l]; j++; } } } void merge_Sort(vector & vc,int l,int r){ if(l >= r)return ; int mid = (l + r) >> 1; merge_Sort(vc,l,mid); merge_Sort(vc,mid+1,r); merge(vc,l,r,mid); } void mergeSort(vector & vc,int n){ merge_Sort(vc,0,n-1); }
以第一个点为基准,大的放后面,小的放前面,之后将第一个点放在中间可以将两个范围区分开
void Quick_Sort(vector堆排序& vc,int l,int r){ if(l >= r)return ; int i = l, j = r, tmp = vc[l]; while(i!=j){ while(vc[j] >= tmp && i < j)j--; while(vc[i] <= tmp && i < j)i++; if(i < j)swap(vc[i], vc[j]); } vc[l] = vc[i]; vc[i] = tmp; Quick_Sort(vc, l, i-1); Quick_Sort(vc, i+1, r); } void QuickSort(vector & vc,int n){ Quick_Sort(vc,0,n-1); }
先建堆,形成大顶堆,然后将最大的值放到最后,堆个数-1,然后再将堆调整成大顶堆,以此循环,直到堆个数剩1不用交换。
void heapadjust(vector计数排序& vc,int i,int n){//调整堆 int l = i * 2 + 1, r = i * 2 + 2; int tmp = i; if(i < n/2) {//保证不是叶子节点 if(l < n && vc[l] > vc[tmp]) tmp = l; if(r < n && vc[r] > vc[tmp]) tmp = r; if(tmp != i){ swap(vc[i],vc[tmp]); heapadjust(vc, tmp, n); } } } void heapbuild(vector & vc,int n){//建堆 for(int i = n / 2 - 1; i >= 0; i--){ heapadjust(vc,i,n); } } void heapSort(vector & vc,int n){ heapbuild(vc,n); for(int i = n - 1; i > 0; i--){ swap(vc[0],vc[i]); heapadjust(vc,0,i); } }
先存下个数,然后从小往后将元素加到数组里,空间换时间。
void countingSort(vector桶排序& vc,int n){ int maxx = INT_MIN, minx = INT_MAX; for(int i = 0;i < n; i++){ maxx = max(maxx, vc[i]); minx = min(minx, vc[i]); } vector cnt(maxx - minx + 1, 0); for(int i = 0; i < n; i++){ cnt[vc[i] - minx]++; } int index = 0; for(int i = 0; i <= maxx - minx ;i++){ while(cnt[i]--){ vc[index++] = i + minx; } } }
计数排序的进阶,每个桶可以存放多个不同元素。基于分治算法,将每个元素分到对应的桶,同一个桶使用链表排序,最后再合并。
const int BUCKET_NUM = 10;
struct ListNode{
int val;
ListNode* next;
ListNode():val(0), next(nullptr){}
ListNode(int _val):val(_val), next(nullptr){}
ListNode(int _val,ListNode* _next):val(_val), next(_next){}
};
ListNode* insert(ListNode* head, int val) {//桶内插入一个数
ListNode* newNode = new ListNode(val);
if(!head)return newNode;
ListNode* head1 = new ListNode();
ListNode* pre = head1;
ListNode* cur = head;
pre ->next = cur;
while(cur && cur -> val <= val){
pre = cur;
cur = cur->next;
}
newNode -> next = cur;
pre -> next = newNode;
return head1 -> next;
}
ListNode* merge(ListNode* head1, ListNode* head2){//两个桶进行合并
ListNode* head = new ListNode();
ListNode* pre = head;
while(head1 && head2){
if(head1 -> val <= head2 -> val){
pre -> next = head1;
head1 = head1 -> next;
}
else{
pre -> next = head2;
head2 = head2 -> next;
}
pre = pre ->next;
}
if(head1) pre -> next = head1;
if(head2) pre -> next = head2;
return head -> next;
}
void BucketSort(vector& vc,int n){
vectorbuckets(BUCKET_NUM,nullptr);
for(int i = 0; i < n; i++){
int index = vc[i] / BUCKET_NUM;
buckets[index] = insert(buckets[index], vc[i]);
}
ListNode* head = buckets[0];
for(int i = 1; i < BUCKET_NUM ; i++){
head = merge(head , buckets[i]);
}
for(int i = 0; i < n; i++){
vc[i] = head -> val;
head = head -> next;
}
}
基数排序
从个位开始对数组进行排序,依次往后,同一位数相等的两个数前面位数不等大的肯定放在后面,所以放的时候肯定还是放在后面,因为是从后面先取放在后面。
int maxbit(vectorvc, int n){//计算最大位数 int d = 1, p = 10; for(int i = 0; i < n; i++){ while(vc[i] >= p){ d++; p *= 10; } } return d; } void radixSort(vector & vc,int n){ int d = maxbit(vc,n),radix = 1; vector tmp(n); vector cnt(10); for(int i = 1; i <= d ;i++){//进行d次,从个位开始 for(int j = 0; j < 10; j++)cnt[j]=0; for(int j = 0; j < n; j++){ int k = vc[j] / radix % 10; cnt[k]++; } for(int j = 1; j < 10; j++)cnt[j] = cnt[j] + cnt[j-1];//算出每个桶放置最后面的位置 for(int j = n - 1; j >= 0; j--){ int k = vc[j] / radix % 10; tmp[cnt[k] - 1] = vc[j]; cnt[k]--; } for(int j = 0; j < n; j++)vc[j] = tmp[j]; radix *= 10; } }



