博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

第一篇我献给排序

Posted on 2010-10-06 20:46  anhei  阅读(96)  评论(0)    收藏  举报

     一直以来学习数据结构的都很不给力,现在不得不还债。废话少说,开讲。

插入排序

     其实插入排序的思想很简单,即利用了一个性质:第n次排序的时候,前面的n个元素已经是有序的了,因此第n次排序的实质只找到我们插入的第n+1个元素在前n+1个元素中的位置。这看起来并不能让你觉得很简单,因为如果第n+1个元素比前面的n个元素都要小,那它可要逐次与前面的元素交换。设置temp的作用时,能方便的找到我们要插入的元素,因为循环开始后可能它的位置已经发生移动。

     所以很容易想到要用循环,n个元素总共排序n-1次,第i次的目的是让前i+1个元素有序,如果对C不熟,写起来还是有困难。。。

 

for(i=1;i<k;i++)                         //表示循环n-1次
{
temp
=a[i];                            //第n次排序中,目的是找到no.n+1在前n+1中的位置
for(j=i;j>0&&a[j-1]>temp;j--) //如果它比前面的元素大,进行左移
{
      a[j]
=a[j-1];                       //进行交换
a[j-1]=temp;                       //目的是让n+1个元素左移到正确的位置
}
}

冒泡排序

     乘胜追击,咱们接着讲,下面是冒泡,冒泡很有意思,它的思路是:第一次排序,我们把最大的元素搞到最右边,因为它是挨着挨着比较第一个跟第二个比,第二个跟第三个比。。。这样的后果就是,如果我是最大的元素,我就能战胜所有的元素,然后成功到达最后。第二次我们只用比较前9个元素,然后依次。。。

 

for(i=0;i<10;i++)                    
{
for(j=0;j<10-i;j++)     
{
if(a[j]>a[j+1])
{
temp
=a[j];
a[j]
=a[j+1];
a[j
+1]=temp;
}
}
}

 

      写冒泡的难点在于控制循环次数,第一次排序要比较前n个元素,第二次要比较前n-1个元素,即序号的关系有比较序号+要比较的元素个数=n+1,进一步抽象有:比较序号+比较次数=n。因为有n个元素,逐次比较那么就要比较n-1次。

直接选择排序

      还不知道神马是选择排序,写一步算一步了,这个算法的思想是:从待排的序列中选择最小的,放到序列的最前面,然后依次减小待排元素,知道待排元素为空。简单说来是这样:第一次我们选择序列中最小的元素跟第一个交换,然后从剩下元素中选择最小的跟第二个交换,依次这样。。

      可能不够直观,但思想基本就是选择出最小的、次小的,把这些个元素从新组成的序列就是排好的,只不过它是通过交换的思想来达到目的.具体写代码时,我们使用了一个small来指向每次排序中最小元素的下标,因为我们需要让它跟原始的序列中第n个元素(由第几次排序决定)进行交换。

1 for(i=0;i<10;i++)
2 {
3 small=i; //small表示指向最小元素的下标 ,先把它赋给第i个元素
4   for(j=i+1;j<10;j++)
5 {
6 if(a[small]<a[j]) // 看看当前序列中第i个元素是不是最小的
7   {
8 small=j; //如果不是,标志着最小元素的下表赋给别人
9   }
10 }
11 if(small!=i) //判断最小元素下标是不是要和第i个元素进行交换
12   {
13 temp=a[i];
14 a[i]=a[small];
15 a[small]=temp;
16 }
17 }
      代码如图,难点在于我们需要知道要进行排序的元素中哪个是最小的,并且判断出它是否要进行交换的必要性,为了这一点我们使用了small来始终指向最小元素的下标,然后通过判断下标来决定是否交换。注意看代码,第一层的循环目的就是找出待排元素中最小元素的下标,并把它赋给small。

      而第二层循环的目的就是减小待排元素的个数(因为进行前n次排序后,前几个元素已经是有序的了)。总而言之,像我这种C语言菜鸟,写这种需要控制循环次数的代码实在是难为我了。总之,写这个是不容易。。。。