排序总结

 

 

 

 

比较排序

  • 选择排序

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);
}

 

posted @ 2023-03-21 15:43  osir  阅读(2)  评论(0编辑  收藏  举报