Dart语言实现quickSort, mergeSort和heapSort

1,443 阅读5分钟

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的开发工作,有需求的请联系我,谢谢~ 祝大家工作顺利,开开心心做开发~