排高低:冒泡与插入排序。不要管别人,自己设计的才是自己的。

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;

            }   

        }   

    }   

}


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;

}


本文出自 “13126504” 博客,转载请与作者联系!

以上是关于排高低:冒泡与插入排序。不要管别人,自己设计的才是自己的。的主要内容,如果未能解决你的问题,请参考以下文章

总结4种常用排序(快排选择排序冒泡排序插入排序)

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

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

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

我知道你会冒泡排序,但是你会优化冒泡排序吗?

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