排高低:冒泡與插入排序。不要管別人,自己設計的才是自己的。
算法問題的一個分類:排高低。
背景:有一系列的值,有大有小,由於某個目的(比如兩兩分組讓最小者的和最大、比如容納最多和不超過某個值的元素、等等),需要先把它們排一下高低。
一個數值數組,怎麽給裏面的元素排出高低(比如由小到大地排序)?
兩兩比較不是問題,要解決的是這兩個問題:
* 誰跟誰比,怎麽安排?
* 比後怎麽處置,怎麽讓問題變小?
全由你來設計!
設計原則:讓問題變小,最終沒有。
不能隨意地比較,比如安排單數的元素來比較,這個設計看不出能解決問題。
不能比完之後卻沒有進一步的動作,只比較卻不記錄也不作換位之類,明顯沒有意義。
誰來比,以及比後怎麽處置,不同的安排,產生不同的算法。
為了簡化思考,可以只考慮只有兩個元素的情況。
比如:
* 讓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” 博客,轉載請與作者聯系!
排高低:冒泡與插入排序。不要管別人,自己設計的才是自己的。