常见排序算法

img

冒泡排序

每次把最大的数移到后面

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

选择排序

每次把最小的数放到前面

void selectionSort(vector<int>& vc,int n){
	for(int i=0;i<n;i++){
		int index = i;
		for(int j=i;j<n;j++){
			if(vc[index]>vc[j])index = j;
		}
		swap(vc[index],vc[i]);
	}
}

插入排序

插入到前面排序的末尾,大的数往后移

void insertionSort(vector<int>& vc,int n){
	for(int i=1;i<n;i++){
		int key = vc[i];
		int j = i - 1;
		while(j>=0 && key < vc[j]){
			vc[j+1] = vc[j];
			j--;
		}
		vc[j+1] = key;
	}
}

希尔排序

先将整个数组分成多块,使用插入排序对每块排序,然后将块大小增大块数量减少再每块排序,直到块数量为1

void shellSort(vector<int>& vc,int n){
	int h = 1;
	while(h < n / 3)h = h * 3 + 1;
	while(h >= 1){
		for(int i = h;i<n;i++){
			int j = i;
			while(j >= h && vc[j] < vc[j - h]){
				swap(vc[j],vc[j-h]);
				j -= h;
			}	
		}
		h /= 3;
	}
}

归并排序

基于分治,先分开,再合并

void merge(vector<int>&vc,int l,int r,int mid){
	vector<int>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<int>& 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<int>& vc,int n){
	merge_Sort(vc,0,n-1);
}

快速排序

以第一个点为基准,大的放后面,小的放前面,之后将第一个点放在中间可以将两个范围区分开

void Quick_Sort(vector<int>& 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<int>& vc,int n){
	Quick_Sort(vc,0,n-1);
}

堆排序

先建堆,形成大顶堆,然后将最大的值放到最后,堆个数-1,然后再将堆调整成大顶堆,以此循环,直到堆个数剩1不用交换。

void heapadjust(vector<int>& 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<int>& vc,int n){//建堆 
	for(int i = n / 2 - 1; i >= 0; i--){
		heapadjust(vc,i,n);
	}
}
void heapSort(vector<int>& 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<int>& 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<int>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<int>& vc,int n){
	vector<ListNode* >buckets(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(vector<int>vc, 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<int>& vc,int n){
	int d = maxbit(vc,n),radix = 1;
	vector<int>tmp(n);
	vector<int>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;
	}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值