1. 程式人生 > >排高低:冒泡與插入排序。不要管別人,自己設計的才是自己的。

排高低:冒泡與插入排序。不要管別人,自己設計的才是自己的。

算法

算法問題的一個分類:排高低。

背景:有一系列的值,有大有小,由於某個目的(比如兩兩分組讓最小者的和最大、比如容納最多和不超過某個值的元素、等等),需要先把它們排一下高低。

一個數值數組,怎麽給裏面的元素排出高低(比如由小到大地排序)?

技術分享

兩兩比較不是問題,要解決的是這兩個問題:

* 誰跟誰比,怎麽安排?

* 比後怎麽處置,怎麽讓問題變小?

全由你來設計!

設計原則:讓問題變小,最終沒有。

不能隨意地比較,比如安排單數的元素來比較,這個設計看不出能解決問題。

不能比完之後卻沒有進一步的動作,只比較卻不記錄也不作換位之類,明顯沒有意義。

誰來比,以及比後怎麽處置,不同的安排,產生不同的算法。

為了簡化思考,可以只考慮只有兩個元素的情況。

比如:

* 讓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” 博客,轉載請與作者聯系!

排高低:冒泡與插入排序。不要管別人,自己設計的才是自己的。