探讨两种循环表示方法的区别,while循环与for循环的小总结

基于前天建立的顺序表(sequeue)的其中一个功能函数,引出两个循环的表示方法的区别和比较。

算法需求:在一个顺序队列中,合并相同的元素。

总体思路:利用两层循环的框架,利用外层循环选中顺序表中第一个数(L->data[i]),再用内循环中进行对比(L->data[j]),如果相同就进行删除操作。

首先采用for循环:

int list_purge(sqlink L)
{
    int i = 1;
    int j;
    if (L->last == 0)//如果顺序表内只有一个函数,则无重复元素直接返回。
        return 0;
        for (i = 1; i <= L->last; i++)//外层循环,选取顺序表中一个数值
    {
        for (j = i - 1; j >= 0; j--)//内层循环,将外层循环的数值依次与i-1以内的数值进行比较
        {
            if (L->data[i] == L->data[j])//若出现相同的情况,则进行删除操作
            {
                list_delete(L, i);
                break;
            }
        }
    }
    }

​ 为减少功能函数间的耦合,用了独立的删除功能函数,具体可见另一篇《基于C语言的顺序表的建立,及各类功能函数实现》,因不是重点,不讨论该函数。

​ 该算法较为简单,能实现基本功能。但有一个非常致命的问题:当出现连续三个需要操作的元素,无法连续删除其中两个。利用简单的几个数字测试,结果示例如下:

int main(int argc, const char *argv[])
{
    sqlink L;
    L = list_create();
    list_insert(L, 10, 0);
    list_insert(L, 20, 0);
    list_insert(L, 30, 0);
    list_insert(L, 20, 0);
    list_insert(L, 30, 0);
    list_show(L);
    list_purge(L);
    list_show(L);
    return 0;
}

运行结果:

​ 为方便分析,编写数组来说明,arr[0]=30;arr[1]=20;arr[2]=30;arr[3]=20;arr[4]=10;

​ 在第一轮循环中,arr[1]!=arr[0],没有相同元素。

​ 在第二轮循环中,arr[2]!=arr[1],arr[2] == arr[0],执行删除操作,删除之后变成了:arr[0]=30;arr[1]=20;arr[2]=20;arr[3]=10;即是在删除第一个相同元素后,整体元素往前移动。

​ 在第三轮循环中,arr[3]!=arr[2],arr[3]!=arr[1],arr[3] != arr[0],即第三轮无法将改变后的a[2]与a[1]进行比较,因此出现运行结果的错误。


因此,考虑采用while循环优化:

int list_purge(sqlink L)
{
    int i = 1;
    int j;
    if (L->last == 0)//如果顺序表内只有一个函数,则无重复元素直接返回。
        return 0;
    while (i <= L->last)//外层循环,选取顺序表中一个数值
    {
        j = i - 1;
        while (j >= 0)
        {
            if (L->data[i] == L->data[j])//内层循环,将外层循环的数值依次与i-1以内的数值进行比较
            {
                list_delete(L, i);//若出现相同的情况,则进行删除操作
                break;
            }
            else
                j--;
            if (j < 0)
                i++;
        }
    }

​ 分析如下,arr[0]=30;arr[1]=20;arr[2]=30;arr[3]=20;arr[4]=10:

​ 在第一轮循环中,arr[1]!=arr[0],没有相同元素。

​ 在第二轮循环中,arr[2]!=arr[1],arr[2] == arr[0],执行删除操作,删除之后变成了:arr[0]=30;arr[1]=20;arr[2]=20;arr[3]=10;整体元素往前移动。

​ 将遍历指数j和i都放进内循环,导致的直接结果是,当进行list_delete(L, i)操作后,通过“break”退出内循环,会重新进行比较,成功解决了重复元素无法删除的问题。

​ 因此运行结果如下:

...

​ 通过这个例子,可较直接理解while与for循环的区别,即在遍历过程中,for的末尾循环体(increment)会直接需要应用在下次循环,而while可在遍历过程结束之后才进行increment操作。总结一句话就是:while遍历更充分。

​ 记录在此供参考学习,如有不足之处,敬请批评指针,欢迎交流。

热门相关:恶魔总裁霸道宠:老婆,太惹火   我拍戏不在乎票房   前夫有毒:1000万夺子契约   驭房我不止有问心术   聊斋大圣人