排序的一些算法

双向冒泡排序,正反两个方向交替进行扫描,第一趟把关键字最大的元素放在序列后面,第二趟把关键元素最小的放在前面,如此反复

奇数趟时,从前往后比较相邻元素关键字,冒泡,最大的到尾部
偶数趟时,从后往前比较相邻元素关键字,冒泡,最小的到前面

void BubbleSort(int A[], int n)
{
    int low = 0, high = n - 1;
    bool flag = true; // 一趟冒泡后记录元素是否交换标志

    while (low < high && flag) // 循环跳出条件:当flag为false时说明已没有逆序
    {
        flag = false;
        // 正向起泡
        for (int i = low; i < high; i++)
        {
            if (A[i] > A[i + 1])
            {
                swap(A[i], A[i + 1]);
                flag = true;
            }
            high--; // 更新上界
        }

        // 逆向气泡
        for (int j = high; high > low; high--)
        {
            if (A[j] < A[j - 1])
            {
                swap(A[j], A[j - 1]);
                flag = true;
            }
            low++; // 修改下界
        }
    }
}

将顺序存储的线性表中的元素,把所有奇数移动到所有偶数前边的算法

利用快速排序的思想: 从前向后找到第一个偶数,再从后往前找到第一个奇数,二者交换,如此重复

void moveOddbeforeEven(int A[], int n)
{
    int i = 0;     // i表示左端偶数下标
    int j = n - 1; // j为右端奇数下标
    while (i < j)
    {
        // 从前往后找偶数
        while (A[i] % 2 != 0)
            i++;
        // 从后往前找奇数
        while (i < j && A[j] % 2 == 0)
            j--;
        if (i < j)
        {
            swap(A[i], A[j]);
            i++;
            j--;
        }
    }
}

设计一个算法能够在数组L[1…n]中找出第k小的元素

基于快排的思想

int Paratition(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;
    return low;
}
int kthSmallest(int A[], int low, int high, int k)
{
    if (k > 0 && k <= high - low + 1)
    {
        int pos = Paratition(A, low, high);
        if (pos - low == k - 1)
            return A[pos];
        // 如果pos比第k小的元素的位置大,则在pos的左边继续寻找第k小的元素
        if (pos - low > k - 1)
        {
            return kthSmallest(A, low, pos - 1, k);
        }
        // 如果pos比第k小的元素的位置小,则在pos的右边继续寻找第k-pos+low-1小的元素
        return kthSmallest(A, pos + 1, high, k - pos + low - 1);
    }
    return -1;
}
// 或p329 5题
int kth_elem(int A[], int low, int high, int k)
{
    int pivot = A[low];
    int low_temp = low;
    int high_temp = high;
    while (low < high)
    {
        while (A[high] >= pivot && low < high)
            high--;
        A[low] = A[high];
        while (A[low] <= pivot && low < high)
            low++;
        A[high] = A[low];
    }
    A[low] = pivot;
    // 以上为快排
    if (low == k)
        return A[low];
    else if (low > k)
        return kth_elem(A, low_temp, low - 1, k);
    else
        return kth_elem(A, low + 1, high_temp, k);
}
// 或p329 5题
int kth_elem(int A[], int low, int high, int k)
{
    int pivot = A[low];
    int low_temp = low;
    int high_temp = high;
    while (low < high)
    {
        while (A[high] >= pivot && low < high)
            high--;
        A[low] = A[high];
        while (A[low] <= pivot && low < high)
            low++;
        A[high] = A[low];
    }
    A[low] = pivot;
    // 以上为快排
    if (low == k)
        return A[low];
    else if (low > k)
        return kth_elem(A, low_temp, low - 1, k);
    else
        return kth_elem(A, low + 1, high_temp, k);
}

基于单链表表示的待排序关键字进行简单选择排序

// 假设不带头结点
void selectSort(LinkList L)
{
    LinkList p = L;
    while (p != NULL)
    {
        LinkList min = p;
        LinkList temp = p->next;
        while (temp != NULL)
        {
            if (temp->data < min->data)
            {
                min = temp;
            }
            temp = temp->next;
        }
        int t = min->data;
        min->data = p->data;
        p->data = t;

        p = p->next;
    }
}

判断一个序列是否构成小根堆

bool isMinHeap(int arr[], int n)
{
    for (int i = 0; i <= (n - 2) / 2; i++)
    {
        // 检查左子节点
        if (2 * i + 1 < n && arr[i] > arr[2 * i + 1])
        {
            return false;
        }
        // 检查右子节点
        if (2 * i + 2 < n && arr[i] > arr[2 * i + 2])
        {
            return false;
        }
    }
    return true;
}

快速排序非递归

// 获取分区点的函数
int partition(int arr[], int low, int high) {
    int pivot = arr[high]; // 选择最后一个元素作为枢纽元素
    int i = (low - 1);

    for (int j = low; j <= high - 1; j++) {
        if (arr[j] < pivot) {
            i++;
            swap(&arr[i], &arr[j]); // 将小于枢纽元素的值交换到左侧
        }
    }
    swap(&arr[i + 1], &arr[high]); // 将枢纽元素放到正确的位置
    return (i + 1); // 返回枢纽元素的位置
}

// 快速排序的非递归函数
void quickSort(int arr[], int low, int high) {
    int stack[high - low + 1]; // 定义一个栈
    int top = -1;

    stack[++top] = low; // 将初始低位和高位压入栈
    stack[++top] = high;

    while (top >= 0) {
        high = stack[top--]; // 弹出栈顶的低位和高位
        low = stack[top--];

        int p = partition(arr, low, high); // 对当前区间进行分区操作

        if (p - 1 > low) { // 如果左子区间存在元素,则将左子区间的低位和高位压入栈
            stack[++top] = low;
            stack[++top] = p - 1;
        }

        if (p + 1 < high) { // 如果右子区间存在元素,则将右子区间的低位和高位压入栈
            stack[++top] = p + 1;
            stack[++top] = high;
        }
    }
}

简单选择的递归

void selectionSort(int arr[], int n, int index) {
    if (index >= n - 1) {
        return; // 递归结束条件:当index超出数组范围时,结束递归
    }

    int minIndex = index;
    for (int i = index + 1; i < n; i++) {
        if (arr[i] < arr[minIndex]) {
            minIndex = i; // 找到最小元素的下标
        }
    }

    swap(&arr[minIndex], &arr[index]); // 将最小元素与当前位置交换

    selectionSort(arr, n, index + 1); // 对剩余元素进行递归排序
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wu丶ying

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值