插入排序、冒泡排序、希尔排序、堆排序、计数排序、基数排序

复习一下插入排序、冒泡排序、希尔排序、堆排序、计数排序、基数排序

插入排序 平均复杂度 O(n^2),最好情况为O(N),且是稳定的。

插入排序是在一个已经有序的小序列的基础上,一次插入一个元素。当然,刚开始这个有序的小序列只有1个元素,也就是第一个元素(默认它有序)。

冒泡排序 平均复杂度 O(n^2),最好情况为O(N),且是稳定的。

它从左到右依次交换元素,若在一次循环中没有出现交换情况,则表明有序,则可停止程序。

对于大规模的数组,插入排序很慢,因为它只能交换相邻的元素,每次只能将逆序数量减少 1。

希尔排序的出现就是为了解决插入排序的这种局限性,它通过交换不相邻的元素,每次可以将逆序数量减少大于 1。

希尔排序使用插入排序对间隔 h 的序列进行排序。通过不断减小 h,最后令 h=1,就可以使得整个数组是有序的。

一个堆的高度为 logN,因此在堆中插入元素和删除最大元素的复杂度都为 logN。

对于堆排序,由于要对 N 个节点进行下沉操作,因此复杂度为 NlogN。

堆排序时一种原地排序,没有利用额外的空间。

计数排序假设输入元素的范围落在一个区间[0,k),运行时间是O(n+k),他是稳定的。

基数排序是先按照最低位进行排序来解决卡片排序问题(将整数按位数切割成不同的数字,然后按每个位数分别比较),同样他是稳定的,其中按位排序可退化为落在范围为0-9的计数排序。

#include<stdlib.h> 
#include<stdio.h>

#define leftChild(i) (2*(i)+1)

static void swap(int *a,int *b){
	int tmp;
	tmp=*a;
	*a=*b;
	*b=tmp;
}

void insertSort(int A[],int N){
	int i,j;
	for(i=1;i<N;i++){
		int tmp=A[i];
		for(j=i;j>0 && tmp<A[j-1];j--)
		  A[j]=A[j-1];
		A[j]=tmp;
	}
}

void shellSort(int A[],int N){
	int increase,i,j,tmp;
	for(increase=N/2;increase>0;increase/=2){
		for(i=increase;i<N;i++){
			tmp=A[i];
			for(j=i;j>=increase;j-=increase){
				if(tmp<A[j-increase])
				  A[j]=A[j-increase];
				else break;
			}
			A[j]=tmp;
		}
	}
}

void printArray(int arr[],int N){
	int i;
	for(i=0;i<N;i++)
	  printf("%d\t",arr[i]);
	printf("\n");
}

static void percDown(int arr[],int pos,int N){
	int child,i;
	int tmp=arr[pos];
	for(i=pos;leftChild(i)<N;i=child){
		child=leftChild(i);
		if(child!=N-1 && arr[child]<arr[child+1])
		  ++child;
		if(tmp<arr[child])
		  arr[i]=arr[child];
		else break;
	}
	arr[i]=tmp;
}

void heapSort(int arr[],int N){
	int i;
	for(i=N/2;i>=0;i--)
		percDown(arr,i,N);
	for(i=N-1;i>0;i--){
		swap(&arr[0],&arr[i]);
		percDown(arr,0,i);
	}	
}

void bubbleSort(vector<int>&v){
	if(v.empty())return;
	auto n=v.size();
	for(int i=n-1;i>=0;--i){
		bool flag=true;
		for(int j=0;j<i;++j){
			if(v[j]>v[j+1]){
				swap(v[j],v[j+1]);
				flag=false;
			}
		}
		if(flag)return;
	}

int main(){
	int array[9]={56,78,33,22,14,156,123,64,634};
	insertSort(array,9);
	printArray(array,9);
	shellSort(array,9);
	printArray(array,9);
	heapSort(array,9);
	printArray(array,9);
	return 0;
	
}

 

以下为计数排序和基数排序的实现:

#include<iostream>
#include<vector>
using namespace std;

vector<int> countingSort(const vector<int>&a,vector<int>&b){
	auto res=a;
	for(int i=0;i!=a.size();++i){
		++b[a[i]];
	}
	for(int i=1;i!=b.size();++i)
	  b[i]+=b[i-1];
	for(int i=a.size()-1;i>=0;--i){
		res[b[a[i]]-1]=a[i];
		--b[a[i]];
	}
	return res;
}

int get_max(const vector<int>&v){
	auto ret=v[0];
	for(int i=1;i<v.size();++i)
		ret=max(ret,v[i]);
	return ret;
}

void count_sort(vector<int>&v,int f){
	vector<int>tmp(10);
	vector<int>ret=v;
	auto n=v.size();
	for(int i=0;i<n;++i)
		++tmp[(v[i]/f)%10];
	for(int i=1;i<10;++i)
		tmp[i]+=tmp[i-1];
	for(int i=n-1;i>=0;--i){
		ret[tmp[(v[i]/f)%10]-1]=v[i];
		--tmp[(v[i]/f)%10];
	}
	for(int i=0;i<n;++i)
		v[i]=ret[i];
}

void radix_sort(vector<int>&v){
	if(v.size()<2)return;
	auto max=get_max(v);
	
	for(int i=1;max/i>0;i*=10){
		count_sort(v,i);
	}
}

int main(){
	/*
	vector<int>a{2,5,3,0,2,3,0,3};
	vector<int>b(6);
	auto res=countingSort(a,b);
	for(auto i:res)cout<<i<<",";
	cout<<endl;
	*/
	vector<int>a{53, 3, 542, 748, 14, 214, 154, 63, 616};
	radix_sort(a);
	for(auto i:a)cout<<i<<",";
	cout<<endl;
}
 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值