排序与查找算法(C语言描述)
2017-04-10 15:11
316 查看
排序算法
选择排序
冒泡排序
快速排序
归并排序
C++自带的algorithm库函数中提供了排序算法。
自带排序算法的一般形式为:
sort(arr+m,arr+n);//将数组arr的下标为m的元素到下标为n-1的元素进行从小到大排序
sort(arr+m,arr+n,comp);//与sort(arr+m,arr+n)相比,这个写法可以自己定义排序的规则,其中,comp为自定义的函数
选择排序(从小到大)的基本思想是,首先,选出最小的数,放在第一个位置;然后,选出第二小的数,放在第二个位置;以此类推,直到所有的数从小到大排序。
在实现上,我们通常是先确定第i小的数所在的位置,然后,将其与第i个数进行交换。
评价:
注意:选择排序是一种不稳定的排序算法,可能会打乱两个相同数字的原有顺序。
例如,序列 5 8 5 2 9, 按照从小到大排序,第一轮会将第1个数字5会和2交换,那么原序列中2个5的相对前后顺序就被破坏了,所以选择排序是一种不稳定的排序算法。
冒泡排序(从小到大)的基本思想是,不断比较相邻的两个数,让较大的元素不断的往后移,经过一轮比较,就选出最大的数;经过第二轮比较就选出次大的数,以此类推。
一般实现
优化实现
评价
优点:稳定;
缺点:慢,每次只能移动相邻两个数据。
选择排序
冒泡排序
快速排序
归并排序
C++自带的algorithm库函数中提供了排序算法。
自带排序算法的一般形式为:
sort(arr+m,arr+n);//将数组arr的下标为m的元素到下标为n-1的元素进行从小到大排序
sort(arr+m,arr+n,comp);//与sort(arr+m,arr+n)相比,这个写法可以自己定义排序的规则,其中,comp为自定义的函数
排序算法
选择排序
基本思想:选择排序(从小到大)的基本思想是,首先,选出最小的数,放在第一个位置;然后,选出第二小的数,放在第二个位置;以此类推,直到所有的数从小到大排序。
在实现上,我们通常是先确定第i小的数所在的位置,然后,将其与第i个数进行交换。
评价:
注意:选择排序是一种不稳定的排序算法,可能会打乱两个相同数字的原有顺序。
例如,序列 5 8 5 2 9, 按照从小到大排序,第一轮会将第1个数字5会和2交换,那么原序列中2个5的相对前后顺序就被破坏了,所以选择排序是一种不稳定的排序算法。
#include <stdio.h> #include <stdlib.h> #include <time.h> const int MAXN = 10; int main (void) { int a[MAXN] = {0}; int i = 0; int j = 0; srand( (unsigned)time(NULL) );//rand()函数产生的是伪随机数(产生原理是 F(种子值),也就是关于一个固定值的固定公式; //也就是程序运行第一次和第二次产生的随机数是一样的,所以我们要利用srand()进行播种;srand(unsigned seed) for (int k = 0; k < MAXN; k++) { a[k] = rand()%100 + 1; } printf("初始化数组:"); for (i = 0; i < MAXN; i++) { printf("%-2d ", a[i]); } printf("\n"); /*----------*/ //选择排序原理: //1、从第一个数开始(a[0]),找到数组中最小的数的位置,然后交换第一个数和最小数 //2、从第二个数开始(a[1]),找到剩余数中最小数的位置(对应整个数组第二小的数),然后交换第二个数和最小数 //...... //N-1、从第N-1个数开始(a[MAXN-1]))、最后一次,比较最后两数了。 //外循环:对应找第一个位置上的最小数,第二个,...,当前N-1个都找好了,最后一个自然不用找了, // 故边界条件为 0 ~ MAXN-1 ,共 N-1次; //内循环:要完成的任务是:遍历数组元素找到最小值;交换该位置数和最小值所在位置数,如果是本身就不用交换; // 起点对应第一小的数放在第一个位置,第一个数也要遍历到; // 但是我是用第一个数最为参照进行比较的,所以起点i = j + 1,直接与下一个数进行比较即可,一直到最后一个数; //交换数:采用位运算中的异或运算交换两个不同的数; // 原理:a^b^b = a; /*------- -*/ for (j = 0; j < MAXN - 1; j++) { int min_index = j; for (i = j + 1; i < MAXN; i++) { if (a[min_index] > a[i]) { min_index = i; } } if (j != min_index) { a[j] = a[j] ^ a[min_index]; a[min_index] = a[j] ^ a[min_index]; a[j] = a[j] ^ a[min_index]; } } printf("排序后数组:"); for (i = 0; i < MAXN; i++) { printf("%-2d ", a[i]); } putchar('\n'); return 0; }
#include <cstdio> #include <cstdlib> #include <ctime> const int size = 10; void select_sort(int a[], int MAXN) { printf("初始化数组:"); for (int i = 0; i < size; i++) { printf("%-2d ", a[i]); } printf("\n"); //核心部分 for (int j = 0; j < MAXN - 1; j++) { int min_index = j; for (int i = j + 1; i < MAXN; i++) { if (a[min_index] > a[i]) { min_index = i; } } if (j != min_index) { a[j] = a[j] ^ a[min_index]; a[min_index] = a[j] ^ a[min_index]; a[j] = a[j] ^ a[min_index]; } } printf("排序后数组:"); for (int i = 0; i < size; i++) { printf("%-2d ", a[i]); } putchar('\n'); } int main (void) { int a[size]; //初始化数组 srand( (unsigned)time(NULL) ); for (int k = 0; k < size; k++) { a[k] = rand()%100 + 1; } select_sort(a, size);//排序 return 0; }
冒泡排序
基本思想冒泡排序(从小到大)的基本思想是,不断比较相邻的两个数,让较大的元素不断的往后移,经过一轮比较,就选出最大的数;经过第二轮比较就选出次大的数,以此类推。
一般实现
#include <cstdio> #include <cstdlib> #include <iostream> #include <ctime> const int size = 10; void select_sort(int a[], int MAXN) { int i; printf("初始化数组:"); for (i = 0; i < size; i++) { printf("%-2d ", a[i]); } printf("\n"); /*--------*/ //基本思想:第一轮,比较a[0]和a[1],如果a[0]>a[1],则交换两数,接着比较a[1]和a[2],......最后一次为a[N-2]和a[N-1]的比较,至此,a[N-1]为最大数 // 第二轮,比较a[0]和a[1], ......最后一次为a[N-3]和a[N-2]的比较 // ....... // 第N-1轮,比较a[0]和a[1],结束排序 // 外循环: 0~szie-1 共 N -1 轮 // 内循环: 总是从0和1开始比较的,故初始值j=0开始,比较到size - 1 - i; // //两轮循环的循环变量的意义不同,一个是轮数,一个数数组元素下表 注意理解二者的区别和联系 /*--------*/ for (i = 0; i < size - 1; i++) { for (int j = 0; j < size - 1 - i; j++) { if (a[j] > a[j+1]) { a[j] = a[j] ^ a[j+1]; a[j+1] = a[j] ^ a[j+1]; a[j] = a[j] ^ a[j+1]; } } } printf("排序后数组:"); for (i = 0; i < size; i++) { printf("%-2d ", a[i]); } putchar('\n'); } int main (void) { int a[size]; //初始化数组 //srand( (unsigned)time(NULL) ); for (int k = 0; k < size; k++) { a[k] = rand()%100 + 1; } select_sort(a, size);//排序 return 0; }
优化实现
for (i = 0; i < size - 1; i++) { bool isSorted = true; // for (int j = 0; j < size - 1 - i; j++) { if (a[j] > a[j+1]) { isSorted = false; // a[j] = a[j] ^ a[j+1]; a[j+1] = a[j] ^ a[j+1]; a[j] = a[j] ^ a[j+1]; } } if (isSorted) { break; // 本轮冒泡没用进行交换,代表已经排序完成,不用再继续冒泡了。 } }
评价
优点:稳定;
缺点:慢,每次只能移动相邻两个数据。
快速排序
归并排序
相关文章推荐
- 排序 - C语言实现(摘自数据结构与算法分析C语言描述))
- 文件排序(C语言描述)(在堆中进行)
- 依旧摘自《数据结构--用C语言描述》的查找算法 哈希和折半
- 排序 (插入排序,快速排序,希尔排序)数据结构与算法分析-C语言描述
- C语言描述——简单插入排序
- 交换排序——冒泡排序和快速排序——C语言描述
- 交换排序——冒泡排序和快速排序——C语言描述
- c语言描述的直接插入排序法
- 数据结构中的排序查找算法(C语言实现)
- C语言直接插入排序和折半插入排序算法的实现
- 常见C语言题目:选择排序,冒泡排序,函数调用,递归等重要题列
- php数据结构与算法(PHP描述) 快速排序 quick sort
- c语言描述的静态查找表
- C语言实现选择排序
- 快速排序--C语言实现、python实现
- PHP常用的排序和查找算法
- 排序【5】之归并排序的C语言实现
- (排序)用C语言实现的快速排序(交换排序)
- C语言-排序-快速排序
- c语言一些简单排序总结