排序是程序开发过程中非常常见的一种操作,是将一组无序的记录序列调整为有序记录。例如,30个学生的考试成绩需要进行从大到小的排列,很多高级语言为我们提供了内置的排序操作,下面是PHP,
JS, 和Python为我们提供的对学生成绩进行排序的方法:
<?php
$score = array(68,79,85,92,99,75,66,88,71,71,63,89,91,96,83,85,86,66,63,66,59,60,65,66,69,67,79,80,90,60);
echo sort($score);//升序排列
echo rsort($score);//降序排列
?>
score = new Array(68,79,85,92,99,75,66,88,71,71,63,89,91,96,83,85,86,66,63,66,59,60,65,66,69,67,79,80,90,60);
score.sort(); //升序排列(字符编码顺序)
score.sort(function(a,b){ return a-b}); //升序排列
score.sort(function(a,b){ return b-a}); //降序排列
score = [68,79,85,92,99,75,66,88,71,71,63,89,91,96,83,85,86,66,63,66,59,60,65,66,69,67,79,80,90,60]
print sorted(score) //升序排列
print sorted(score,cmp=lambda x,y:cmp(y,x)) //降序排列
那么,在其它没有给我们实现排序算法的语言里,我们如何去做呢?或者说,如何实现一个排序算法呢?排序算法中,最常见的算法为冒泡排序,其实现办法如下:
比较相邻的元素。如果第一个比第二个大,就交换他们两个。
对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
针对所有的元素重复以上的步骤,除了最后一个。
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
用C语言实现如下:
#include <stdio.h>
void sort(int num[], int len){
int i ,j ,tmp;
j = len;
for (j ; j > 2; j --){
for(i = 0; i<j -1; i++){
if(num[i] > num[i+1]){
tmp = num[i+1];
num[i+1] = num[i];
num[i] = tmp;
}
}
}
}
int main(){
int num[] = {121,120,10,100,342};
sort(num,5);
int i;
for(i = 0 ; i< 5; i ++ ){
printf("%d\n",num[i]);
}
return 0;
}
冒泡就是对元素进行一个两两对比,把大的往后移动,小的往前移动,最终形成一个序列,建设有n个元素需要排列,那么其计算的次数为(n-1)的阶乘。
大数据排序问题
有一千万条随机排列的数字,如何求出其中最大的10个数?
显然,这里不能采用完全的冒泡排序的办法,一种简单的办法是,先创建10个数组,然后逐个往数组中填入数据,并进行排序,最后得出的这个数组即为最大的10个数,如下:
#!/usr/bin/env python
class Container:
def __init__(self,length):
self.length = length
self.ele=range(length)
def add(self,number):
if number > self.ele[0]:
self.ele.remove(self.ele[0])
self.ele.insert(0,number)
self.ele.sort()#内置函数进行排序
elif number < self.ele[0]:
return
def get(self):
return self.ele
arr = Container(10)
number = open("num.txt","r") #假设num.txt中存放了这个一千万个数据
while True:
line = number.readline()
if not line:
break
num = line.strip()
arr.add(num)
number.close()
print arr.get()
以上add的操作(27行)是一千万次,最好情况下,num.txt中前面的10个数是最大的,self.ele.sort()则只需要进行10次,最差的情况下需要进行一千万次,两种情况,其总计算次数为(假设sort为冒泡排序实现的):
最好情况: 10*(10-1)!
最差情况: 10000000*(10-1)!
从上面的结果可以看出,在不考虑运气的情况下,获取最大的数的个人越多,情况越复杂,那么问题就来了,如果要对这一千万的所有数字进行排序呢,该如何做?