Dart语言的语法糖很多,写起短码时非常好用。今晚,我带大家用Dart语言实现 快速排序、归并排序和堆排序。这三种排序方法是面试时经常考到的,希望对大家有帮助。
1.快速排序(quick sort)
快速排序主要是取数列中的一个元素为主元(pivot),通过双指针方法从两端开始推进。这里以升序排列为例,右侧元素小于主元就进行交换,左侧元素大于主元就进行交换。直到双指针位置重合,我们就达到了主元左侧元素均小于主元,右侧元素均大于主元的排列目的。再用递归的方法对主元左侧和右侧的子序列作相同操作,最后完成快速排序。快速排序采用了分治法(divide and conquer),是非常经典的算法思想。下面给出Dart源码:
import 'dart:math';
List<int> generateIntegers(){
List<int> li=List<int>();
for(int i=0;i<10;i++){
int x=Random().nextInt(10000);
li.add(x);
}
return li;
}
void quickSort(List<int> lst, int left, int right){
if(left>=right)return;
int pivot=left, i=left, j=right, direction=-1, temp=0;
while(i<j){
if(direction==-1){
if(lst[j]<lst[pivot]){
temp=lst[j];
lst[j]=lst[pivot];
lst[pivot]=temp;
pivot=j;
direction=1;
}else j--;
}
if(direction==1){
if(lst[i]>lst[pivot]){
temp=lst[i];
lst[i]=lst[pivot];
lst[pivot]=temp;
pivot=i;
direction=-1;
}else i++;
}
}
quickSort(lst, left, i);
quickSort(lst, i+1, right);
}
void main(){
List<int> intSet=generateIntegers();
print('The original list is $intSet');
quickSort(intSet, 0, intSet.length-1);
print('The sorted list by QUICKSORT is $intSet');
}
/*
Result shown below:
The original list is [3761, 3594, 9967, 2097, 4347, 5986, 9720, 5711, 6201, 4953]
The sorted list by QUICKSORT is [2097, 3594, 3761, 4347, 4953, 5711, 5986, 6201, 9720, 9967]
*/
生成的结果在代码注释区,原始数列是随机生成的,所以读者本地跑的结果可能跟我的不同。
2.归并排序(merge sort)
归并排序顾名思义,先是将乱序数组重的元素两两一排序,再合并为四元素的子数组,再两个四元素数组按大小排列为八元素数组,以此类推,直至子数组归并为一个升序排列数组。这里代码也是用递归的方法实现的,实际过程就是 排列合并再排列。下面给出Dart源码:
import 'dart:math';
List<int> generateIntegers(){
List<int> li=List<int>();
for(int i=0;i<10;i++){
int x=Random().nextInt(10000);
li.add(x);
}
return li;
}
void swap(List<int> l, int i, int j){
int temp=l[i];
l[i]=l[j];
l[j]=temp;
}
void merge(List<int> lst, int left, int mid, int right){
int i=left, j=mid+1;
List<int> temp=List<int>();
while(i<=mid && j<=right){
if(lst[i]<lst[j]){
temp.add(lst[i++]);
}else{
temp.add(lst[j++]);
}
}
while(i<=mid){
temp.add(lst[i++]);
}
while(j<=right){
temp.add(lst[j++]);
}
for(int k=left;k<=right;k++)
lst[k]=temp[k-left];
}
void sort(List<int> lst, int left, int right){
if(left>=right)return;
int mid=(left+right)~/2;
sort(lst, left, mid);
sort(lst, mid+1, right);
merge(lst, left, mid, right);
}
void main(){
List<int> numSet=generateIntegers();
print('The original list is $numSet');
sort(numSet, 0, numSet.length-1);
print('The sorted list by MERGESORT is $numSet');
}
/*
Result shown below:
The original list is [342, 1179, 6556, 9849, 1456, 2308, 4145, 7191, 4908, 6185]
The sorted list by MERGESORT is [342, 1179, 1456, 2308, 4145, 4908, 6185, 6556, 7191, 9849]
*/
3.堆排序(heap sort)
堆排序可以在一个数组内存中完成(in-place algorithm),这里还是以升序排列为例,采用的是最大堆。首先拿到一个乱序数组,先建立最大堆,然后将最后一个元素同堆顶元素互换位置,进行堆调整;再将倒数第二位的元素和堆顶元素互换位置,调整堆;以此类推,直至堆中元素只剩下堆顶元素为止。这样,我们就实现了升序目的的堆排序。降序同理,采用最小堆即可实现。下面是Dart源码:
import 'dart:math';
List<int> generateIntegers(){
List<int> li=List<int>();
for(int i=0;i<10;i++){
int x=Random().nextInt(10000);
li.add(x);
}
return li;
}
void swap(List<int> l, int i, int j){
int temp=l[i];
l[i]=l[j];
l[j]=temp;
}
void buildUpHeap(List<int> li){
int len=li.length, cnt=0, temp=0;
do{
cnt=0;
for(int i=0;i*2+1<len;i++){
if(i*2+2<len){
if(li[i*2+1]>li[i*2+2] && li[i*2+1]>li[i]){
swap(li, i, i*2+1);
cnt++;
}else if(li[2*i+2]>li[2*i+1] && li[2*i+2]>li[i]){
swap(li, i, i*2+2);
cnt++;
}
}else if(i*2+1<len){
if(li[2*i+1]>li[i]){
swap(li, i, i*2+1);
cnt++;
}
}
}
}while(cnt>0);
}
void adjustHeap(List<int> lst, int border){
int pos=0;
while(2*pos+1<=border){
if(2*pos+2<=border){
if(lst[2*pos+1]>lst[2*pos+2] && lst[2*pos+1]>lst[pos]){
swap(lst, pos, 2*pos+1);
pos=2*pos+1;
}else if(lst[2*pos+2]>lst[2*pos+1] && lst[2*pos+2]>lst[pos]){
swap(lst, pos ,2*pos+2);
pos=2*pos+2;
}else break;
}else if(2*pos+1<=border && lst[2*pos+1]>lst[pos]){
swap(lst, pos, 2*pos+1);
pos=2*pos+1;
}else break;
}
}
void heapSort(List<int> lst){
int len=lst.length;
buildUpHeap(lst);
for(int i=len-1;i>0;i--){
if(lst[i]<lst[0]){
swap(lst, 0, i);
adjustHeap(lst, i-1);
}
}
}
void main(){
List<int> intSet=generateIntegers();
print('The original list is $intSet');
heapSort(intSet);
print('The sorted list by HEAPSORT is $intSet');
}
/*
Result shown below:
The original list is [3326, 9956, 696, 5419, 1803, 8834, 7000, 2581, 5834, 3615]
The sorted list by HEAPSORT is [696, 1803, 2581, 3326, 3615, 5419, 5834, 7000, 8834, 9956]
*/
最后,我想在南京找份flutter的开发工作,有需求的请联系我,谢谢~ 祝大家工作顺利,开开心心做开发~