腾讯-1亿个数据取前1万大的整数-题解答

题目描述:
1亿个数据取前1万大的整数

常规思路:
运用数据结构里面描述的常规排序算法,快速排序法是常规排序中速度最快的

我的思路:
====我的机器太差,就不跑1亿数据了,1000000吧
1、把1亿个数据分成1000个数组,
2、求出1000个数组的最大值,保存到$max 数组中,
3、对$max本身用快速排序法排序 $max数组中保存了一个有序序列数组
4、遍历1亿个数据,依次对比$max最小的数据,如果比这个最小数据小,那么就依次对比$max的其他数据,从大到小开始对比,如果比max数组中的数据大,就替换。
5、获得10000个从大到小的数据$max.

代码:

< ?php
 
/**
 * 交换两个数据的值
 *
 * @param unknown_type $x
 * @param unknown_type $y
 */
function swap(&$x,&$y)
{
	$c = $x;
	$x = $y;
	$y = $c;	
}
 
/**
 * 快速排序函数
 *
 */
function quicksort( $arr, $l = 0 , $r = NULL ) {
    static $list = array();
    if( $r == NULL )
        $list = $arr;
 
    if( $r == NULL )
        $r = count($list)-1;
 
    $i = $l;
    $j = $r;
 
    $tmp = $list[(int)( ($l+$r)/2 )];
    do {
        while( $list[$i] < $tmp )
            $i++;
 
        while( $tmp < $list[$j] )
            $j--;
 
        if( $i <= $j ) 
        {
           swap($list[$i],$list[$j]);
           $i++;
           $j--;
        }
    }while( $i <= $j );
 
    if( $l < $j )
        quicksort(NULL, $l, $j);
 
    if( $i < $r )
        quicksort(NULL, $i, $r);
 
    return $list;
}
 
/**
 * 计算运行时间类
 *
 */
class timer 
{ 
	var $StartTime = 0; 
	var $StopTime = 0; 
	var $TimeSpent = 0; 
	function start()
	{ 
	  $this->StartTime = microtime(); 
	} 
	function stop()
	{ 
	  $this->StopTime = microtime(); 
	} 
	function spent() 
	{ 
	  if ($this->TimeSpent)
	  { 
	   		return $this->TimeSpent; 
	  }
	  else
	  { 
		   $StartMicro = substr($this->StartTime,0,10); 
		   $StartSecond = substr($this->StartTime,11,10); 
		   $StopMicro = substr($this->StopTime,0,10); 
		   $StopSecond = substr($this->StopTime,11,10); 
		   $start = doubleval($StartMicro) + $StartSecond; 
		   $stop = doubleval($StopMicro) + $StopSecond; 
		   $this->TimeSpent = $stop - $start; 
		   return substr($this->TimeSpent,0,8)."秒"; 
	  } 
	}
}//end class timer;
 
//构造1000000个数据的数组
// $number 拆分1000*1000数组
// $number2 1000000个数据的1维数组
 
for($i=0;$i< = 999;$i++)
{
	for($j=0;$j<=999;$j++)
	{
		$number2[] = $number[$i][$j] = rand(0,10000);
	}
}
 
$timer = new timer; 
$timer->start(); 
 
$max = array();
foreach ($number as $list)
{
	$maxvalue = 0;
	foreach ($list as $value)
	{
		if($maxvalue < $value)
		{
			$maxvalue = $value;
		}
	}
	$max[] = $maxvalue;
}
 
 
$max = quicksort($max,0);
for($i=0;$i < 1000000;$i++)
{
		//如果数组的数据大于max最小值,则从大到小对比其他数据
	if($number2[$i] >$max[0])
	{
		for ($k=999;$k>=0;$k--)
		{
			if($max[$k] < $number2[$i])
			{
					//替换数据
				$max[$k] = $number2[$i];
				break;
			}
		}
	}
}
 
$timer->stop(); 
 
echo '第一次排序时间:'.$timer->spent();
/*print_r($max);*/
$timer2 = new timer();
$timer2->start();
quicksort($number2,0);
$timer2->stop();
echo '第2次排序时间:'.$timer2->spent();
/*print_r($number2);*/

运行结果:
第一次排序时间:2.370435秒
第2次排序时间:38.43304秒

ps:
运行时间可能有所变化,我是在几年前的笔记本上测试的,不过显然第一次排序结果速度更快

 

Tags:

Comments: 7

Leave a reply »

 
  • PHP排序的内部实现已经是快速排序,
    如果直接使用rsort函数
    使用lz代码:第一次排序时间:0.817933秒第2次排序时间:11.13846秒
    使用rsort:第一次排序时间:0.407768秒第2次排序时间:2.634183秒

     
     
     
  • 哇,不好意思,一直不知道没有看过rsort的C实现,所以使用了PHP的,总体来讲,我是为了体现算法的思路

     
     
     
  • 呵,也是忽然看到这个的,
    另外:这个是编程之美上的题目,书上有5种解法

     
     
     
  • 博主的文章写的不错,换个链接吧.
    有机会多交流一下了.呵.
    http://www.phppan.com/

     
     
     
  • 5种解法?看来我也要看本这样的书看看

     
     
     
  • 哈哈,好的,昨天没有看到留言

     
     
     
  • tedeyang

    “遍历1亿个数据,依次对比$max最小的数据,如果比这个最小数据/小/,那么就依次对比$max的其他数据,”
    写错了。

     
     
     
  • Leave a Reply
     
    Your gravatar
    Your Name
     
     
     
     
     
 
About This Website

Lamp development & SEO & Plan of Website & Project Managment

Learn more »
Follow Us (SNS)
Help & Support

more about Bruce.xu»

Get in touch

QQ: +252339382
Email: shjuto @ gmail.com

Online contact form »