【面试题目】手撕快速排序
一、概述
写一个快速排序算法。
果真是面试最喜欢问的问题,可惜在面试前我只是匆匆浏览了一遍,然后就略过了。以为会问很多C++的语法知识,结果一点没问,直接开始写代码。没有提示和补全,完全靠手打,我写的代码几乎就是只把思想说出来了,和伪代码差不多。
二、分析
1、我的代码
好惨。如下:
vector<int> quick(vector<int>& s) { /*int first=s[0]; vector<int> left,right; for(int i=1;i<s.size();i++) if(s[i]<first) left.push_back(s[i]); else right.push_back(s[i]); s=left+first+right; quick(left); quick(right);*/ int first=s[0]; int start=1,end=s.size()-1; while(start<end) if(s[end]>s[0]) end++; continue; else { if(s[start]<s[0]) start++; continue; else swap(s[start],s[end]); } quick(s[0],s[start]) quick(s[star+1],s[s.size()-1]); }
不管参数对或者错了。
输入一个vector,选第一个作为分界点,然后维护两个指针,start和end,从后往前找第一个小于分界点的值,再从前往后找第一个大于分界点的值,然后交换这两个值,当start不小于end时退出循环。
然后递归。
勉强可以从代码看出思路。
被吐槽顾头不顾尾,大概就是递归时参数完全不一样了,应该是vector我却用了两个int。
2、正确思路
代码如下:
#include <stdio.h> int a[101],n;//定义全局变量,这两个变量需要在子函数中使用 void quicksort(int left, int right) { int i, j, t, temp; if(left > right) return; temp = a[left]; //temp中存的就是基准数 i = left; j = right; while(i != j) { //顺序很重要,要先从右边开始找 while(a[j] >= temp && i < j) j--; while(a[i] <= temp && i < j)//再找右边的 i++; if(i < j)//交换两个数在数组中的位置 { t = a[i]; a[i] = a[j]; a[j] = t; } } //最终将基准数归位 a[left] = a[i]; a[i] = temp; quicksort(left, i-1);//继续处理左边的,这里是一个递归的过程 quicksort(i+1, right);//继续处理右边的 ,这里是一个递归的过程 } int main() { int i; //读入数据 scanf("%d", &n); for(i = 1; i <= n; i++) scanf("%d", &a[i]); quicksort(1, n); //快速排序调用 //输出排序后的结果 for(i = 1; i < n; i++) printf("%d ", a[i]); printf("%d ", a[n]); return 0; }
看完之后我才发现我的思路没大错= =
一年前看快排看了好久果然还是有用的。
的确是维护两个变量,然后从后往前找,从前往后找,我弄错的有以下几点:
1、函数的输入参数应该是首尾的下标,不能直接把数组扔进来,引用也不行;
2、首先判断首尾下标是否合法,不合法则直接返回;
3、基准数归位没有写好;
4、begin和end应该是输入参数,而不是第一个或最后一个,这个是连锁反应;
5、循环退出条件是begin==end,交换条件是begin<end;
感觉还是可以的嘛(5条错误可以个头)
求生欲让我把自己的博客发给了面试小哥,代码暴露了好多缺点,总得把优点给人家看看,虽然这不算什么优点,但也证明了我不是什么都没写过啊hhhhh。
三、总结
不能偷懒啊,基础算法应该学会自己实现,不能因为有了sort就全不会了。
C中没有sort不就傻眼了。
很宝贵的经验教训。
上一篇:
IDEA上Java项目控制台中文乱码