1.冒泡排序
第一层循环
冒泡排序第一层循环的含义为:需要遍历多次数组,才能将这个数组排好序,
第一次遍历,确定一个最值。
第二次遍历,确定第二个最值。
。。。
第len-1次遍历,确定第len-1最值。 len-1个最值都确定了,自然整个数组也就排好序了。
因此,第一层循环含义为:需要遍历len-1次数组,才能将数组排好序。
通常定义为int j; j是一个与i相关的变量,第2层循环需要用到第一层的i的值。
那第二层循环要解决的问题是什么?
不好想的话,我们反过来想,在第二层循环时,我们还要对已经排好序的位置进行遍历吗?
当然不需要作此无用功,在第二层遍历中,我们只需对未排好序的那些待排位置进行遍历即可,而首先,我们必须知道,哪些元素是已经拍过序的,哪些元素是待排序的。
所以,我们第二层循环要解决的问题便是:待排序区域的起始和结尾位置。
而要解决这个问题,
首先,第一个要解决的便是:在进行这个循环时,数组已经排好了几个值。
其次,第二个要解决的便是:在数组中,待排序区域的其实和末尾位置分别是什么。
第一个要解决的问题与第一层循环已经进行了多少次有关。
第二个要解决的问题则与排序时遍历的方向有关。
#include<stdio.h>
int main()
{
int a[10]={10,9,8,7,6,5,4,3,2,1};
int len=sizeof(a)/sizeof(int);
int i,j;
for(i=0;i<len-1;i++) //第len-1次遍历,确定第len-1最值
{
for(j=0;j<len-i-1;j++) //对未排好序的那些待排位置进行遍历j=0,拿第0位与第1位比较;j=1拿第1位与第2位元素比较;。。。。。。j=8拿第8位与第9位比较
{
if(a[j]>a[j+1])
{
int temp=a[j]; //遍历找出的最大值放在最后
a[j]=a[j+1];
a[j+1]=temp;
}
}
for(j=0;j<10;j++)
{
printf("%d ",a[j]);
}
printf("\n");
}
return 0;
}
2.选择排序
选择排序也是一种简单直观的排序算法。它的工作原理很容易理解:初始时在序列中找到最小(大)元素,放到序列的起始位置作为已排序序列;然后,再从剩余未排序元素中继续寻找最小(大)元素,放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
注意选择排序与冒泡排序的区别:冒泡排序通过依次交换相邻两个顺序不合法的元素位置,从而将当前最小(大)元素放到合适的位置;而选择排序每遍历一次都记住了当前最小(大)元素的位置,最后仅需一次交换操作即可将其放到合适的位置。
#include <stdio.h>
int main ()
{
int a[10]={10,9,8,7,6,5,4,3,2,1};
int len=sizeof(a)/sizeof(int);
int i,j;
int min;
for(i=0;i<len-1;i++)
{
min=i; //每次都从已排序序列的末尾后一位开始
for(j=i+1;j<len;j++) //
{
if(a[j]<a[min]) //寻找最小的数
{
min=j; //将最小数的索引保存
}
} //放到已排序序列的末尾(即交换),该操作很有可能把稳定性打乱,所以选择排序是不稳定的排序算法
if (min != i)
{
int temp=a[i];
a[i]=a[min];
a[min]=temp;
}
for(j=0;j<10;j++)
{
printf("%d ",a[j]);
}
printf("\n");
}