C语言实现数组奇偶数位置调整的三种方法

 更新时间:2026年06月16日 08:41:14   作者:十月的皮皮  
这篇文章主要介绍了三种调整整数数组顺序的方法,包括原地交换法、额外数组分离存储法和冒泡相邻交换法;详细解释了每种方法的算法思路、特点和代码实现;特别强调了空间和时间复杂度的权衡,需要的朋友可以参考下

功能需求

输入一个整数数组,调整该数组的顺序使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。

方法一:原地交换法(双指针)

算法思路
使用双指针技术,左指针从数组开头向右移动,右指针从数组末尾向左移动:

•左指针寻找偶数(需要移动到后半部分的元素)

•右指针寻找奇数(需要移动到前半部分的元素)

•当找到需要交换的元素对时,进行交换操作

代码实现

void Change_arr(int arr[], int n)
{
    int left = 0;
    int right = n - 1;

    while (left < right)
    {
        // 左指针向右移动,跳过奇数(不需要移动的元素)
        while (left < right && arr[left] % 2 != 0)
        {
            left++;
        }
        // 右指针向左移动,跳过偶数(不需要移动的元素)
        while (left < right && arr[right] % 2 == 0)
        {
            right--;
        }
        // 交换奇偶元素
        if (left < right)
        {
            int temp = arr[left];
            arr[left] = arr[right];
            arr[right] = temp;
            left++;
            right--;
        }
    }
}

算法特点

• 优点:空间效率高,只需要常数额外空间

• 缺点:相对复杂,需要仔细处理边界条件

• 稳定性:不稳定,会改变相同类型元素的相对顺序

方法二:额外数组分离存储

算法思路
使用一个临时数组,分两步存储:

  1. 第一次遍历:将所有奇数按原顺序存入临时数组
  2. 第二次遍历:将所有偶数按原顺序存入临时数组
  3. 将临时数组内容复制回原数组

代码实现

void Change_arr(int arr[], int n)
{
    int temp[100]; // 临时数组,存放结果
    int idx = 0;

    // 第一步:先存所有奇数
    for (int i = 0; i < n; i++)
    {
        if (arr[i] % 2 == 1)
        {
            temp[idx++] = arr[i];
        }
    }
    // 第二步:再存所有偶数
    for (int i = 0; i < n; i++)
    {
        if (arr[i] % 2 == 0)
        {
            temp[idx++] = arr[i];
        }
    }
    // 把临时数组数据拷贝回原数组
    for (int i = 0; i < n; i++)
    {
        arr[i] = temp[i];
    }
}

算法特点

• 优点:逻辑清晰,易于理解和实现

• 缺点:需要额外的数组空间

• 稳定性:稳定,保持了相同类型元素的相对顺序

方法三:冒泡相邻交换法

算法思路

类似于冒泡排序的思想,通过相邻元素的比较和交换:

• 遍历数组,比较相邻的两个元素

• 如果前一个是偶数,后一个是奇数,则交换它们

• 这样奇数会逐渐"冒泡"到数组的前面

代码实现

void Change_arr(int arr[], int n)
{
    // 外层循环控制遍历轮数
    for (int i = 0; i < n; i++)
    {
        // 内层相邻两两对比
        for (int j = 0; j < n - 1 - i; j++)
        {
            // 前偶数、后奇数,交换位置
            if (arr[j] % 2 == 0 && arr[j + 1] % 2 == 1)
            {
                int tmp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = tmp;
            }
        }
    }
}

算法特点

• 优点:实现简单,逻辑直观

• 缺点:时间复杂度较高,效率较低

• 稳定性:稳定,但效率不如方法二

完整测试代码

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

// 方法1:原地交换
void Change_arr_method1(int arr[], int n)
{
    int left = 0;
    int right = n - 1;

    while (left < right)
    {
        while (left < right && arr[left] % 2 != 0)
        {
            left++;
        }
        while (left < right && arr[right] % 2 == 0)
        {
            right--;
        }
        if (left < right)
        {
            int temp = arr[left];
            arr[left] = arr[right];
            arr[right] = temp;
            left++;
            right--;
        }
    }
}

// 方法2:额外数组
void Change_arr_method2(int arr[], int n)
{
    int temp[100];
    int idx = 0;

    for (int i = 0; i < n; i++)
    {
        if (arr[i] % 2 == 1)
        {
            temp[idx++] = arr[i];
        }
    }
    for (int i = 0; i < n; i++)
    {
        if (arr[i] % 2 == 0)
        {
            temp[idx++] = arr[i];
        }
    }
    for (int i = 0; i < n; i++)
    {
        arr[i] = temp[i];
    }
}

// 方法3:冒泡交换
void Change_arr_method3(int arr[], int n)
{
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n - 1 - i; j++)
        {
            if (arr[j] % 2 == 0 && arr[j + 1] % 2 == 1)
            {
                int tmp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = tmp;
            }
        }
    }
}

int main()
{
    int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
    int arr2[10] = { 1,2,3,4,5,6,7,8,9,10 };
    int arr3[10] = { 1,2,3,4,5,6,7,8,9,10 };

    printf("原数组: ");
    for (int i = 0; i < 10; i++)
    {
        printf("%d ", arr1[i]);
    }
    printf("\n");

    Change_arr_method1(arr1, 10);
    printf("方法1结果: ");
    for (int i = 0; i < 10; i++)
    {
        printf("%d ", arr1[i]);
    }
    printf("\n");

    Change_arr_method2(arr2, 10);
    printf("方法2结果: ");
    for (int i = 0; i < 10; i++)
    {
        printf("%d ", arr2[i]);
    }
    printf("\n");

    Change_arr_method3(arr3, 10);
    printf("方法3结果: ");
    for (int i = 0; i < 10; i++)
    {
        printf("%d ", arr3[i]);
    }
    printf("\n");

    return 0;
}

到此这篇关于C语言实现数组奇偶数位置调整的三种方法的文章就介绍到这了,更多相关C语言数组奇偶数位置调整内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C语言动态内存分配图文讲解

    C语言动态内存分配图文讲解

    给数组分配多大的空间?你是否和初学C时的我一样,有过这样的疑问。这一期就来聊一聊动态内存的分配,读完这篇文章,你可能对内存的分配有一个更好的理解
    2023-01-01
  • Qt如何设置窗口屏幕居中显示以及设置大小

    Qt如何设置窗口屏幕居中显示以及设置大小

    这篇文章主要介绍了Qt如何设置窗口屏幕居中显示以及设置大小的相关资料,需要的朋友可以参考下
    2017-01-01
  • 最短时间学会基于C++实现DFS深度优先搜索

    最短时间学会基于C++实现DFS深度优先搜索

    常见使用深度优先搜索(DFS)以及广度优先搜索(BFS)这两种搜索,今天我们就来讲讲什么是深度优先搜索,感兴趣的可以了解一下
    2021-08-08
  • C++线性时间的排序算法分析

    C++线性时间的排序算法分析

    这篇文章主要介绍了C++线性时间的排序算法分析,是非常经典的非比较排序算法,对于C++程序员有很大的借鉴价值,需要的朋友可以参考下
    2014-08-08
  • QT使用QSS进行界面美化的完整步骤记录

    QT使用QSS进行界面美化的完整步骤记录

    qss样式表和css层叠样式表是差不多的东西,都是用于设置QT程序UI界面中控件的背景图片、大小、字体颜色、字体类型、按钮状态变化等属性,这篇文章主要介绍了QT使用QSS进行界面美化的相关资料,需要的朋友可以参考下
    2025-08-08
  • Qt 5.9使用VTK显示点云的详解详解

    Qt 5.9使用VTK显示点云的详解详解

    这篇文章主要介绍了Qt 5.9使用VTK显示点云,主要包括PCL安装及在VS2013中使用PCL的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-07-07
  • C语言中常量指针与指针常量区别浅析

    C语言中常量指针与指针常量区别浅析

    这篇文章主要介绍了C语言中常量指针与指针常量区别,有需要的朋友可以参考一下
    2013-12-12
  • C语言中二级指针解析(指向指针的指针)

    C语言中二级指针解析(指向指针的指针)

    这篇文章主要介绍了C语言中二级指针(指向指针的指针),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-05-05
  • VScode中C++头文件问题的终极解决方法详析

    VScode中C++头文件问题的终极解决方法详析

    最近使用VSCode编译C/C++时发现了问题,下面这篇文章主要给大家介绍了关于VScode中C++头文件问题的终极解决方法,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-08-08
  • c++定义全局变量详解

    c++定义全局变量详解

    这篇文章主要给大家介绍了C++语言中定义全局变量,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2021-10-10

最新评论