排序总结
比较排序
-
选择排序
void selectionSort(int arr[],int length);
void swap(int arr[],int i,int minIndex);
void selectionSort(int arr[],int length) //从小到大排序
{
if(arr==NULL||length<2){
return ;
}
for(int i=0;i<length-1;i++){ //i到N-1范围 切记是sizeof(arr)/sizeof(int)-1
int minIndex=i;
for(int j=i+1;j<length;j++){ //找最小值的下标
minIndex=arr[j]<arr[minIndex]?j:minIndex;
}
swap(arr,i,minIndex);
}
}
void swap(int arr[],int i,int minIndex)
{
int tmp=arr[i];
arr[i]=arr[minIndex];
arr[minIndex]=tmp;
}
-
冒泡排序
void bubbleSort(int arr[],int length);
void swap(int arr[],int i,int j);
void bubbleSort(int arr[],int length)
{
if(arr==NULL||length<2){
return ;
}
for(int i=length-1;i>0;i--){ //0-i范围上有序
for(int j=0;j<i;j++){
if(arr[j]>arr[j+1]){
swap(arr,j,j+1); // 保证i 和 j的地址不会相同
}
}
}
}
void swap(int arr[],int i,int j)
{
arr[i]=arr[i]^arr[j];
arr[j]=arr[i]^arr[j];
arr[i]=arr[i]^arr[j];
}
-
插入排序(数据状况不同,速度不同)
void InsertionSort(int arr[],int length);
void swap(int arr[],int i,int j);
void InsertionSort(int arr[],int length)
{
if(arr == NULL || length < 2){
return ;
}
for(int i = 1; i < length;i++){
for(int j = i - 1 ;j >= 0 && arr[j] > arr[j+1];j--){
swap(arr, j, j + 1);
}
}
}
void swap(int arr[],int i ,int j)
{
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
-
归并排序
void process(int arr[],int L,int R);
void merge(int arr[],int L,int M,int R);
void process(int arr[],int L,int R)
{
if(L==R){
return;
}
int mid=L+((R-L)>>1);
process(arr,L,mid);
process(arr,mid+1,R);
merge(arr,L,mid,R);
}
void merge(int arr[],int L,int M,int R)
{
int help[R-L+1];
int i=0;
int p1=L;//p1从L开始到M停止(左边数组) p1,p2只是数组下标,不是指针,并且都是从左往右移动
int p2=M+1; //p2从M+1开始到R停止(右边数组)
while(p1<=M&&p2<=R){
help[i++]=arr[p1]<=arr[p2]?arr[p1++]:arr[p2++];
}
while(p1<=M){
help[i++]=arr[p1++];
}
while(p2<=R){
help[i++]=arr[p2++];
}
for(i=0;i<R-L+1;i++){
arr[L+i]=help[i];
}
}
-
快排3.0(递归实现)
void quickSort(int arr[],int L,int R);
int *partition(int arr[],int L,int R);
void swap(int arr[],int i,int j);
void quickSort(int arr[],int L,int R) //R为arr.length-1
{
if(L<R){
swap(arr,(rand()%(R-L+1))+L,R); //(rand()%(R-L+1))+L是从数组中随机选一个下标,换到数组末尾R位置 让数组末尾的数作为划分值
int *p=partition(arr,L,R); //数组p的大小为2,其中p[0]是=区间的左边界下标,p[1]是 = 区间的右边界下标.p[0]-1是<区间右边界 p[1]+1是>区间左边界
quickSort(arr,L,p[0]-1); // <num区间
quickSort(arr,p[1]+1,R);// >num区间
}
}
int *partition(int arr[],int L,int R) //R为划分值的下标
{
int less=L-1; //<区右边界
int more=R; //>区左边界
while(L<more){ //L为当前数下标
if(arr[L]<arr[R]){ //当前数 < 划分值
swap(arr,++less,L++);
}
else if(arr[L]>arr[R]){ //当前数 > 划分值
swap(arr,--more,L);
}
else{
L++;
}
}
swap(arr,more,R);
int p[]={less+1,more};
return p;
}
void swap(int arr[],int i,int j)
{
int tmp=arr[i];
arr[i]=arr[j];
arr[j]=tmp;
}
-
堆排序
void heapInsert(int arr[],int index);
void heapify(int arr[],int index,int heapsize);
void heapSort(int arr[],int length);
void swap(int arr[],int i,int j);
void heapInsert(int arr[],int index) //某个数处于index(孩子)位置,不断往上移动到合适位置
{ //不用担心下标越界,因为(-n - 1 )/ 2 =0 0/2也是0;
while(arr[index]>arr[(index-1)/2]){
swap(arr,index,(index-1)/2);
index=(index-1)/2;
}
}
void heapify(int arr[],int index,int heapsize) //某个数处于index(父)位置,不断往下移动到合适的位置
{
int left=index*2+1; //左孩子下标
while(left<heapsize){ //下方还有孩子的时候
//两个孩子中,谁的值大,就把下标给largest
int largest=left+1<heapsize&&arr[left+1]>arr[left]?left+1:left;
//父和较大值孩子,谁的值大,把下标给largest
largest=arr[largest]>arr[index]?largest:index;
if(largest==index){
break;
}
swap(arr,largest,index);
index=largest;
left=index*2+1;
}
}
void heapSort(int arr[],int length)
{
if(arr==NULL||length<2){
return ;
}
for(int i=0;i<length;i++){ //让arr变成大根堆 O(N)
heapInsert(arr,i); //O(logN)
}
int heapsize=length;
swap(arr,0,--heapsize); //第一个数(最大值)和最后一个值交换,并且剔除最后一个值(最大值)
while(heapsize>0){ //O(N)
heapify(arr,0,heapsize); // O(logN)
swap(arr,0,--heapsize); //O(1)
}
}
void swap(int arr[],int i,int j)
{
int tmp=arr[i];
arr[i]=arr[j];
arr[j]=tmp;
}
桶排序(非比较) --基数排序
int maxbits(int arr[],int length);
int getDigit(int x,int d);
void radixSort(int arr[],int L,int R,int digit);
int maxbits(int arr[],int length) //返回 数组中最大的数的 位数
{
int max0=INT_MIN; //INT_MIN是整型能表示的最小值
for(int i=0;i<length;i++){
max0=max(max0,arr[i]);
}
int count=0;
while(max0!=0){
count++;
max0/=10;
}
return count;
}
void radixSort(int arr[],int L,int R,int digit)
{
const int radix=10;//以10为基底,radix为常数,不会改变
int i=0,j=0,d=0;
int bucket[R-L+1];
for(int d=1;d<=digit;d++){ // 最大的数有多少位就 进出桶几次
//10个空间
//count[0] 当前位(i)是0的数字有多少个
//count[1] 当前位(i)是0,1的数字有多少个
//count[2] 当前位(i)是0,1,2的数字有多少个
//count[9] 当前位(i)是0~9的数字有多少个
int count[radix]={0}; //count[0..9]
for(i=L;i<=R;i++){
j=getDigit(arr[i],d);
count[j]++;
}
for(i=1;i<radix;i++){
count[i]=count[i]+count[i-1];
}
for(i=R;i>=L;i--){
j=getDigit(arr[i],d);
bucket[count[j]-1]=arr[i];
count[j]--;
}
for(i=L,j=0;i<=R;i++,j++){
arr[i]=bucket[j];
}
}
}
int getDigit(int x,int d)
{
return ((x/((int)pow(10,d-1)))%10);
}