内部排序算法合集

#include<stdio.h>

void InsertSort(int arr[], int n) {  
    int i, j, temp;  
    for (i = 1; i < n; i++) {  
        temp = arr[i]; // 存储当前位置的值  
        j = i - 1;  
        // 查找插入位置  
        while (j >= 0 && arr[j] > temp) {  
            arr[j + 1] = arr[j]; // 移动元素  
            j--;  
        }  
        arr[j + 1] = temp; // 插入元素  
    }  
}

//希尔排序
void ShellSort(int arr[], int n) {  
    int d, i, j;  
    
    // 使用减少增量的方式开始  
    for (d = n / 2; d >= 1; d /= 2) {  
        for (i = d; i < n; ++i) {  
            int temp = arr[i]; // 使用临时变量存储当前值  
            // 将元素插入到适当的位置  
            for (j = i; j >= d && arr[j - d] > temp; j -= d) {  
                arr[j] = arr[j - d];  
            }  
            arr[j] = temp; // 在合适的位置插入temp  
        }  
    }  
}  

//冒泡排序
void BubbleSort(int arr[], int n) {  
    int i, j, temp;  
    int swapped; // 用于标记是否发生交换  

    for (i = 0; i < n - 1; i++) {  
        swapped = 0; // 交换标记  

        // 在每一轮中,比较相邻元素  
        for (j = 0; j < n - 1 - i; j++) {  
            if (arr[j] > arr[j + 1]) {  
                // 交换元素  
                temp = arr[j];  
                arr[j] = arr[j + 1];  
                arr[j + 1] = temp;  
                swapped = 1; // 标记已发生交换  
            }  
        }  

        // 如果没有发生交换,数组已排好序,结束排序  
        if (swapped == 0) {  
            break;  
        }  
    }  
}  

//快速排序
void QuickSort(int arr[], int low, int high) {  
    if (low < high) {  
        int pivot = arr[high]; // 选取最后一个元素作为基准  
        int i = (low - 1); // 指向较小元素的索引  

        for (int j = low; j < high; j++) {  
            // 如果当前元素小于等于基准  
            if (arr[j] <= pivot) {  
                i++; // 增加较小元素的索引  
                // 交换 arr[i] 和 arr[j]  
                int temp = arr[i];  
                arr[i] = arr[j];  
                arr[j] = temp;  
            }  
        }  
        // 交换 arr[i + 1] 和 arr[high](即基准)  
        int temp = arr[i + 1];  
        arr[i + 1] = arr[high];  
        arr[high] = temp;  

        // 递归排序两个分区  
        QuickSort(arr, low, i);  
        QuickSort(arr, i + 2, high);  
    }  
}  

//简单选择排序
void SelectionSort(int arr[], int n) {  
    for (int i = 0; i < n - 1; i++) {  
        int min_idx = i; // 假设当前索引为最小值索引  
        for (int j = i + 1; j < n; j++) {  
            // 找到最小值的索引  
            if (arr[j] < arr[min_idx]) {  
                min_idx = j;  
            }  
        }  
        // 交换找到的最小值和当前位置的元素  
        if (min_idx != i) {  
            int temp = arr[i];  
            arr[i] = arr[min_idx];  
            arr[min_idx] = temp;  
        }  
    }  
} 

//归并排序
// 合并两个子数组  
void merge(int arr[], int left, int mid, int right) {  
    int n1 = mid - left + 1; // 左子数组的大小  
    int n2 = right - mid;     // 右子数组的大小  

    // 创建临时数组  
    int L[n1], R[n2];  

    // 复制数据到临时数组 L[] 和 R[]  
    for (int i = 0; i < n1; i++)  
        L[i] = arr[left + i];  
    for (int j = 0; j < n2; j++)  
        R[j] = arr[mid + 1 + j];  

    // 合并临时数组  
    int i = 0; // 初始化左子数组的索引  
    int j = 0; // 初始化右子数组的索引  
    int k = left; // 初始化合并后的数组的索引  

    while (i < n1 && j < n2) {  
        if (L[i] <= R[j]) {  
            arr[k] = L[i];  
            i++;  
        } else {  
            arr[k] = R[j];  
            j++;  
        }  
        k++;  
    }  

    // 复制剩余的元素  
    while (i < n1) {  
        arr[k] = L[i];  
        i++;  
        k++;  
    }  

    while (j < n2) {  
        arr[k] = R[j];  
        j++;  
        k++;  
    }  
}  

// 归并排序算法  
void MergeSort(int arr[], int left, int right) {  
    if (left < right) {  
        int mid = left + (right - left) / 2; // 计算中间索引  

        // 递归排序  
        MergeSort(arr, left, mid);  
        MergeSort(arr, mid + 1, right);  

        // 合并已排序的子数组  
        merge(arr, left, mid, right);  
    }  
}  

//堆排序
// 交换两个元素  
void swap(int* a, int* b) {  
    int temp = *a;  
    *a = *b;  
    *b = temp;  
}  

// 建立最大堆  
void heapify(int arr[], int n, int i) {  
    int largest = i;  // 初始化最大元素为根  
    int left = 2 * i + 1; // 左子节点  
    int right = 2 * i + 2; // 右子节点  

    // 如果左子节点大于根  
    if (left < n && arr[left] > arr[largest])  
        largest = left;  

    // 如果右子节点更大  
    if (right < n && arr[right] > arr[largest])  
        largest = right;  

    // 如果最大不是根  
    if (largest != i) {  
        swap(&arr[i], &arr[largest]); // 交换  
        heapify(arr, n, largest); // 递归堆化  
    }  
}  

// 堆排序算法  
void HeapSort(int arr[], int n) {  
    // 建立最大堆  
    for (int i = n / 2 - 1; i >= 0; i--)  
        heapify(arr, n, i);  

    // 一个一个取出元素  
    for (int i = n - 1; i >= 0; i--) {  
        swap(&arr[0], &arr[i]); // 移动当前根到数组的末尾  
        heapify(arr, i, 0); // 递归堆化减少的堆  
    }  
}  

// 获取数组中最大值  
int getMax(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 countingSort(int arr[], int n, int exp) {  
    int output[n]; // 输出数组  
    int count[10] = {0}; // 计数数组  

    // 计算每个数字在当前位上出现的次数  
    for (int i = 0; i < n; i++)  
        count[(arr[i] / exp) % 10]++;  

    // 计算当前位置  
    for (int i = 1; i < 10; i++)  
        count[i] += count[i - 1];  

    // 构建输出数组  
    for (int i = n - 1; i >= 0; i--) {  
        output[count[(arr[i] / exp) % 10] - 1] = arr[i];  
        count[(arr[i] / exp) % 10]--;  
    }  

    // 将排序后的数据拷贝到原数组  
    for (int i = 0; i < n; i++)  
        arr[i] = output[i];  
}  

// 基数排序主函数  
void RadixSort(int arr[], int n) {  
    int max = getMax(arr, n); // 找到最大数  

    // 对每一位进行计数排序  
    for (int exp = 1; max / exp > 0; exp *= 10)  
        countingSort(arr, n, exp);  
}

int main()
{
    //直接插入排序
    int arr[] = {1,5,1,8,42,464,425,888,999,4541};
    int n = sizeof(arr) / sizeof(arr[0]); //求元素个数;
    InsertSort(arr,n);
    printf("直接插入排序序列为:");
    for(int i=0;i<n;i++)
        printf("%d ",arr[i]);
    printf("\n");

    //希尔排序
    int arr2[] = {1,5,1,8,42,464,425,888,999,4541,318,985,211,350};
    int n2 = sizeof(arr2) / sizeof(arr2[0]);
    ShellSort(arr2,n2);
    printf("希尔排序序列为:");
    for(int i=0;i<n2;i++)
        printf("%d ",arr2[i]);
    printf("\n");

    //冒泡排序
    int arr3[] = {1,5,1,8,42,464,425,888,999,4541,318,985,211,350,555,777};
    int n3 = sizeof(arr3) / sizeof(arr3[0]);
    printf("冒泡排序序列为:");
    BubbleSort(arr3,n3);
    for(int i=0;i<n3;i++)
        printf("%d ",arr3[i]);
    printf("\n");

    //快速排序
    int arr4[] = {1,5,1,8,42,464,425,888,999,4541,318,985,211,350,555,777,15454,4543,451299,11243};
    int n4 = sizeof(arr4) / sizeof(arr4[0]);
    printf("快速排序序列为:");
    QuickSort(arr4,0,n4-1);
    for(int i=0;i<n4;i++)
        printf("%d ",arr4[i]);
    printf("\n");

    //简单选择排序
    int arr5[] = {1,5,1,8,42,464,425,888,999,4541,318,985,211,350,555,777,15454,4543,451299,11243,151515,44848,451964,3,2,45,82,11};
    int n5 = sizeof(arr5) / sizeof(arr5[0]); //求元素个数;
    InsertSort(arr5,n5);
    printf("直接插入排序序列为:");
    for(int i=0;i<n5;i++)
        printf("%d ",arr5[i]);
    printf("\n");

    //归并排序
    int arr6[] = {1,5,1,8,42,464,425,888,999,4541,318,985,211,350,555,777,15454,4543,451299,11243,151515,44848,451964,3,2,45,82,11,12,18,54,44};
    int n6 = sizeof(arr6) / sizeof(arr6[0]);
    MergeSort(arr6,0,n6-1);
    printf("归并排序序列为:");
    for (int i=0;i<n6;i++)
        printf("%d ",arr6[i]);
    printf("\n");

    //堆排序
    int arr7[] = {4541,318,985,211,350,555,777,15454,4543,451299,11243,151515,44848,451964,3,2,45,82,11,12,18,54,44,45151,1548481,2495269,1548299};
    int n7 = sizeof(arr7) / sizeof(arr7[0]);
    HeapSort(arr7,n7);
    printf("堆排序序列为:");
    for (int i=0;i<n7;i++)
        printf("%d ",arr7[i]);
    printf("\n");

    //基数排序
    int arr8[] = {616582,4541,318,985,211,350,555,777,15454,4543,451299,11243,151515,44848,451964,3,2,45,82,11,12,18,54,44,45151,1548481,2495269,1548299};
    int n8 = sizeof(arr8) / sizeof(arr8[0]);
    RadixSort(arr8,n8);
    printf("基数排序序列为:");
    for (int i=0;i<n8;i++)
        printf("%d ",arr8[i]);
    printf("\n");
}

运行结果如图:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值