排序算法
1.冒泡排序(思路)
从前向后,即从下标小的开始,依次比较相邻的两个值,发现逆序(前面的大于后面的)则交换,最后大的值像气泡一样逐渐上冒
#需要设置标识变量flag记录交换次数
#核心还是交换,需要遍历加判断
#对数组进行操作比较适合
#a【i】与a【i+1】
#每一次判读一次,最多交换一次,交换后才算一趟
#错误的,只有一趟
for(int i=0;i<size-1;i++){
if(a[i]>a[i+1]){
int t;
t=a[i];
a[i]=a[i+1];
a[i+1]=t;
}
}
#一个最大的数要比较好多次,一趟比较的次数,与交换的次数
#数组一共进行n-1次的循环
#每一趟排序的次数在逐渐的减小
#第一趟排序,将最大的数排在最后
for(int i=0;i<size-1;i++){
if(a[i]>a[i+1]){
int t;
t=a[i];
a[i]=a[i+1];
a[i+1]=t;
}
}
#第二趟排序,把第二大的数排在倒数第二位
for(int i=0;i<size-1-1;i++){
if(a[i]>a[i+1]){
int t;
t=a[i];
a[i]=a[i+1];
a[i+1]=t;
}
}
.。。。。。。
#总的,需要多少趟,size-1
for(int j=1;j<size;j++){
for(int i=0;i<size-1*j;i++){
if(a[i]>a[i+1]){
int t;
t=a[i];
a[i]=a[i+1];
a[i+1]=t;
}
}
}
#外面循环控制趟数
#里面循环控制每一趟交换的次数
#时间复杂度O(n^2)
#冒泡排序的优化
如果某一趟发现没有发生交换,则说明排序完成。
boolean flag=flase;
for(int j=1;j<size;j++){
for(int i=0;i<size-j;i++){
if(a[i]>a[i+1]){
flag=true;
int t;
t=a[i];
a[i]=a[i+1];
a[i+1]=t;
}
}
if(!flag){
break;}
else{
flag=flase;}
}
#可以改变排序的趟数
#可以封装成一个方法
2、选择排序
选择最小值与前面第一个数进行交换
#先找再换
for(int i=0;i<size-1;i++){
#如何找最小值,通过相邻比较和交换,把最小值交换到最后
if(a[i]>a[i+1]){
int t;
t=a[i];
a[i]=a[i+1];
a[i+1]=t;
}
}
#找到之后怎么办,赋值给第一个
a[0]=a[size-1];
#上面是第一次选择
#第二次选择
for(int i=1;i<size-1;i++){
#如何找最小值,通过相邻比较和交换,把最小值交换到最后
if(a[i]>a[i+1]){
int t;
t=a[i];
a[i]=a[i+1];
a[i+1]=t;
}
}
#找到之后怎么办,赋值给第一个
a[1]=a[size-1];
#总的选择,外边控制选择次数,里面控制数组下标的开始,最后的下标不变
for(int i=0;i<size-1;i++){
for(int j=0+i;j<size-1;j++){
#如何找最小值,通过相邻比较和交换,把最小值交换到最后
if(a[j]>a[j+1]){
int t;
t=a[j];
a[j]=a[j+1];
a[j+1]=t;
}
}
#找到之后怎么办,赋值给第一个
a[i]=a[size-1];
}
#和冒泡排序类似
#每一轮排序得出一个结果
#和冒泡比,比较的次数少了。
#分步进行,逐步推导
#排序就是比较和交换
#选择排序还可以利用下标交换,也可以值交换
#数组长度是80000就可以理解了
#不同电脑同样的程序运行的时间是不同的
3.插入排序
#收试卷排序
思想:把数组看成一个有序表和一个无序表,
开始时有序表是第一个值,然后从无序表中从第一个数开始取,依次插入到有序表中,其中需要通过判断,知道插入的位置
#减少无序表比较和交换,增加有序表比较和交换
#用数组实现插入比较困难
#6个数据插入5次
#如何把值插入,创建一个新的数组吗
#用交换代替插入,再原数组上进行操作
#有序数组里面也要进行多次比较和交换
#先处理插入的处理,再在外层循环处写出取数据的循环
#第一次
for(int i=1;i<2;i++){
if(a[0]>a[i]){
int t;
t=a[0];
a[0]=a[i];
a[i]=t;
}
int startindex=0+1;
}
#第二次
for(int i=2;i<3;i++){
if(a[1]>a[i]){
int t;
t=a[1];
a[1]=a[i];
a[i]=t;
}
int startindex=1+1;
}
#需要设置更多变量来让思路更明确
int startindex=1;
#设置出有序列表与无序列表的分界线,代表无序列表的第一个
#开始索引的意思也是插入数据的索引
#再次尝试,插入的交换是从右到左
#知识没有盲区,数据结构用对,思想理解对,写对只是时间问题
##第一次
int startindex=1;
#设置比较次数
for(int i=startindex-1;i>=0;i--){
if(a[i]>a[startindex]){
int t;#交换数据用的
t=a[i];
a[i]=a[startindex];
a[startindex]=t;
}
startindex++;
}
##第二次
int startindex=2;
#设置比较次数,i为有序列表的索引
#插入时只排一次序,故一个循环就够了
for(int i=startindex-1;i>=0;i--){
#设置一个变量复制startindex的值从而进行参与变化
#k需要放在循环这里
int k=startindex;
if(a[i]>a[k]){
int t;#交换数据用的
t=a[i];
a[i]=a[k];
#数据交换索引没有交换
a[k]=t;
k--;
}
#插入之后,startindex才开始加一
}
startindex++;
###总的
需要加外层循环改变startindex的值
for(int startindex=1;startindex<size;startindex++){
#设置比较次数,i为有序列表的索引
#插入时只排一次序,故一个循环就够了
for(int i=startindex-1;i>=0;i--){
#设置一个变量复制startindex的值从而进行参与变化
#k需要放在循环这里
int k=startindex;
if(a[i]>a[k]){
int t;#交换数据用的
t=a[i];
a[i]=a[k];
#数据交换索引没有交换
a[k]=t;
k--;
}
#插入之后,startindex才开始加一
}
}
#与选择排序类似,进阶,减少了冒泡排序的比较次数
#需要引入变量k
#用for+while也行
#即大数后移
#小的数如果在后面会移动次数过多
4.希尔排序
#先把数据存到数组中
#减少交换次数
思想:先把数组分组
同组的人隔着相同的增量
第一次分size/2=n组,第二次分n/2组,直到1组
分组后进行插入排序
#如何对数组进行分组i ,i+k
for(int i=0;i<size/2;i++){
if(a[i]>a[size/2+i]{
int t;
t=a[i];
a[i]=a[size/2+i];
a[size/2+i]=t;
}
}
#如何分到最后剩两组,怎么对数取整
if(size/2^n==1)
外层需要加一个n变换的循环
for(int n=1;n<log,n++){
}
#增量随n变换
#但如果每组里面多个数据怎么办,如何设置循环变量
for(int i=0;i<size/2^n;i++){
if(a[i]>a[size/2^n+i]{
int t;
t=a[i];
a[i]=a[size/2+i];
a[size/2+i]=t;
}
}
#插入时采用交换法,或采用移动法
#希尔排序快
#里面控制交换,外面控制步长
5.快速排序
对冒泡算法的改进
思想:通过一趟排序将要排序的数据分成独立的两部分,
其中一部分的所有数据都比另外一部分的所有数据都要小
#需要找一个中间比较值
#时间复杂度一样,所用的时间也不一定一样
#递归
6.归并排序
7.基数排序
######################################################
c语言有内置的排序函数qsort()
排序大多是针对数组的操作,队列,栈排序没必要,树,图没法排
链表可以排序