插入&冒泡排序 | 算法就是你的设计

Posted 编程牛人

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了插入&冒泡排序 | 算法就是你的设计相关的知识,希望对你有一定的参考价值。

我们是喜欢比较的,正如羡慕忌妒与攀比

这种比较就是要给出一个高低排序之分。

如何得到排序结果自然就是算法的问题。


算法问题的一个分类:排序。


问题是需要抽象的。退,退到最简单而不失真的状态,是一种重要技巧。

所以,我们有理由,只对数值数组排序!



怎么排序?

要解决的是两个问题:

* 谁跟谁比,怎么安排?

* 比完后怎么处置,怎么让问题变小?


全由你来设计!


设计原则:让问题变小,最终没有。


不能随意地比较,比如安排单数的元素来比较,这个设计能解决问题吗?

不能比完之后没有进一步的动作,只比较却不记录也不作换位之类,明显没有意义。


谁来比,以及比后怎么处置,不同的安排,产生不同的算法。


为了简化思考,那就考虑只有两个元素的情况吧,真的只需要比较两个元素,好简单的。


比如:


        让n1跟n2比较,如果n1>n2,则值互换位置,让n1最小。

然后,继续让n1与n3比较,同样最小的放到n1。

全部比较完后,第一个位置就是最小的,之后再同样考虑第二个位置(问题规模在收敛)。

这是“冒泡排序”算法。


让n1跟最后一个比较,再跟倒数第二个比较,...,小的放到n1。

再考虑n2...。

这是“冒泡排序”算法。


让n1跟n2比,n2跟n3比...,大者放到后面。

一轮下来,最后的位置就是最大值,然后放过这个位置再重复。

这是“冒泡排序”算法。


模拟排队(从一个都没有开始),从左往右,找到一个比自己高的元素,排到前面。

这是“插入排序”。

注意,“谁来比”不要有遗漏,否则不公平。

公平是很重要的!


以上,更多想说明,你可以自己设计,并不一定要从已知的算法去思考。


然后,就是代码细节了,这些不重要啦,设计思想才是重要的,而你已经想通啦。



代码示例


#include <stdio.h>

#include <stdlib.h>

#include <string.h>


void bubble1(int* arr, int size) {

    for (int i = 0; i < size-1; i ++) {

        for (int j = i+1; j < size; j ++) {

            if (arr[i] > arr[j]) {

                arr[i]=arr[i] ^ arr[j];

                arr[j]=arr[i] ^ arr[j];

                arr[i]=arr[i] ^ arr[j];

            }

        }

    }

}


void bubble2(int* arr, int size) {

    for (int i = 0; i < size-1; i ++) {

        for (int j = size-1; j > i; j --) {

            if (arr[i] > arr[j]) {

                arr[i]=arr[i] ^ arr[j];

                arr[j]=arr[i] ^ arr[j];

                arr[i]=arr[i] ^ arr[j];

            }

        }

    }

}


void bubble3(int* arr, int size) {

    int count = size;

    while (count) {

        for (int i = 0; i < count-1; i ++) {

            if (arr[i] > arr[i+1]) {

                arr[i]=arr[i] ^ arr[i+1];

                arr[i+1]=arr[i] ^ arr[i+1];

                arr[i]=arr[i] ^ arr[i+1];

            }       

        }

        count --;

    }

}


// 多用一个临时组

void insertsort(int* arr, int size) {

    int* tmparr=(int*)malloc(sizeof(int) * size);

    memcpy(tmparr, arr, size*sizeof(int));

    int count = 0;

    for (int i = 0; i < size; i ++) {

        int j=0;

        for (j = 0; j < count; j ++) {

            if (arr[i]<tmparr[j]) {

                memcpy(tmparr+j+1, tmparr+j, (size-j-1)*sizeof(int));

                tmparr[j]=arr[i];

                break;

            }

        }

        if (j==count) {

            tmparr[j]=arr[i];   

        }

        count ++;

    }

    memcpy(arr, tmparr, size*sizeof(int));

    free(tmparr);

}


// 就地insert

void insertsort2(int* arr, int size) {

    for (int i = 0; i < size; i ++) {

        for (int j = 0; j < i; j ++) {

            if (arr[i] < arr[j]) {

                int t = arr[i];

                memcpy(arr+j+1, arr+j, (i-j)*sizeof(int));

                arr[j]=t;

                break;

            }   

        }   

    }   

}


// 就地insert,另一个思路:从右向左比较,边比较边移动元素(保持小值在前,大值移后)。


int main(int argc, char *argv[])

{

    int arr[] = {5, 3, 6, 1, 2};

    int size = sizeof arr/sizeof *arr;

    /*bubble3(arr, size);*/

    insertsort2(arr, size);

    for (int i = 0; i < size; i ++) {

        printf("%d, ", arr[i]);

    }

    return 0;

}



以上是关于插入&冒泡排序 | 算法就是你的设计的主要内容,如果未能解决你的问题,请参考以下文章

排序算法复习:直接插入排序堆排序快排冒泡排序

Java排序算法分析与实现:快排冒泡排序选择排序插入排序归并排序

链表排序(冒泡选择插入快排归并希尔堆排序)

排序算法学习(直接插入排序,希尔排序,选择排序,堆排序,冒泡排序)

算法分析与设计——各类排序算法

排序算法3---插入排序