快排找出数组的中位数

之前苏州双选会的时候,面试斯睿普智能这家公司,问了我两个问题。一个是 strcpy 和 memcpy 的区别,第二个就是如何快速地在一个数组里面找出他的中位数。参考百度的方法,可以用快排和堆排序的方法来做,这里对快排做一下总结。

 

任意挑一个元素,以该元素为支点,划分集合为两部分,如果左侧集合长度恰为 一半,那么支点恰为中位数。 
如果左侧长度小于一半, 那么中位点在右侧, 反之,中位数在左侧。 进入相应的一侧继续寻找中位点。可以用类似于二分查找那种的 while 循环来实现这种递归(这是叫递归吗?)调用。

 

int main()
{
    int a[]={1,2,3,4,5,6,7,8,9,10,11,12};
    int len=sizeof(a)/sizeof(int);  //取数组长度
    int start=0,end=len-1;
    int addr=partition(a,start,end);
    int mid=(len-1)/2;
    while(addr!=mid)
    {
        if(addr=key)
            right--;
        a[left]=a[right];  //把比 pivot 小的元素调到 pivot 左边去
        while(left

这种方法可行性在于数组作为参数传递的时候,会退化为指针。所以在形参里对数组的修改会直接影响到main 里面的数组。

要确定一个一维数组需要知道哪些信息?一个是数组的首地址,另一个是数组的长度。这样就可以唯一地确定一个一维数组。因为数组是连续存放的,只要知道数组的首地址和数组的长度就能找到这个数组中所有的元素。

因此,要想通过实参和形参将一个数组从主调函数传到被调函数,那么只需要传递这两个信息即可。对于一维数组来说,其数组名就表示一维数组的首地址。所以只需要传递数组名和数组长度这两个参数就可以将数组从主调函数传入被调函数中。

所以在传递实参的时候,数组名和数组长度也只能用两个参数分开传递,而不能写在一起。因为即使写在一起,系统在编译时也只是检查数组名,并不会检查数组长度。所以数组长度要额外定义一个变量进行传递。

综上所述,当将数组从一个函数传到另一个函数中时,并不是将数组中所有的元素一个一个传过来(那样效率就太低了)。而是将能够唯一确定一个数组的信息传过来,即数组名(数组首地址)和数组长度。此时主调函数和被调函数操作的就是同一个数组。被调函数里对于数组的修改会直接的反映在调用函数里。

代码如下:

void fun(int a[],int n)
{
    for(int i=0;i

代码输出如下

数组 b 的字节大小:4
2 3 4 5 6 7

为什么数组b 的字节大小是 4 个字节呢?

因为数组名做函数参数时,只是将实参数组的“首地址”传给了形参数组。此时被调函数 fun1 中的数组 b 看起来是一个int 型数组,其实本质上是一个指针变量,里面存放的是主调函数中数组 a 的地址。指针变量也是一个变量类型。不同于前面所讲的其他变量类型,指针变量里面存放的不是一般的数据,而是地址。在 C 语言中,指针变量所占的字节数都是 4(但有些显示求出的可能是 8,这跟操作系统有关)。
 

 

你可能感兴趣的:(快排找出数组的中位数)