排高低:冒泡与插入排序。不要管别人,自己设计的才是自己的。
2017-07-18 00:02
543 查看
算法问题的一个分类:排高低。背景:有一系列的值,有大有小,由于某个目的(比如两两分组让最小者的和最大、比如容纳最多和不超过某个值的元素、等等),需要先把它们排一下高低。一个数值数组,怎么给里面的元素排出高低(比如由小到大地排序)?
两两比较不是问题,要解决的是这两个问题:
#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);}
// 就地insertvoid 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;}
两两比较不是问题,要解决的是这两个问题:
* 谁跟谁比,怎么安排?
* 比后怎么处置,怎么让问题变小?
全由你来设计!
设计原则:让问题变小,最终没有。
不能随意地比较,比如安排单数的元素来比较,这个设计看不出能解决问题。不能比完之后却没有进一步的动作,只比较却不记录也不作换位之类,明显没有意义。谁来比,以及比后怎么处置,不同的安排,产生不同的算法。
为了简化思考,可以只考虑只有两个元素的情况。比如:* 让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);}
// 就地insertvoid 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;}
相关文章推荐
- 排高低:冒泡与插入排序。不要管别人,自己设计的才是自己的。
- 只有自己才能对自己负责,别人的建议只能做参考。简单的才是最美的,不要以为将程序搞得复杂就好,其实简单的简洁的只要符合功能要求才是最完美的。
- 难过了,不要告诉别人。自己知道就好:伤感
- 看着自己有什么样的资源,利用好这些资源就好了。不要看着别人的资源流口水(转)
- 不是自己的事情不要问, 别人的事情不要管
- android入门,最好不要直接开发自己的3D项目,要多借鉴别人的项目
- 在自己强大之前,不要奢望别人主动帮助你
- 难过了,不要告诉别人。自己知道就好:伤感
- 难过了,不要告诉别人,自己知道就好
- 加入一个团队时要弄清楚自己在团队中投入的级别是什么, 别人的期望值是什么. 不要拿着卖白菜的钱, 操那卖白粉的心(转)
- 在自己强大之前,不要奢望别人主动帮助你
- 书到用时方恨少 做项目的时候才知道自己懂的东西少了,有时候会因为无知,导致比较重的后果。所以平时不断地学习,看论文啊,或者看别人的设计方案了
- 励志名言:不要仰望别人,自己亦是风景
- 挤不进的世界,不要硬挤;难为了别人,作贱了自己
- 选择自己想要的生活,不要太过于执着别人对你的看法和评价!
- 不要让明星产品,影响自己产品的设计
- 在自己强大之前,不要奢望别人主动帮助你
- 不要总活在自己和别人的世界里
- 麻烦别人 也不要麻烦自己
- 【随感】不要以为自己不足轻重而放任自己做一些事或一些话。你的不在意,才会影响到别人也不在意你。