插入&冒泡排序 | 算法就是你的设计
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排序算法分析与实现:快排冒泡排序选择排序插入排序归并排序