排序算法的代码-交换排序(考快速排序的代码)

目录

过程:

冒泡排序

快速排序

有递归和非递归两种方式,经常考代码。一定要理解、会背代码、会敲代码。

递归

非递归​​​​​​​​​​​​​​


过程:

第一遍:按照自己的理解整出代码。

冒泡排序遇到的问题:

1、冒泡排序的函数名称叫什么呢?bubble:气泡的意思。所以叫Bubblesort。

2、思想有了,但是脑子里浮现的大致步骤和课本上的不大一样。

3、没有想过,怎样才是已经有序啦?应该想到使用一个flag来标志一下的。

快速排序遇到的问题:

1、已经忘了快速排序的步骤与做法。

2、有递归和非递归两种方式,但是,看到递归两个字就害怕。两种模式都不会写。

3、快速排序名字:QuickSort

4、while(low<high && a[high] >= pivot){--high;}

我在敲快速排序的代码时,使用的是high >= pivot,但是pivot是一个元素值,不是一个下标,应该用a[high]>=pivot才对。并且,不明白为什么要有low<high????,

我找到答案了:这里的low和high都是下标,防止pivot就是最小的元素,所以一直满足a[high]>= pivot,就会一直--high,然后越界,low< high是防止越界的。

总结一下。要分清下标和元素值。

5、忘了返回low的值,也就是说,我只敲出了一趟的代码,没有想过以后怎么办,只有返回low的值,才能令pivot 重新=low。开始新一轮的循环。

啊,不对,自作多情了。。。这里 return low;是为了后面的 a[low] = pivot;这里a[low] = pivot,是因为排序之后会空出来一个位置,这个位置就是需要填入pivot。

开启新循环是后面调用这个函数的事情。。。

6、注意 partition函数里的形参是(ElemType a[], int low, int high)

7、想不出非递归的方法。

第二遍:忘了不少啊。。。废物

冒泡排序

思想:在每一趟里找出一个最小值(或最大值),安顿好它的位置。接下来在剩余的元素里继续寻找。每次寻找到的元素就会确定它的最终位置。

所采用的比较方式是相邻的两个元素进行比较,若a[j-1]<a[j],则交换位置。那么,在一趟过去后,并不是除了最小值跑到开头的位置外,其他元素相对位置不变,而是只要符合换位置条件就会两两交换,所以每一趟发生的交换次数未知。

//C语言里其实并没有交换这一基本函数,只能自己敲一个。
void swap(int *a,int *b)
{
    int temp;
    temp = *a;
    *a = *b;
    *b = temp;
}

//冒泡排序,本次以选出最小的为例。
void BubbleSort(ElemType a[],int n)    //不需要一个特殊的a[0]了,所以,0~n-1.
{
    for (int i = 0; i < n-1; i++)
    {
        flag = false;//表示本趟冒泡排序是否发送交换
        for (int j = n-1; j >= i;j--)   //一趟冒泡过程
        {
            
            if (a[j] < a[j-1])
            {
               swap(a[j-1],a[j]);//交换
               flag = true;
            }  
        }
        if(flag == false)
        {
            return;
            /*注意到:在该for循环里,每次都将flag置为false,
                若没发生交换,则不会有对flag的赋值为true。
                则说明已经有序,排序完毕。
            */
        }  
    }
}

快速排序

思想:选定一个枢轴(一般是首元素)。从两头开始,往中间走,若最后一个小于所选的枢轴值,则换到前面来,放在枢纽所在的位置,那么后面就会空出来一个位置,从枢轴后一个开始选,选出一个大于枢轴的元素放在空出来的位置,那么此时前面又空出来一个,再从后面选一个元素放在空出来的位置…。直到无法交换,把枢轴放在空出来的位置上,此时就形成了枢轴左边的元素都比枢轴小,右边的都比枢轴大。(与枢轴的远近只代表交换的前后顺序,与大小关系不大)。

递归

//划分操作:将比枢轴(pivotpos)小的元素放在枢轴左边,比枢轴大的元素放在枢轴右边。
int Partition(ElemType a[],int low,int high)    //一趟划分
{
    ElemType 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];//将比枢轴大的元素移动到右端
        return low;   
    }
    a[low] = pivot;    
}

//快速排序·递归方式。
void QuickSort(ElemType a[],int n)
{
    if (low < high) //递归跳出条件
    {
        int pivotpos = partition (a,low,high);
        //partition()就是划分操作,将表a[low...high]划分为满足上述条件的两个子表
        QuickSort(a,low,pivotpos-1);
//这里的pivotpos= partition返回的值,也就是枢轴所在的位置,low.
//因为C语言的特性,这里的low 和 partition返回的low是两个low,指向两个不同的地方。
        QuickSort(a,pivotpos+1,high);
        
    }   
}

非递归

递归的算法主要是在划分子区间,如果要非递归实现快速排序,只要使用一个栈来保存区间就可以了。
一般将递归程序改成非递归首先想到的就是使用栈,因为递归本身就是一个压栈的过程。​​​​​​​

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Wmpreturn

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

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

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

打赏作者

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

抵扣说明:

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

余额充值