排序算法:QuickSort以及dualPivotQuickSort的练习_java和C++源码

2022-03-08 0 5,708

前些日子,java网友聊排序,
谈到Java库的排序算法有双轴快排比普通快排好,
然后一个好奇,就度娘看了看原理思想,自己写着练手

说下算法核心大概思想:

QuickSort:
取一个基数,把元素划分2边,
一边小于这个基数,一边大于这个基数,
然后一直这样划分到最小,也就把所有元素排序完成了
dualPivotQuickSort:
核心思想跟上面一样,都是划分元素
不过这个有2个基数,也就是把元素划分3份

接下来直接分享学习源码:

C++版:经典快排

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
//交换2个元素
void QuickSort::swap(int* a, int* b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}
/**
 * 快速排序的核心算法
 * @param arr       需要排序的数组
 * @param start     排序的开始位置
 * @param end       排序的结束位置
 */
 void QuickSort::qSort(int* arr, int start, int end) {
    //防止无限递归
    if (end > start) {
        int low = start++;
        int high = end;
        int pivot = arr[low];
        //基于pivot划分位置
        while (start < end) {
            if (arr[start] < pivot) {
                start++;
            }
            else {
                this->swap(arr+start, arr+end--);
            }
        }
        //防止停止位置的值大于基数
        if (arr[start] >= pivot) {
            start--;
        }
        this->swap(arr+start, arr+low);
        //继续划分更小
        this->qSort(arr, low, start);
        this->qSort(arr, start + 1, high);
    }
}

C++版:双轴快排

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
/**
  * 双轴快速排序的核心算法
  * @param arr       需要排序的数组
  * @param start     排序的开始位置
  * @param end       排序的结束位置
  */
void QuickSort::dualPivotQuickSort(int* arr, int start, int end) {
    //如果数量太少则直接采用经典的单轴快排
    if (end - start < 64) {
        this->qSort(arr, start, end);
        return;
    }
    //双轴快排核心
    int low = start++;
    int high = end--;
    //先排序前面6个元素
    this->qSort(arr, low, low + 5);
    //初始化双轴的2个基数
    this->swap(arr+low, arr+low + 1);
    this->swap(arr+high, arr+low + 3);
    int pivotLow = arr[low], pivotHigh = arr[high];
    int lowIndex = low + 1, highIndex = high - 1;
    //基于pivot划分位置
    while (start < end) {
        //小于左边基数
        if (arr[start] < pivotLow) {
            this->swap(arr+start++, arr+lowIndex++);
        }
        //大于右边基数
        else if (arr[start] > pivotHigh) {
            this->swap(arr+start, arr+highIndex--);
            end--;
        }
        //位置2个基数中间
        else {
            start++;
        }
    }
    //修正基数位置
    --lowIndex;
    if (arr[highIndex] < pivotLow) {
        this->swap(arr+low, arr+highIndex);
    }
    else if (arr[highIndex] >= pivotHigh) {
        --highIndex;
    }
    //继续划分更小
    dualPivotQuickSort(arr, low, lowIndex);//左边
    dualPivotQuickSort(arr, lowIndex + 1, highIndex);//中间
    dualPivotQuickSort(arr, highIndex + 1, high);//右边
}

C++版:双轴快速无递归方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
/**
  * 双轴快速排序的核心算法_去掉递归
  * @param arr       需要排序的数组
  * @param start     排序的开始位置
  * @param end       排序的结束位置
  */
void QuickSort::dualPivotQuickSortNoRecursion(int* arr, int start, int end) {
    int indexLen = pow(log2(end - start), 2) + 8;
    int current = indexLen;
    int* index = new int[indexLen+1];
SORT:
    //如果数量太少则直接采用经典的单轴快排
    if (end - start < 64) {
        this->qSort(arr, start, end);
        //判断是否全部排序完成
        if (current < indexLen){
            start = index[++current];
            end = index[++current];
            goto SORT;
        }
        else
        {
            return;
        }        
    }
    //双轴快排核心
    int low = start++;
    int high = end--;
    //先排序前面6个元素
    this->qSort(arr, low, low + 5);
    //初始化双轴的2个基数
    this->swap(arr + low, arr + low + 1);
    this->swap(arr + high, arr + low + 3);
    int pivotLow = arr[low], pivotHigh = arr[high];
    int lowIndex = low + 1, highIndex = high - 1;
    //基于pivot划分位置
    while (start < end) {
        //小于左边基数
        if (arr[start] < pivotLow) {
            this->swap(arr + start++, arr + lowIndex++);
        }
        //大于右边基数
        else if (arr[start] > pivotHigh) {
            this->swap(arr + start, arr + highIndex--);
            end--;
        }
        //位置2个基数中间
        else {
            start++;
        }
    }
    //修正基数位置
    --lowIndex;
    if (arr[highIndex] < pivotLow) {
        this->swap(arr + low, arr + highIndex);
    }
    else if (arr[highIndex] >= pivotHigh) {
        --highIndex;
    }
    //分割位置_最大
    index[current--] = high;
    index[current--] = highIndex + 1;
    //分割位置_中间
    index[current--] = highIndex;
    index[current--] = lowIndex + 1;
    //分割位置_最小
    end = lowIndex;
    start = low;
    goto SORT;
}

其实,这些东西,我真心用不上
只是刚好网友聊到,自己失业没事做,陪着他玩了,
感觉这些知道下概念就行,真写都用别人封装好的
java的也写了一份,一起分享了吧

java版:经典快排

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
/**
    * 快速排序的核心算法
    * @param arr       需要排序的数组
    * @param start     排序的开始位置
    * @param end       排序的结束位置
    */
   public void qSort(int[] arr,int start,int end){
       //防止无限递归
       if(end>start){
           int low =start++;
           int high = end;
           int pivot =arr[low];
           //基于pivot划分位置
           while (start < end){
               if (arr[start] < pivot){
                   start++;
               }else {
                   swap(arr,start,end--);
               }
           }
           //防止停止位置的值大于基数
           if (arr[start] >= pivot){
               start--;
           }
           swap(arr,start,low);
           //继续划分更小
           qSort(arr,low,start);
           qSort(arr,start+1,high);
       }
   }
   /**
    * 交换数组中的2个元素
    * @param arr       数组
    * @param indexA    元素A的位置
    * @param indexB    元素B的位置
    */
   public void swap(int[] arr,int indexA,int indexB){
       int temp = arr[indexA];
       arr[indexA] = arr[indexB];
       arr[indexB]=temp;
   }

java版:双轴快排

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
/**
   * 快速排序
   * @param arr 需要排序的数组
   */
  public void quickSort(int[] arr){
      dualPivotQuickSort(arr,0,arr.length-1);
  }
  /**
   * 双轴快速排序的核心算法
   * @param arr       需要排序的数组
   * @param start     排序的开始位置
   * @param end       排序的结束位置
   */
  public void dualPivotQuickSort(int[] arr,int start,int end){
      //如果数量太少则直接采用经典的单轴快排
      if (end-start < 64) {
          qSort(arr,start,end);
          return;
      }
      //双轴快排核心
      int low =start++;
      int high = end--;
      //先排序前面6个元素
      qSort(arr,low,low+5);
      //初始化双轴的2个基数
      swap(arr,low,low+1);
      swap(arr,high,low+3);
      int pivotLow =arr[low],pivotHigh =arr[high];
      int lowIndex =low+1,highIndex=high-1;
      //基于pivot划分位置
      while (start < end){
          //小于左边基数
          if (arr[start] < pivotLow){
              swap(arr,start++,lowIndex++);
          }
          //大于右边基数
          else if(arr[start] > pivotHigh){
              swap(arr,start,highIndex--);
              end--;
          }
          //位置2个基数中间
          else{
              start++;
          }
      }
      //修正基数位置
      --lowIndex;
      if (arr[highIndex] < pivotLow ) {
          swap(arr,low,highIndex);
      }else if (arr[highIndex] >= pivotHigh){
          --highIndex;
      }
      //继续划分更小
      dualPivotQuickSort(arr,low,lowIndex);//左边
      dualPivotQuickSort(arr,lowIndex+1,highIndex);//中间
      dualPivotQuickSort(arr,highIndex+1,high);//右边
  }
收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

注:在使用本系统时,使用方必须在国家相关法律法规范围内并经过国家相关部门的授权许可,禁止用于一切非法行为。使用用途仅限于测试、实验、研究为目的,禁止用于一切商业运营,本团队不承担使用者在使用过程中的任何违法行为负责。

83源码 技术教程 排序算法:QuickSort以及dualPivotQuickSort的练习_java和C++源码 https://www.83ym.com/149.html

认准唯一TG:@ym830

常见问题
  • 站内所有资源,针对不同等级VIP会员可直接下载,特殊资源商品会注明是否免费,指会员所享有根据选择购买的会员选项所享有的特殊服务,具体以本站公布的服务内容为准。
查看详情
  • 按照我国的法律规定,运营网络棋牌首先需要成立一个注册正规备案的公司,然后申请网站备案、文网文、ICP等等,这些证件缺一不可。 一.注册公司 在当地工商进行注册,公司名称以“XX科技有限公司”为名,如:富裕棋牌经营范围填写“计算机软硬件、网络设备的设计开发与购销”。 二.域名及网站备案 在国内从事网站经营活动就必须经过相关部门的备案,因此棋牌运营商在购买了域名后,就要到当地网监局办理网站备案,或者请服务器提供商代为备案。 三.申请文网文 文网文全称为网络文化经营许可证,是从事经营性互联网文化活动所必需的资质。一般是需要到当地省一级(省、直辖市、自治区)的文化行政部门提出申请,并经由当地的文化行政部门合法批准。次资质要求申请公司注册资金必需达到1000万,并提供游戏版权证明文件。 四.申请ICP ICP又称为增值电信业务许可证,所有网络游戏运营商均需要办理ICP许可证,此证件要求公司注册资金1000万,需到当地市级通讯管理局办理。 五.申请文网游——游戏备案 根据《网络游戏管理暂行办法》(文化部第49号)的规定,国产网络游戏在上网运营之日起30日内应当按规定向国务院文化行政部门履行备案手续。 以上就是网络棋牌游戏正规运营所必需的资质证明。一般作为正规有实力的棋牌游戏开发公司,不光要具备所有的正规资质,而且会对投资者、代理商等合作伙伴给予相关指导和协助,与合作伙伴携手共赢!
查看详情

相关文章

猜你喜欢
官方客服团队

为您解决烦忧 - 24小时在线 专业服务