C语言奇偶数交换排序问题

目录

问题描述如下:

move函数的具体实现:

main函数

运行效果

代码(注意看注释):


问题描述如下:

给定一个整数数组,要求将其中的奇数元素全部移动到前面,偶数元素全部移动到后面,但不要求奇数和偶数内部的具体顺序。

move函数的具体实现:

cpp 复制代码
void move(int* p, int sz) {
    // 验证输入指针有效性
    assert(p);

    int left = 0; // 初始化左下标为0
    int right = sz - 1; // 初始化右下标为数组长度减1

    // 当左下标小于右下标时,循环执行交换操作
    while (left < right) 
    {
        // 从前往后查找第一个偶数元素
        while ((left < right) && (p[left] % 2 == 1)) 
        {
            left++;
        }
        // 从后往前查找第一个奇数元素
        while ((left < right) && (p[right] % 2 == 0)) 
        {
            right--;
        }

        // 如果左下标仍然小于右下标,说明找到可交换的一对奇偶数
        if (left < right)
        {
            // 交换这两个元素
            int tmp = p[left];
            p[left] = p[right];
            p[right] = tmp;
        }
    }
}

我们关注move函数的核心逻辑部分:

cpp 复制代码
// 从前往后查找第一个非奇数(即偶数)元素
while ((left < right) && (p[left] % 2 == 1)) 
{
    left++;
}

但实际上代码是准确无误的。该段代码的作用是从数组的起始位置(左下标left处)开始,向右遍历查找第一个偶数元素。这是因为我们的目标是在保持奇数在前的前提下,找到数组中首个"非奇数"位置。初始状态下,由于数组的左侧可能是连续的奇数,所以需要先越过这些奇数,找到第一个偶数。

接下来是右侧指针的操作:

cpp 复制代码
// 从后往前查找第一个奇数元素
while ((left < right) && (p[right] % 2 == 0))
{
    right--;
}

这段代码则是从数组的末尾(右下标right处)开始,向左遍历以寻找第一个奇数元素。这样,当左右指针分别定位到一个奇数和一个偶数时,就可以执行交换操作:

cpp 复制代码
if (left < right)
{
    // 交换这两个元素
    int tmp = p[left];
    p[left] = p[right];
    p[right] = tmp;
}

通过这种方式,每次循环都会确保一对奇偶数被成功地进行交换,直到所有奇数都被移动到数组的前面为止。

main函数

main函数中创建了一个包含8个元素的数组arr,并调用move函数对其进行处理,之后调用print_t函数输出处理后的数组内容,以验证move函数的效果。

cpp 复制代码
int main() {
    int arr[] = {1, 2, 3, 4, 5, 6, 7, 8};
    int sz = sizeof(arr) / sizeof(arr[0]);
    
    // 调用move函数实现奇偶数交换
    move(arr, sz);
    
    // 打印交换后的数组
    print_t(arr, sz);

    return 0;
}

运行效果

代码(注意看注释):

cpp 复制代码
// move函数用于将数组中的奇数移到前面,偶数移到后面
void move(int* p, int sz) {
    assert(p); // 验证输入指针有效性
    
    int left = 0; // 初始化左下标为0
    int right = sz - 1; // 初始化右下标为数组长度减1

    // 主循环:当左下标小于右下标时持续执行交换操作
    while (left < right) 
    {
        // 从前往后查找第一个非奇数(即偶数)元素
        // 这里的目的是找到奇数区域的边界,越过连续的奇数
        while ((left < right) && (p[left] % 2 == 1)) 
        {
            left++;
        }

        // 从后往前查找第一个奇数元素
        // 这里是找到偶数区域的边界,以便与左侧找到的偶数进行交换
        while ((left < right) && (p[right] % 2 == 0))
        {
            right--;
        }

        // 如果左下标仍然小于右下标,则找到了一对可交换的奇偶数
        if (left < right)
        {
            // 交换这两个元素
            int tmp = p[left];
            p[left] = p[right];
            p[right] = tmp;
        }
    }
}

// 辅助函数,用于打印数组元素
void print_t(int* p, int sz){
    for (int i = 0; i < sz; i++)
    {
        printf("%d ", p[i]);
    }
}

// 主程序入口
int main() {
    int arr[] = {1, 2, 3, 4, 5, 6, 7, 8};
    int sz = sizeof(arr) / sizeof(arr[0]);

    // 调用move函数对数组arr进行奇偶数交换
    move(arr, sz);

    // 打印交换后的数组元素
    print_t(arr, sz);

    return 0;
}
相关推荐
apcipot_rain1 小时前
计科八股20260616(1)——堆存中位数、链表判环、黑白测试、敏捷开发与瀑布模型、配置管理、持续集成、池化
数据结构·算法·软件工程
JAVA面经实录9178 小时前
Java 数据结构与算法 (终极完整学习文档)
java·数据结构·算法
影视飓风TIM10 小时前
数据结构 | 链表超全笔记(单链表+双链表+高频算法题)
数据结构·笔记·链表
牛油果子哥q11 小时前
STL set与map底层精讲,红黑树适配原理、有序去重特性、迭代器遍历、API实战与面试核心考点全解
开发语言·数据结构·c++·面试
一切皆是因缘际会12 小时前
LLM轻量化联邦微调机理
数据结构·人工智能·数学建模·ai
玖玥拾13 小时前
C/C++ 数据结构(六)链表迭代器与底层
c语言·数据结构·c++·链表·stl库
牛油果子哥q13 小时前
AVL平衡树与红黑树深度精讲对比,平衡因子、四大旋转原理、着色规则、平衡策略、性能差异与面试手撕全解
数据结构·c++·面试
Irissgwe14 小时前
map/set/multimap/multiset 的底层逻辑与实现
数据结构·c++·算法·二叉树·stl·c·红黑树
IronMurphy14 小时前
【算法五十八】23. 合并 K 个升序链表
数据结构·算法·链表
noipp15 小时前
【无标题】
c语言·数据结构·c++·算法