C语言数组的五种排序

冒泡排序

快速排序

选择排序

插入排序

归并排序

冒泡排序
冒泡排序的基本思想:不断比较相邻的两个数,让较大的元素不断地往后移。经过一轮比较,就选出最大的数;经过第2轮比较,就选出次大的数,以此类推。对于具有N个元素的数组R[N],进行最多N-1轮比较;

/**
* 冒泡排序数组
* @param int a[] 要排序的数组
* @param int n 数组元素的个数
**/
void bubble_sort(int a[],int n){
    for(int i=0; i<n-1; i++){
        bool isSorted = true;
        for(int j=0; j<n-1-i; j++){
            if(a[j] > a[j+1]){
                isSorted = false;
                int temp = a[j];
                a[j] = a[j+1];
                a[j+1]=temp;
            }  
        }
        if(isSorted) break;
    }
}
快速排序
快速排序是对冒泡法排序的一种改进。

快速排序算法的基本思想:定义一个变量将数组分为左右两个部分,左边的数据都比该变量小,右边的数据都比该变量大,然后将所分得的两部分数据进行同样的划分,重复执行以上的划分操作,直到所有要进行排序的数据变为有序为止。

代码说明:

在第一次划分操作中,先进行初始设置,key的值是进行划分的基准,其值为要划分数组的第一个元素值,同时将low设置为要排序数组中第一个元素的下标,将high设置为要排序序列最后一个元素的下标。

先将下标为high的数组元素与key进行比较,如果该元素值大于key,则high向左移动一个位置。如果该元素值小于等于key,则将该元素赋值给下标为low所指向的数组元素,同时将low右移一个位置。

然后将low所指向的数组元素的值与key进行比较,如果该元素值小于key,则low向右移动一个位置描。如果该元素值大于等于key,则将该元素赋值给下标为high所指向的数组元素,同时将high左移一个位置。

如此循环直到low不再小于high,划分结束。

需要注意的是,在进行划分的过程中,都是将扫描的值与key的值进行对比,如果小于key,那么将该值赋值给数组中的另外一个元素,而该元素的值并没有改变。 从图中可以看出这一点,所以需要在划分的最后将作为划分基准的key值赋值给下标为 pos的数组元素,这个元素不再参与接下来的划分操作。

//对数组进行划分
int partition(int arr[], int low, int high){
    int key;
    key = arr[low];
    while(low<high){
        while(low <high && arr[high]>= key ) high--;
        if(low<high) arr[low++] = arr[high];
        while( low<high && arr[low]<=key ) low++;
        if(low<high) arr[high--] = arr[low];
    }
        arr[low] = key;
        return low;
}
 
/**
* 快速排序数组
* @param int arr[] 要排序的数组
* @param int start 序列的起始元素
* @param int end 序列的最后一个元素
**/
void quick_sort(int arr[], int start, int end){
    int pos;
    if (start<end){
        pos = partition(arr, start, end);
        quick_sort(arr,start,pos-1);
        quick_sort(arr,pos+1,end);
    }
    return;
}
选择排序
选择排序的基本思想:首先,选出最小的数放在第一个位置;然后,选出第二小的数放在第二个位置;以此类推,直到所有的数从小到大排序。

代码说明:

选择排序对大小为N的无序数组R[N]进行排序,进行N-1轮选择过程。第i轮选取第i小的数,并将其放在第i个位置上,然后将其与第i个数进行交换。

选择排序是一种不稳定的排序算法,可能会打乱两个相同数字的原有顺序。

/**
* 选择排序数组
* @param int a[] 要排序的数组
* @param int n 数组元素的个数
**/
void select_sort(int a[],int n){
    for(int i=0; i<n-1; i++){
        int min_index = i;
        for(int j=i+1; j<n; j++)
            if(a[j] < a[min_index])min_index = j;
        if( i != min_index){
            int temp = a[i];
            a[i] = a[min_index];
            a[min_index] = temp;
        }
    }
}
插入排序
插入排序的基本思想:将无序数组分为两部分,排序好的子数组和待插入的元素。在一个已经有序的小序列的基础上,一次插入一个元素,直到所有元素都加入排序好数组。

/**
* 插入排序数组
* @param int a[] 要排序的数组
* @param int n 数组元素的个数
**/
void insert_sort(int a[],int n){
for(int i=1; i<n; i++){
    int j=0;
    while( (a[j]<a[i]) && (j<i)) j++;
        if(i != j){
            int temp = a[i];
            for(int k = i; k > j; k--) a[k] = a[k-1];
            a[j] = temp;
        }
    }
}
归并排序
归并排序也称合并排序,其算法思想是将待排序序列分为两部分,依次对分得的两个部分再次使用归并排序,之后再对其进行合并。

代码说明:

先对所要进行排序的序列进行分解,直到分为单个元素为止,然后将其进行两两合并。由于最终分解成单个元素,因此在合并的时候.将小数放在前面,大数放在后面,得到一个有序序列。接下来对两个相连的有序序列进行排序,先比较有序序列中的第一个元素,将较小的元素放入临时数组中,接着将较小元素所在数组的下一个元素与另一个数组中的较小元素比较,同样将较小元素放入临时数组中,依次进行,直到两个数组的所有元素都放入临时数组中,最后再将临时数组的元素放入原始数组中的对应位置。

/**
* 归并排序数组
* @param int a[] 要排序的数组
* @param int n 数组元素的个数
**/
void merge(int arr[], int low, int mid, int high){
    int i, k;
    //申请空间,使其大小为两个
    int *tmp = (int *)malloc((high-low+1)*sizeof(int));
    int left_low = low;
    int left_high = mid;
    int right_low = mid + 1;
    int right_high = high;
    // 比较两个指针所指向的元素
    for(k=0; left_low<=left_high && right_low<=right_high; k++){ 
        if(arr[left_low]<=arr[right_low]) tmp[k] = arr[left_low++];
        else tmp[k] = arr[right_low++];
    }
    if(left_low <= left_high){ 
        //若第一个序列有剩余,直接复制出来粘到合并序列尾
        //memcpy(tmp+k, arr+left_low, (left_high-left_low+l)*sizeof(int));
        for(i=left_low;i<=left_high;i++)
            tmp[k++] = arr[i];
        }
    if(right_low <= right_high){
        //若第二个序列有剩余,直接复制出来粘到合并序列尾
        //memcpy(tmp+k, arr+right_low, (right_high-right_low+1)*sizeof(int));
        for(i=right_low; i<=right_high; i++)
            tmp[k++] = arr[i];
        }
    for(i=0; i<high-low+1; i++)
        arr[low+i] = tmp[i];
    free(tmp);
    return;
}
 
/**
* 归并排序数组
* @param int arr[] 要排序的数组
* @param unsigned int first 数组首元素的下标
* @param unsigned int last 数组末元素的下标
**/
 
void merge_sort(int arr[], unsigned int first, unsigned int last){
    int mid = 0;
    if(first<last){
        mid = (first+last)/2; /* 注意防止溢出 */
        /*mid = first/2 + last/2;*/
        //mid = (first & last) + ((first ^ last) >> 1);
        merge_sort(arr, first, mid);
        merge_sort(arr, mid+1,last);
        merge(arr,first,mid,last);
    }
    return;
}
 
————————————————
版权声明:本文为CSDN博主「Noteligible」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_42322548/article/details/88317570

发布了10 篇原创文章 · 获赞 25 · 访问量 3万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章