基础排序代码

Posted 牧空

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

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

[vscode]--HTML代码片段(基础版,reactvuejquery)

java基础3-重载+命令行传参+递归+数组+排序

算法排序之堆排序

[Go] 通过 17 个简短代码片段,切底弄懂 channel 基础

以下代码片段的时间复杂度是多少?

VsCode 代码片段-提升研发效率