#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<stdbool.h>
#include<time.h>
#include<math.h>
void swap(int* a, int* b) {
int t = *a;
*a = *b;
*b = t;
}
void bubble_sort(int arr[],int n) {
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
swap(&arr[j], &arr[j + 1]);
}
}
}
}
void insrt_sort(int arr[],int n) {
for (int i = 1; i < n; i++) {
int key = arr[i];//待排序的那一个元素位置相当于空出来了
int j = i - 1;//从排好序的最后一个开始比较
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = key;
}
}
int pivot_index(int arr[], int left, int right) {
int pivot = arr[left];
int i = left + 1;
int j = right;
while (i <= j) {//即使i和j的停止条件是相悖的也要写=,因为只有两个元素的时候i和j相等,仍然需要排序
while (arr[i] <= pivot&&i<=right) {//找打比基准元素大的就停下来(需要写<=,来避免重复元素导致的无限循环)
i++;
}
while (arr[j] >= pivot&&j>=left+1) {//找到比基准元素小的就停下来
j--;
}
if (i < j) {//当i和j交叉时不要交换
swap(&arr[i], &arr[j]);
}
}
swap(&arr[left], &arr[j]);//j必然指向最后一个小于pivot的元素,前面的if语句会确保
return j;
}
void quick_sort(int arr[], int left, int right) {
if (right - left <= 0) return;//只有一个元素的时候不需要排序直接返回;
int pivot = pivot_index(arr, left, right);
quick_sort(arr, left, pivot - 1);
quick_sort(arr, pivot + 1, right);
}
void selection_sort(int arr[],int n) {
for (int i = 0; i < n - 1; i++) {
int min_index = i;
for (int j = i + 1; j < n; j++) {
if (arr[j] < arr[min_index]) {
min_index = j;
}
}
swap(&arr[i], &arr[min_index]);
}
}
void heapify(int arr[], int n, int i) {
int largest_index = i;
int left_index = i * 2 + 1;
int right_index = i * 2 + 2;
if (arr[left_index] > arr[largest_index] && left_index < n) {
largest_index = left_index;
}
if (arr[right_index] > arr[largest_index] && right_index < n) {
largest_index = right_index;
}
if (largest_index != i) {
swap(&arr[i], &arr[largest_index]);
heapify(arr, n, largest_index);
}
}
void heap_sort(int arr[],int n) {
for (int i = n / 2 - 1; i >= 0; i--) {//n/2-1是最后一个非叶子节点,因为叶子节点没有子节点,不需要heapify
heapify(arr, n, i);
}
for (int i = n - 1; i >= 0; i--) {
swap(&arr[0], &arr[i]);
heapify(arr, i, 0);
}
}
void merge(int arr[], int l, int m, int r) {
int n1 = m - l + 1;
int n2 = r - m;
int i, j, k;
int* L = (int*)malloc(sizeof(int) * n1);
int* R = (int*)malloc(sizeof(int) * n2);
for (i = 0; i < n1; i++) {
L[i] = arr[l + i];
}
for (j = 0; j < n2; j++) {
R[j] = arr[m + 1 + j];
}
i = 0; j = 0; k = l;//k一定要从l开始,不是从0开始,如果从0开始会导致递归合并的时候覆盖错误
while (i < n1 && j < n2) {
if (L[i] < R[j]) {
arr[k++] = L[i++];
}
else {
arr[k++] = R[j++];
}
}
while (i < n1) {
arr[k++] = L[i++];
}
while(j < n2) {
arr[k++] = R[j++];
}
}
void merge_sort(int arr[], int l, int r) {
if (r-l<=0) return;//当只有一个元素的时候则返回,不需要合并
int mid = (l + r) / 2;
merge_sort(arr, l, mid);
merge_sort(arr, mid + 1 , r);
merge(arr, l, mid, r);
}
int get_max(int arr[], int n) {
int max = arr[0];
for (int i = 1; i < n; i++) {
if (arr[i] > max) max = arr[i];
}
return max;
}
void radix_sort(int arr[],int l,int r) {
int max_val = get_max(arr, r - l + 1);
int count = 0;
while (max_val != 0) {
max_val /= 10;
count++;
}
int** buckets = (int**)malloc(sizeof(int*) * 10);//根据位数数字0-9,创建10个桶
int* buckets_size = (int*)malloc(sizeof(int) * 10);//记录每个桶的元素个数来方便赋值到原数组进行排序
for (int i = 0; i < 10; i++) {
buckets[i] = (int*)malloc(sizeof(int) * (r - l + 1));
buckets_size[i] = 0;
}
for (int i = 0; i < count; i++) {
for (int j = l; j <= r; j++) {
int temp = arr[j];
temp = temp / (int)pow(10, i);
int digit = temp % 10;
buckets[digit][buckets_size[digit]++] = arr[j];
}
int index = l;
for (int k = 0; k < 10; k++) {
for (int m = 0; m < buckets_size[k]; m++) {//根据每个桶的元素个数来进行赋值
arr[index++] = buckets[k][m];
}
buckets_size[k] = 0;//只需要情况每个桶的元素个数,不需要清空桶内元素
}
}
}
void shell_sort(int arr[], int n) {
int gap;
for (gap = n / 2; gap > 0; gap /= 2) {
for (int i = gap; i < n; i++) {//i从gap开始,从第一组开始(插入排序假定第一个数字有序)
int key = arr[i];
int j = i-gap;
while (j >= 0 && arr[j] > key) {
arr[j + gap] = arr[j];
j -= gap;//保证了每一个数组都和它那一组的数组进行插入排序,即间隔为gap
}
arr[j + gap] = key;
}
}
}//希尔排序
void print_arr(int arr[], int l,int r) {
for (int i = l; i <=r; i++) {
printf("%d ", arr[i]);
}
}
void copy_arr(int arr[], int temp[], int n) {
for (int i = 0; i < n; i++) {
temp[i] = arr[i];
}
}
void compare_arrays(int arr1[], int arr2[], int n) {
for (int i = 0; i < n; i++) {
if (arr1[i] != arr2[i]) {
printf("排序错误\n\n");
return;
}
}
printf("排序正确\n\n");
}
int main() {
int n = 50;
srand(time(NULL));
int* arr =(int *)malloc(sizeof(int) * n);
for (int i = 0; i < n; i++) {
arr[i] = rand();
}
int a[50],b[50],c[50],d[50],e[50],f[50],g[50],h[50],i[50];
copy_arr(arr, a, n); copy_arr(arr, b, n); copy_arr(arr, c, n);
copy_arr(arr, d, n); copy_arr(arr, e, n); copy_arr(arr, f, n);
copy_arr(arr, g, n); copy_arr(arr, h, n); copy_arr(arr, i, n);
bubble_sort(a, n);
printf("冒泡排序:\n");
print_arr(a, 0, n - 1); printf("\n");
compare_arrays(a, a, n);
printf("插入排序:\n");
insrt_sort(b, n);
print_arr(b, 0, n - 1); printf("\n");
compare_arrays(b, a, n);
printf("快速排序:\n");
quick_sort(c, 0, n - 1);
print_arr(c, 0, n - 1); printf("\n");
compare_arrays(c, a, n);
printf("选择排序:\n");
selection_sort(d, n);
print_arr(d, 0, n - 1); printf("\n");
compare_arrays(d, a, n);
printf("堆排序:\n");
heap_sort(e, n);
print_arr(e, 0, n - 1); printf("\n");
compare_arrays(e, a, n);
printf("归并排序:\n");
merge_sort(f, 0, n - 1);
print_arr(f, 0, n - 1); printf("\n");
compare_arrays(f, a, n);
printf("基数排序:\n");
radix_sort(g, 0, n - 1);
print_arr(g, 0, n - 1); printf("\n");
compare_arrays(g, a, n);
printf("希尔排序:\n");
shell_sort(h, n);
print_arr(h, 0, n - 1); printf("\n");
compare_arrays(h, a, n);
return 0;
}
简单排序算法
于 2024-05-02 01:49:42 首次发布