基础排序代码

Posted 牧鱼ys

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基础排序代码相关的知识,希望对你有一定的参考价值。

冒泡

void BubbleSort(int *h,size_t len)
    if(h==NULL) return;
    if(len<=1) return;
    
    for(int i = 0;i<len-1;i++)
        for(int j = 0;j<len-1-i;j++)
            if(h[j]>h[j+1])
                Swap(h[j],h[j+1]);
            
        
    
    return;

快排

递归

void QuickSort(int *h, int left, int right)

    if (h == NULL)
        return;
    if (left >= right)
        return;
    //防止有序队列导致快排效率降低,随机选择提高算法的鲁棒性
    srand((unsigned)time(NULL));
    int len = right - left;
    int k_index = rand() % (len + 1) + left;
    Swap(h[left], h[k_index]);

    int key = h[left], i = left, j = right;
    while (i < j)
    
        while (h[j] >= key && i < j)
            j--;
        //找到h[j]<key停止,并交换
        if (i < j)
            h[i] = h[j];
        while (h[i] < key && i < j)
            i++;
        if (i < j)
            h[j] = h[i];
    
    h[i] = key;

    QuickSort(h, left, i - 1);
    QuickSort(h, j + 1, right);

非递归

int Partition(int a[], int low, int high)

    //假设每次都以第一个元素作为枢轴值,进行一趟划分:
    int pivot = a[low];

    while (low < high)
    
        while (low < high && a[high] >= pivot)
            --high;
        a[low] = a[high]; //停下来做交换
        while (low < high && a[low] <= pivot)
            ++low;
        a[high] = a[low]; //停下来做交换
    

    a[low] = pivot; //pivot的最终落点
    return low;


//非递归快排
void QuickSort(int a[], int left, int right)

    //手动利用栈来存储每次分块快排的起始点
    //栈非空时循环获取中轴入栈
    stack<int> s;
    if (left < right)
    
        int boundary = Partition(a, left, right);

        if (boundary - 1 > left) //确保左分区存在
        
            //将左分区端点入栈
            s.push(left);
            s.push(boundary - 1);
        
        if (boundary + 1 < right) //确保右分区存在
        
            s.push(boundary + 1);
            s.push(right);
        

        while (!s.empty())
        
            //得到某分区的左右边界
            int r = s.top();
            s.pop();
            int l = s.top();
            s.pop();

            boundary = Partition(a, l, r);
            if (boundary - 1 > l) //确保左分区存在
            
                //将左分区端点入栈
                s.push(l);
                s.push(boundary - 1);
            
            if (boundary + 1 < r) //确保右分区存在
            
                s.push(boundary + 1);
                s.push(r);
            
        
    

归并

void MergeArray(int * arr, size_t left,size_t mid,size_t right,int *temp)
    if(arr==NULL) return;
    size_t i = left,j = mid + 1,k=0;
    while(i<=mid && j<=right)
        if(arr[i]<=arr[j])
            temp[k++] = arr[i++];
            continue;
        
        
        temp[k++] = arr[j++];
    
    while(i<=mid)
        temp[k++] = arr[i++];
    while(j<=right)
        temp[k++] = arr[j++];
    memcpy(&arr[left],temp,k*sizeof(int));
    return;


void MMergeSort(int *arr,size_t left,size_t right,int * temp)
    if(left<right)
        size_t mid = (left+right)/2;
        MMergeSort(arr,left,mid,temp);
        MMergeSort(arr,mid+1,right,temp);
        MergeArray(arr,left,mid,right,temp);
    


void MergeSort(int *h,size_t len)
    if(h==NULL) return;
    if(len<=1) return;
    int * temp = (int *) calloc(len,sizeof(int));
    MMergeSort(h,0,len-1,temp);
    memcpy(h,temp,sizeof(int) *len);
    free(temp);
    return ;

插入

void InsertSort(int * h,size_t len)
    if(h==NULL) return;
    if(len<=1) return;
    int i,j;
    
    for(i=1;i<len;i++)
        for(j=i;j>0;j--)
            if(h[j]<h[j-1])
                Swap(h[j],h[j-1]);
            else 
                break;
        
    
    return;

希尔排序

void ShellSort(int * h,size_t len)
    if(h==NULL) return;
    if(len<=1) return;
    //div 步长,k 组号
    for(int div=len/2;div>=1;div/=2)
        for(int k=0;k<div;k++)
            for(int i=div+k;i<len;i+=div)
                for(int j=i;j>k;j-=div)
                    if(h[j]<h[j-div]) Swap(h[j],h[j-div]);
                    else break;
                
            
        
    
    return;

选择

void SelectionSort(int* h,size_t len)
    if(h==NULL) return;
    if(len<=1) return;
    
    int min_index,i,j;
    //i已排序的,j后面还需要排的序列
    for(i=0;i<len-1;i++)
        min_index = i;
        for(j=i+1;j<len-1;j++)
            if(h[j]<h[min_index]) min_inde = j;
        
        Swap(h[i],h[min_index]);
    
    return ;

堆排序

//===调整堆===	
void AdjustHeap(int *h,int node,int len)
    int index = node;
    int child = 2*index + 1;
    while(child<len)
        if(child+1<len && h[child]<h[child+1])
            child++;
        if(h[index]>=h[child]) break;
        Swap(h[index],h[child]);
        index = child;
        child = 2*index+1;
    

//===建堆===
void MakeHeap(int *h,int len)
    for(int i=len/2;i>=;i--)
        AdjustHeap(h,i,len);
    

//===排序===
 void HeapSort(int *h,int len)
     MakeHeap(h,len);
     for(int i=len-1;i>=0;i--)
         Swap(h[i],h[0]);
         AdujstHeap(h,0,i);
     
 

以上是关于基础排序代码的主要内容,如果未能解决你的问题,请参考以下文章

对快速排序的理解以及相关c++代码

快速排序:选择枢轴

快速排序

C++ 向量快速排序 - 似乎对不同的枢轴有不同的工作方式

快速排序

快速排序从入门到精通