1、 . . . . 在学习算法的过程中,排序算法是很基础的。下面我用C语言实现了5中基础的排序算法:插入排序、选择排序、冒泡排序、并归排序、快速排序。1.插入排序插入排序很简单,在算法导论中的解释是这样的。插入排序的工作机理与很多人打牌时,整理手上的牌的做法差不多。开始的时候我们的左手是空的。接着我们从桌面上一一的摸牌,并将它放到左手的一个正确的位置上。为了找到这个正确的位置,要将它与左手的牌从右到左地进行比较,无论在什么时候左手的牌都是排好序的。很简单吧,不过当初为了理解这个算法也花了一点时间,下面是C语言对插入排序的一个简单实现:帮助12345678910111213/插入排序 int in
2、sert_sort(int a,int size) int i,j,temp; for(i = 1;i =0 & temp .选择排序选择排序的工作原理是这样的,对数据进行遍历,找出最小的元素(升序)作为第一个元素,再在剩下的数中找出最小的作为第二个元素,一直循环下去,最后的你会发现这个数组中的数据已经排好序了。下面是C语言的选择排序的一个简单实现:帮助123456789101112131415/选择排序 int select_sort(int a,int size) int i,j,temp; for(i = 0;i size;i+) for(j = i+1;j aj) /交换位置 temp
3、 = ai; ai = aj; aj = temp; return0; /end select_sort3.冒泡排序冒泡排序是重复交换相邻的两个反序元素。它的工作工作机理我觉得跟选择排序差不多。因为在第一个遍历整个数组交换反序元素之后,数组的第一个元素就已经是整个数组中最小的元素了。下面是C语言实现的一个冒泡排序。帮助123456789101112/冒泡排序 int bubble_sort(int data,int size) int i,j,temp; for(i = 0;i i;j-) if(dataj .并归排序并归排序,你也可以叫它合并排序。它采用了递归的思想,将数据分成两个部分,将这
4、两个部分排好序之后再进行合并,一直重复这个过程,得出最后的结果。可能说的比较抽象,大家看下面的代码。帮助12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455/合并两个已经排好的结果 int merg_result(int data,int start,int middle,int end) int s1,s2, i,i1,i2; s1 = middle-start+1; s2 = end - middle; i1 = i2 = 0; /两个临时的
5、数组 int temp1s1,temp2s2; /复制数据前后两个段的数据进临时数组 for(i = 0;i s1;i+) temp1i = datastart+i; for(i = 0;i s2;i+) temp2i = datamiddle+1+i; /开始合并 for(i = start;i s1+s2+start;i+) if(temp1i1 = s1) break;/无法将两个临时数组的最后一个 元素设为无穷大 datai = temp1i1+; else if(i2 = s2) break; datai = temp2i2+; /添加两个循环,将最后的数据合并好 while(i1
6、s1) datai+ = temp1i1+; while(i2 s2) datai+ = temp2i2+; /end merg_result /并归排序 int merg_sort(int data,int start,int end) int middle; if(start .快速排序这是我觉得最神奇的一个。前面3个排序时间代价都是O(n2),虽然并归排序的时间O(nlgn)。但是由于合并过程中需要的临时数组,使得它占用的栈空间相当大,在我的机子上(2G存)排序50万的整形数据程序就会崩溃,存不够了。而快速排序虽然也是递归的,但是它完全在本地工作,不需要申请额外的空间,所以很方便。下面是
7、我用C语言写的一个快速排序的例程,帮助12345678910111213141516171819202122232425262728293031323334353637383940/合并两个已经排好的结果 int partition(int data,int start,int end) int key, i,j,temp; /选取最后一个元素作为主元素 key = dataend; i = start; for(j = start;j end;j+) if(dataj = key) /交换dataj与datai temp = datai; datai+ = dataj; dataj = te
8、mp; /将主元素换到i位置 temp = datai; datai = dataend; dataend = temp; /返回主元素的位置 /printf(%d ,i); returni; /end partition /并归排序 int quick_sort(int data,int start,int end) int middle; if(start end) middle = partition(data,start,end); quick_sort(data,start,middle-1); quick_sort(data,middle+1,end); return0; /end
9、 quick_sort这只是我理解的快速排序一个很简单的实现。更多有关快速排序的原理你可以看这里上面的代码都是我在理解算法之后写出来的,当然可能有一些bug,如果你发现了请联系我。:)关于算法性能的分析,我实在不在行。在书上说的这几个算法性能上,前3个是O(n2),后两个是O(nlgn)。说实话我对这些的理解不是很够。于是我自己写了一个测试程序在我的笔记本上跑了下。我的方式是随机生成数据,然后使用不同的排序算法进行测试,当然几百个数据几乎一瞬间就可以解出,所以我在测试的时候是对1000次(或者更多)排序的总时间进行统计。通过统计结果,我发现插入排序在对于小量的数据,效果很好。但是在数据太大的时候就不能和并归排序和快速排序进行比较了。这个数据的间值在200左右。而快速排序不管是大数据还是小数据的效果都非常好,有些时候比插入排序还好。当然,这是我没有遇到传说中的坏数据,因为坏数据是有可能让快速排序的时间达到O(n2)的。这个文件是我测试的结果,有一些我连续测了几次,结果都差不多。你可以看看。当然,你可能会看的眼花。寒假过了这么久,在家看游戏设计方面的是容。参考书是windows游戏编程大师技巧。终于会读取bmp位图了,并且还按照书上做了一个小动画。哈哈,过几天再把整理的一个容发到博客上。快过年了,提前祝大家新年快乐!:)7 / 7