日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

快排优化

發布時間:2023/11/16 windows 81 coder
生活随笔 收集整理的這篇文章主要介紹了 快排优化 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

實驗一:快速排序算法及其優化

編程實現快速排序

// 編程實現的快排
void qSort(int n[],int l,int r){
     if(l>=r){
         return;
     }
     int i,j;
     i=l-1;
     j=r+1;
     int x = n[ (i+j)/2 ];
     while(i<j){
         do i++ ;while(n[i]<x);
         do j-- ;while(n[j]>x);
         if(i<j){
             int ten = n[i];
             n[i] = n[j];
             n[j] = ten;
         }
     }
     qSort(n,l,j);
     qSort(n,j+1,r);
 }

快速排序的優化

1)基準的選擇

1)基準的選擇:快速排序的運行時間與劃分是否對稱有關。最壞情況下,每次劃分過程產生兩個區域分別包含n-1個元素和1個元素,其時間復雜度會達到O(n^2)。在最好的情況下,每次劃分所取的基準都恰好是中值,即每次劃分都產生兩個大小為n/2的區域。此時,快排的時間復雜度為O(nlogn)。

所以基準的選擇對快排而言至關重要。快排中基準的選擇方式主要有以下三種:① 固定基準; ② 隨機基準; ③ 三數取中

固定基準

// 編程實現的快排
// 固定基準
void qSort(int n[],int l,int r){
     if(l>=r){
         return;
     }
     int i,j;
     i=l-1;
     j=r+1;
     int x = n[ (i+j)/2 ];
     while(i<j){
         do i++ ;while(n[i]<x);
         do j-- ;while(n[j]>x);
         if(i<j){
             int ten = n[i];
             n[i] = n[j];
             n[j] = ten;
         }
     }
     qSort(n,l,j);
     qSort(n,j+1,r);
 }

隨機基準

std::mt19937_64 gen(std::random_device{}());

int generateRandomNumber(int min_value, int max_value) {
    std::uniform_int_distribution<int> distribution(min_value, max_value);
    return distribution(gen);
}

// 元素互換
void swap(int* arr,int i,int j) {
	int temp = arr[i];
	arr[i] = arr[j];
	arr[j] = temp;
}

// 編程實現的快排
void qSort(int n[],int l,int r){
     if(l>=r){
         return;
     }
     int i,j;
     i=l-1;
     j=r+1;
     int x = n[ (i+j)/2 ];
     
     // 改為隨機基準
     int xx = generateRandomNumber(l,r);
     swap(n ,(i+j)/2  , xx);
     x = n[ (i+j)/2 ];



     while(i<j){
         do i++ ;while(n[i]<x);
         do j-- ;while(n[j]>x);
         if(i<j){
             int ten = n[i];
             n[i] = n[j];
             n[j] = ten;
         }
     }
     qSort(n,l,j);
     qSort(n,j+1,r);
 }
 

三數取中

void quick_sort(int q[], int l, int r)
{
    if (l >= r) return;

    int i = l - 1, j = r + 1, x =(l + r) >> 1;
    // 多數取中法
    int lll = 3;
    if(r-l+1>=lll){
        
        for (int i = l+1; i <= l+lll; i++) {
            int key = q[i];
            int j = i - 1;
        
            while (j >= l && q[j] > key) {
                q[j + 1] = q[j];
                j--;
            }
        
            q[j + 1] = key;
        }
        int te = q[l+lll];
        q[l+lll] = q[x];
        q[x] = te;
    }
    x = q[x]; 
    while (i < j)
    {
        do i ++ ; while (q[i] < x);
        do j -- ; while (q[j] > x);
        if (i < j){
            int rdf = q[i];
            q[i] = q[j];
            q[j] = rdf;
        }
    }
    quick_sort(q, l, j), quick_sort(q, j + 1, r);
}


2)(習題7.4-5)

void quick_sort(int q[], int l, int r)
{
    if (l >= r) return;
    if(r-l+1<=10){
        for (int i = l+1; i <= r; i++) {
        int key = q[i];
        int j = i - 1;
        
        while (j >= l && q[j] > key) {
            q[j + 1] = q[j];
            j--;
        }
        
        q[j + 1] = key;
        }
        return;
    }

    int i = l - 1, j = r + 1, x =(l + r) >> 1;


    x = q[x];

    while (i < j)
    {
        do i ++ ; while (q[i] < x);
        do j -- ; while (q[j] > x);
        if (i < j){
            int rdf = q[i];
            q[i] = q[j];
            q[j] = rdf;
        }
    }
    quick_sort(q, l, j), quick_sort(q, j + 1, r);
}

我的其他優化方式

拆遞歸

#include<stack>// 記得導入棧

void quick_sort2(int q[], int ll, int rr){
//    int ind = 0;
   int l,r;
   stack<int> sta;
   // 也可以用數組  

    sta.push(ll);
    sta.push(rr);
    
   
   while(!sta.empty()){
    // r = sta[--ind];
    // l = sta[--ind];
    r = sta.top();
    sta.pop();
    l = sta.top();
    sta.pop();
    

    if (l >= r) continue;
    if(r-l+1<=20){// 結合插入排序
        for (int i = l+1; i <= r; i++) {
        int key = q[i];
        int j = i - 1;
        
        while (j >= l && q[j] > key) {
            q[j + 1] = q[j];
            j--;
        }
        
        q[j + 1] = key;
        }
        continue;
    }


    // 多元取中
    int lll = 5;
    for (int i = l+1; i <= l+lll; i++) {
        int key = q[i];
        int j = i - 1;
        
        while (j >= l && q[j] > key) {
            q[j + 1] = q[j];
            j--;
        }
        
        q[j + 1] = key;
    }
    int te = q[l+lll];
    q[l+lll] = q[x];
    q[x] = te;
    i = l+lll-1;

    x = q[x];


    while (i < j)
    {
        do i ++ ; while (q[i] < x);
        do j -- ; while (q[j] > x);
        if (i < j){
            int rdf = q[i];
            q[i] = q[j];
            q[j] = rdf;
        }
    }
    sta.push(l);
    sta.push(j);
    sta.push(j+1);
    sta.push(r);
   }

}

多線程

雙線程

//  多線程之雙線程

#include <iostream>
#include <chrono>
#include<stack>//使用stack時需要的頭文件 
#include<mingw.thread.h> // 我的vscode   如果是別的編譯器直接用thread包就可以
using namespace std;

void threadFunctionA(int q[], int ll, int rr){
//    int ind = 0;
   int l,r;
   stack<int> sta;
    sta.push(ll);
    sta.push(rr);
    
   
   while(!sta.empty()){
    // r = sta[--ind];
    // l = sta[--ind];
    r = sta.top();
    sta.pop();
    l = sta.top();
    sta.pop();
    

    if (l >= r) continue;
    if(r-l+1<=20){
        for (int i = l+1; i <= r; i++) {
        int key = q[i];
        int j = i - 1;
        
        while (j >= l && q[j] > key) {
            q[j + 1] = q[j];
            j--;
        }
        
        q[j + 1] = key;
        }
        continue;
    }

    int i = l - 1, j = r + 1, x =(l + r) >> 1;

    // 多元取中
    int lll = 5;
    for (int i = l+1; i <= l+lll; i++) {
        int key = q[i];
        int j = i - 1;
        
        while (j >= l && q[j] > key) {
            q[j + 1] = q[j];
            j--;
        }
        
        q[j + 1] = key;
    }
    int te = q[l+lll];
    q[l+lll] = q[x];
    q[x] = te;
    i = l+lll-1;

    x = q[x];


    while (i < j)
    {
        do i ++ ; while (q[i] < x);
        do j -- ; while (q[j] > x);
        if (i < j){
            int rdf = q[i];
            q[i] = q[j];
            q[j] = rdf;
        }
    }
    sta.push(l);
    sta.push(j);
    sta.push(j+1);
    sta.push(r);
   }

}

void quick_sort3(int q[], int l, int r)
{
    // 多線程
    if (l >= r) return;
    if(r-l+1<=10){
        for (int i = l+1; i <= r; i++) {
        int key = q[i];
        int j = i - 1;
        
        while (j >= l && q[j] > key) {
            q[j + 1] = q[j];
            j--;
        }
        
        q[j + 1] = key;
        }
        return;
    }

    int i = l - 1, j = r + 1, x =(l + r) >> 1;

    // 另一種取中
    int lll = 5;
    for (int i = l+1; i <= l+lll; i++) {
        int key = q[i];
        int j = i - 1;
        
        while (j >= l && q[j] > key) {
            q[j + 1] = q[j];
            j--;
        }
        
        q[j + 1] = key;
    }
    int te = q[l+lll];
    q[l+lll] = q[x];
    q[x] = te;

    x = q[x];
    i = l+lll-1;

    while (i < j)
    {
        do i ++ ; while (q[i] < x);
        do j -- ; while (q[j] > x);
        if (i < j){
            int rdf = q[i];
            q[i] = q[j];
            q[j] = rdf;
        }
    }
    // quick_sort(q, l, j), quick_sort(q, j + 1, r);
    thread newTh1(threadFunctionA, q, l,j);
    thread newTh2(threadFunctionA, q, j+1,r);
    // 這里是拆分為兩個線程
    newTh1.join();
    newTh2.join(); 
}

四線程

// 四線程并發

#include <iostream>
#include <chrono>
#include<stack>//使用stack時需要的頭文件 
#include<mingw.thread.h> // 我的vscode   如果是別的編譯器直接用thread包就可以
using namespace std;

void threadForSort(int q[], int ll, int rr)
{
    // 消遞歸
   int ind = 0;
   int l,r;
   int* sta1 = new int[1000000]; // 也可以用stack  沒太大差別 所以暫時沒優化
   sta1[ind++] = ll;
   sta1[ind++] = rr;
   
   while(ind>0){
    r = sta1[--ind];
    l = sta1[--ind];
    

    if (l >= r) continue;
    if(r-l+1<=20){
        for (int i = l+1; i <= r; i++) {
        int key = q[i];
        int j = i - 1;
        
        while (j >= l && q[j] > key) {
            q[j + 1] = q[j];
            j--;
        }
        
        q[j + 1] = key;
        }
        continue;
    }

    int i = l - 1, j = r + 1, x =(l + r) >> 1;

    // 另一種取中
    int lll = 5;
    for (int i = l+1; i <= l+lll; i++) {
        int key = q[i];
        int j = i - 1;
        
        while (j >= l && q[j] > key) {
            q[j + 1] = q[j];
            j--;
        }
        
        q[j + 1] = key;
    }
    int te = q[l+lll];
    q[l+lll] = q[x];
    q[x] = te;
    i = l+lll-1;

    x = q[x];


    while (i < j)
    {
        do i ++ ; while (q[i] < x);
        do j -- ; while (q[j] > x);
        if (i < j){
            int rdf = q[i];
            q[i] = q[j];
            q[j] = rdf;
        }
    }
    sta1[ind++] =l ;
    sta1[ind++] =j ;
    sta1[ind++] =j+1 ;
    sta1[ind++] =r ;

    

   }
   delete[] sta1;


}


// 元素互換
void swap(int* arr,int i,int j) {
	int temp = arr[i];
	arr[i] = arr[j];
	arr[j] = temp;
}

// 數組分區
int partition(int* arr, int strat, int end) {
	// 選取一個分區的-支點
	int pivot = arr[strat];
 
	// 左右指針指向
	int left = strat, right = end;
 
	while (left < right)
	{
		// 分別從左右兩邊遍歷數組
		while (arr[left] <= pivot && left < right)
			left++;
		while (arr[right] >= pivot && left < right)
			right--;
 
		// 交換左右指針的值
		swap(arr, left, right);
	}
 
	if (arr[left] < pivot)
	{
		swap(arr, strat, left);
		return left;
	}
	else if (arr[left] > pivot)
	{
		swap(arr, strat, left - 1);
		return left - 1;
	}
}
 

// 四線程
// 定義快速排序函數,遞歸實現
void quick_sort4(int* q, int l, int r) {
	// 前提條件
	if (l >= r)
		return;

	// 分區,返回分區下標
	int mid = partition(q, l, r);

    // 現在 拆成四個線程

	// 遞歸調用
	// quickSort(q, l, mid - 1); // 這里對應兩個線程
    int mid1 = partition(q, l, mid - 1);
    thread newTh1(threadForSort, q, l,mid1-1);
    thread newTh2(threadForSort, q, mid1+1,mid-1);
	// quickSort(q, mid + 1, r);// 這里也對應兩個線程
    mid1 = partition(q, mid + 1, r);
    thread newTh3(threadForSort, q, mid+1,mid1-1);
    thread newTh4(threadForSort, q, mid1+1,r);
    newTh1.join();
    newTh2.join();
    newTh3.join();
    newTh4.join();
}
 

動態多線程

除了多線程之外的方法都沒有特別明顯的速度提升

同時,雙線程,四線程的提升也都不如這里的動態多線程

所以 僅在這里展示一下 加速效果 同時提供我自己寫的測試函數

// 動態進行多線程劃分

#include <iostream>
#include <chrono>
#include<stack>//使用stack時需要的頭文件 
#include<mingw.thread.h> // 我的vscode   如果是別的編譯器直接用thread包就可以
using namespace std;
int maxLength = 1000000;// 測試數據長度
int devideSize = maxLength/100; // 開新線程標準 防止產生太多線程   數據長度大于此數時開啟新線程
int testNum = 15;// 測試次數
// volatile int maxThread

int compare(const void *a, const void *b)
{
    int *pa = (int*)a;
    int *pb = (int*)b;
    return (*pa )- (*pb);  //從小到大排序
}

int* getRand(int length)
{
    
    int* n = new int[length];
    int i;
    for(i=0;i<length;i++){
        n[i] = rand();
    }
    return n;
}


void threadForSort(int q[], int ll, int rr)
{
    // thread* all[10000];
    // int thNum = 0;
    // 消遞歸
   int ind = 0;
   int l,r;
   int* sta1 = new int[1000000]; // 也可以用stack  沒太大差別 所以暫時沒優化
   sta1[ind++] = ll;
   sta1[ind++] = rr;
   
   while(ind>0){
    r = sta1[--ind];
    l = sta1[--ind];
    

    if (l >= r) continue;
    if(r-l+1<=20){
        for (int i = l+1; i <= r; i++) {
        int key = q[i];
        int j = i - 1;
        
        while (j >= l && q[j] > key) {
            q[j + 1] = q[j];
            j--;
        }
        
        q[j + 1] = key;
        }
        continue;
    }

    int i = l - 1, j = r + 1, x =(l + r) >> 1;

    // 另一種取中
    int lll = 5;
    for (int i = l+1; i <= l+lll; i++) {
        int key = q[i];
        int j = i - 1;
        
        while (j >= l && q[j] > key) {
            q[j + 1] = q[j];
            j--;
        }
        
        q[j + 1] = key;
    }
    int te = q[l+lll];
    q[l+lll] = q[x];
    q[x] = te;
    i = l+lll-1;

    x = q[x];


    while (i < j)
    {
        do i ++ ; while (q[i] < x);
        do j -- ; while (q[j] > x);
        if (i < j){
            int rdf = q[i];
            q[i] = q[j];
            q[j] = rdf;
        }
    }
    // thread* point1 = NULL;
    // thread* point2 = NULL;
    
    if( j-l>devideSize ){
        thread newTh1(threadForSort, q, l,j);
        // all[thNum++] = &newTh1;
        // point1 = &newTh1;
        newTh1.join();
    
    }else{
        sta1[ind++] =l ;
        sta1[ind++] =j ;
    }
    if( r-j>devideSize ){
        thread newTh1(threadForSort, q, l,j);
        // point2 = &newTh1;
        newTh1.join();
        
        // all[thNum++] = &newTh1;
    }else{
        sta1[ind++] =j+1 ;
        sta1[ind++] =r ;
    }
    

   }
   delete[] sta1;


}


// 元素互換
void swap(int* arr,int i,int j) {
	int temp = arr[i];
	arr[i] = arr[j];
	arr[j] = temp;
}

void mysort(int *n,int l){
    threadForSort(n,0,l-1);
}



void comprehensiveTest()
{// 進行100次測試   算平均時間  計算性能提升
    double cAllTime = 0;
    double myAllTime = 0;
    int i,j;
    int total = maxLength;
    for(i=0;i<testNum;i++){
        int *num1 = getRand(total);
        int* num2 = new int[total];
        for(j=0;j<total;j++){
            num2[j] = num1[j];
        }

        auto start1 = std::chrono::high_resolution_clock::now(); // 記錄開始時間
        qsort(num1, total, sizeof(int), compare);
        auto end1 = std::chrono::high_resolution_clock::now(); // 記錄結束時間

        auto start2 = std::chrono::high_resolution_clock::now(); // 記錄開始時間
        mysort(num2 , total);
        auto end2 = std::chrono::high_resolution_clock::now(); // 記錄結束時間
        for(j=0;j<total;j++){
            if(num1[i] !=num2[i]){
                cout << "出錯了" << endl;
                break;
            }
        }
        delete[] num1;
        delete[] num2; 
        std::chrono::duration<double, std::milli> cTime = end1 - start1; // 計算執行時間
        std::chrono::duration<double, std::milli> myTime = end2 - start2; // 計算執行時間
        std::cout << "c++程序執行時間:" << cTime.count() << " 毫秒" <<  "    " << "我的程序執行時間:" << myTime.count() << " 毫秒" ;
        double gap = cTime.count()-myTime.count();
        if(gap>0){
            cout << "                 快了  "  << gap << "  " <<endl;
        }else{
            cout << "                 慢了  "  << -1*gap << "  " <<endl;
        }
        cAllTime +=cTime.count();
        myAllTime+=myTime.count();
    }
    cAllTime/=testNum;
    myAllTime/=testNum;
    cout << "平均快了   " << cAllTime-myAllTime << endl;
    cout << "提升比例   " << (cAllTime-myAllTime)/cAllTime << endl;

    


}

void compareTest(){
    int count = 7;
    int allLen[count] = {10000,50000,100000,1000000 , 5000000,8000000 , 10000000};
    // int myScore;
    // int cScore = myScore = 0;
    int i,j;
    for(i=0;i<count;i++){
        int *num1 = getRand(allLen[i]);
        int* num2 = new int[allLen[i]];
        for(j=0;j<allLen[i];j++){
            num2[j] = num1[j];
        }

        auto start1 = std::chrono::high_resolution_clock::now(); // 記錄開始時間
        qsort(num1, allLen[i], sizeof(int), compare);
        auto end1 = std::chrono::high_resolution_clock::now(); // 記錄結束時間

        auto start2 = std::chrono::high_resolution_clock::now(); // 記錄開始時間
        mysort(num2 , allLen[i]);
        auto end2 = std::chrono::high_resolution_clock::now(); // 記錄結束時間
        for(j=0;j<allLen[i];j++){
            if(num1[i] !=num2[i]){
                cout << "出錯了" << endl;
                break;
            }
        }
        delete[] num1;
        delete[] num2; 
        std::chrono::duration<double, std::milli> cTime = end1 - start1; // 計算執行時間
        std::chrono::duration<double, std::milli> myTime = end2 - start2; // 計算執行時間
        std::cout << "c++程序執行時間:" << cTime.count() << " 毫秒" <<  "    " << "我的程序執行時間:" << myTime.count() << " 毫秒" ;
        double gap = cTime.count()-myTime.count();
        if(gap>0){
            cout << "                 快了  "  << gap << "  " <<endl;
        }else{
            cout << "                 慢了  "  << -1*gap << "  " <<endl;
        }
    }

}

int main()
{
    srand(time(0));

    // compareTest();
    comprehensiveTest();


    return 0;
}

在我自己電腦上的輸出:

c++程序執行時間:80.01 毫秒    我的程序執行時間:19.538 
毫秒                 快了  60.472
c++程序執行時間:79.171 毫秒    我的程序執行時間:30.538 毫秒                 快了  48.633
c++程序執行時間:82.023 毫秒    我的程序執行時間:36.338 毫秒                 快了  45.685
c++程序執行時間:78.11 毫秒    我的程序執行時間:23.378 
毫秒                 快了  54.732
c++程序執行時間:79.382 毫秒    我的程序執行時間:27.272 毫秒                 快了  52.11
c++程序執行時間:79.223 毫秒    我的程序執行時間:19.551 毫秒                 快了  59.672
c++程序執行時間:79.345 毫秒    我的程序執行時間:23.529 毫秒                 快了  55.816
c++程序執行時間:78.306 毫秒    我的程序執行時間:25.156 毫秒                 快了  53.15
c++程序執行時間:78.463 毫秒    我的程序執行時間:21.429 毫秒                 快了  57.034
c++程序執行時間:78.98 毫秒    我的程序執行時間:28.995 
毫秒                 快了  49.985
c++程序執行時間:78.659 毫秒    我的程序執行時間:22.821 毫秒                 快了  55.838
c++程序執行時間:78.817 毫秒    我的程序執行時間:25.161 毫秒                 快了  53.656
c++程序執行時間:79.496 毫秒    我的程序執行時間:25.921 毫秒                 快了  53.575
c++程序執行時間:78.601 毫秒    我的程序執行時間:31.099 毫秒                 快了  47.502
c++程序執行時間:79.954 毫秒    我的程序執行時間:21.93 
毫秒                 快了  58.024
平均快了   53.7256
提升比例   0.678045
PS E:\c++_proje

我的其他優化方式--算法思想描述

  • 在拆遞歸之前,也嘗試了多元取中法,以及在長度足夠短的時候采用插入排序直接排序的算法,所以在我的其他優化中都加入了這些成分。

拆遞歸思想

拆遞歸的優化方式是考慮到算法的遞歸調用是有一定的代價的,但其實每次遞歸只是傳遞的兩個下標的差異,所以采用棧來拆解遞歸,進而算法執行的整個流程就不再進行遞歸調用。這樣就能降低成本

雙線程和四線程思想

因為我們進行一次partition之后,就會分解成兩個序列,在對兩個序列進行單獨處理。同時也沒有處理之后的合并操作。所以可以將兩個序列的操作分給兩個不同的線程進行處理,然后等待兩個線程執行完畢即可。 同樣的四線程也是這樣,進行了兩次partition之后,拆成四段之后在進行分線程。

動態多線程思想

延續前面的多線程方法,前面給線程設計的方法是通過解遞歸的方式對其所分得的序列進行快排處理,這里改動了一下,為其新增了創建新線程的功能。這樣就是說,我們新建立的線程也能接著拆分出新的線程。這樣就可以動態的進行線程創建。進而提高效率。

同時考慮到如果序列已經夠短了,就不要接著劃分了,所以在代碼的全局變量加入了長度限制,只對足夠長的序列進行下一步的拆分,交給不同的線程。否則就進行普通的解遞歸的快排處理。

附錄----代碼和性能比較

另附 從最開始優化,到最后的動態多線程的代碼(可直接運行測試性能對比)

綜合來看,每一次迭代 性能有提升,同時 在多線程,性能有極大提升

solution1:

//  插入排序 和取中法優化

#include <iostream>
#include <chrono>
#include<stack>
#include<mingw.thread.h>
using namespace std;

int testLength = 1000000;// 測試數據長度
int testNum = 15;// 測試次數




void quick_sort(int q[], int l, int r)
{
    if (l >= r) return;
    if(r-l+1<=10){
        for (int i = l+1; i <= r; i++) {
        int key = q[i];
        int j = i - 1;
        
        while (j >= l && q[j] > key) {
            q[j + 1] = q[j];
            j--;
        }
        
        q[j + 1] = key;
        }
        return;
    }

    int i = l - 1, j = r + 1, x =(l + r) >> 1;




    int lll = 5;
    for (int i = l+1; i <= l+lll; i++) {
        int key = q[i];
        int j = i - 1;
        
        while (j >= l && q[j] > key) {
            q[j + 1] = q[j];
            j--;
        }
        
        q[j + 1] = key;
    }
    int te = q[l+lll];
    q[l+lll] = q[x];
    q[x] = te;
    i = l+lll-1;

    x = q[x];

    while (i < j)
    {
        do i ++ ; while (q[i] < x);
        do j -- ; while (q[j] > x);
        if (i < j){
            int rdf = q[i];
            q[i] = q[j];
            q[j] = rdf;
        }
    }
    quick_sort(q, l, j), quick_sort(q, j + 1, r);
}



int* getRand(int length)
{
    int* n = new int[length];
    int i;
    for(i=0;i<length;i++){
        n[i] = rand();
    }
    return n;
}

int compare(const void *a, const void *b)
{
    int *pa = (int*)a;
    int *pb = (int*)b;
    return (*pa )- (*pb);  //從小到大排序
}






void mysort(int *n,int l){
    quick_sort(n,0,l-1);

}

void comprehensiveTest()
{// 進行100次測試   算平均時間  計算性能提升
    double cAllTime = 0;
    double myAllTime = 0;
    int i,j;
    int total = testLength;
    for(i=0;i<testNum;i++){
        int *num1 = getRand(total);
        int* num2 = new int[total];
        for(j=0;j<total;j++){
            num2[j] = num1[j];
        }

        auto start1 = std::chrono::high_resolution_clock::now(); // 記錄開始時間
        qsort(num1, total, sizeof(int), compare);
        auto end1 = std::chrono::high_resolution_clock::now(); // 記錄結束時間

        auto start2 = std::chrono::high_resolution_clock::now(); // 記錄開始時間
        mysort(num2 , total);
        auto end2 = std::chrono::high_resolution_clock::now(); // 記錄結束時間
        for(j=0;j<total;j++){
            if(num1[i] !=num2[i]){
                cout << "出錯了" << endl;
                break;
            }
        }
        delete[] num1;
        delete[] num2; 
        std::chrono::duration<double, std::milli> cTime = end1 - start1; // 計算執行時間
        std::chrono::duration<double, std::milli> myTime = end2 - start2; // 計算執行時間
        std::cout << "c++程序執行時間:" << cTime.count() << " 毫秒" <<  "    " << "我的程序執行時間:" << myTime.count() << " 毫秒" ;
        double gap = cTime.count()-myTime.count();
        if(gap>0){
            cout << "                 快了  "  << gap << "  " <<endl;
        }else{
            cout << "                 慢了  "  << -1*gap << "  " <<endl;
        }
        cAllTime +=cTime.count();
        myAllTime+=myTime.count();
    }
    cAllTime/=testNum;
    myAllTime/=testNum;
    cout << "平均快了   " << cAllTime-myAllTime << endl;
    cout << "提升比例   " << (cAllTime-myAllTime)/cAllTime << endl;

    


}

void compareTest(){
    int count = 7;
    int allLen[count] = {10000,50000,100000,1000000 , 5000000,8000000 , 10000000};
    int myScor=0;
    // int cScore = myScore = 0;
    int i,j;
    for(i=0;i<count;i++){
        int *num1 = getRand(allLen[i]);
        int* num2 = new int[allLen[i]];
        for(j=0;j<allLen[i];j++){
            num2[j] = num1[j];
        }

        auto start1 = std::chrono::high_resolution_clock::now(); // 記錄開始時間
        qsort(num1, allLen[i], sizeof(int), compare);
        auto end1 = std::chrono::high_resolution_clock::now(); // 記錄結束時間

        auto start2 = std::chrono::high_resolution_clock::now(); // 記錄開始時間
        mysort(num2 , allLen[i]);
        auto end2 = std::chrono::high_resolution_clock::now(); // 記錄結束時間
        for(j=0;j<allLen[i];j++){
            if(num1[i] !=num2[i]){
                cout << "出錯了" << endl;
                break;
            }
        }
        delete[] num1;
        delete[] num2; 
        std::chrono::duration<double, std::milli> cTime = end1 - start1; // 計算執行時間
        std::chrono::duration<double, std::milli> myTime = end2 - start2; // 計算執行時間
        std::cout << "c++程序執行時間:" << cTime.count() << " 毫秒" <<  "    " << "我的程序執行時間:" << myTime.count() << " 毫秒" ;
        double gap = cTime.count()-myTime.count();
        if(gap>0){
            cout << "                 快了  "  << gap << "  " <<endl;
        }else{
            cout << "                 慢了  "  << -1*gap << "  " <<endl;
        }
    }

}

int main()
{
    srand(time(0));

    // compareTest();
    comprehensiveTest();

	

    return 0;
}

性能比較輸出:

PS E:\c++_project\test\算法實驗1\output> cd 'e:\c++_project\test\算法實驗1\output'
PS E:\c++_project\test\算法實驗1\output> & .\'solution1.exe'
c++程序執行時間:80.034 毫秒    我的程序執行時間:75.85 
毫秒                 快了  4.184
c++程序執行時間:79.018 毫秒    我的程序執行時間:77.662 毫秒                 快了  1.356
c++程序執行時間:79.014 毫秒    我的程序執行時間:76.007 毫秒                 快了  3.007
c++程序執行時間:78.297 毫秒    我的程序執行時間:77.185 毫秒                 快了  1.112
c++程序執行時間:79.307 毫秒    我的程序執行時間:76.601 毫秒                 快了  2.706
c++程序執行時間:79.042 毫秒    我的程序執行時間:76.736 毫秒                 快了  2.306
c++程序執行時間:78.652 毫秒    我的程序執行時間:76.327 毫秒                 快了  2.325
c++程序執行時間:83.278 毫秒    我的程序執行時間:77.002 毫秒                 快了  6.276
c++程序執行時間:79.51 毫秒    我的程序執行時間:77.103 
毫秒                 快了  2.407
c++程序執行時間:77.844 毫秒    我的程序執行時間:76.903 毫秒                 快了  0.941
c++程序執行時間:78.333 毫秒    我的程序執行時間:78.68 
毫秒                 慢了  0.347
c++程序執行時間:79.051 毫秒    我的程序執行時間:76.808 毫秒                 快了  2.243
c++程序執行時間:82.108 毫秒    我的程序執行時間:77.068 毫秒                 快了  5.04
c++程序執行時間:78.342 毫秒    我的程序執行時間:77.008 毫秒                 快了  1.334
c++程序執行時間:79.231 毫秒    我的程序執行時間:76.034 毫秒                 快了  3.197
平均快了   2.53913
提升比例   0.0319774

solution2:

//  解遞歸

#include <iostream>
#include <chrono>
#include<stack>//
#include<mingw.thread.h>
using namespace std;
int testLength = 1000000;// 測試數據長度
int testNum = 15;// 測試次數

void quick_sort2(int q[], int ll, int rr){
//    int ind = 0;
   int l,r;
   stack<int> sta;
   // 也可以用數組    不過還是略慢

//    sta[ind++] = ll;
//    sta[ind++] = rr;
    sta.push(ll);
    sta.push(rr);
    
   
   while(!sta.empty()){
    // r = sta[--ind];
    // l = sta[--ind];
    r = sta.top();
    sta.pop();
    l = sta.top();
    sta.pop();
    

    if (l >= r) continue;
    if(r-l+1<=20){
        for (int i = l+1; i <= r; i++) {
        int key = q[i];
        int j = i - 1;
        
        while (j >= l && q[j] > key) {
            q[j + 1] = q[j];
            j--;
        }
        
        q[j + 1] = key;
        }
        continue;
    }

    int i = l - 1, j = r + 1, x =(l + r) >> 1;

    // 多元取中
    int lll = 5;
    for (int i = l+1; i <= l+lll; i++) {
        int key = q[i];
        int j = i - 1;
        
        while (j >= l && q[j] > key) {
            q[j + 1] = q[j];
            j--;
        }
        
        q[j + 1] = key;
    }
    int te = q[l+lll];
    q[l+lll] = q[x];
    q[x] = te;
    i = l+lll-1;

    x = q[x];


    while (i < j)
    {
        do i ++ ; while (q[i] < x);
        do j -- ; while (q[j] > x);
        if (i < j){
            int rdf = q[i];
            q[i] = q[j];
            q[j] = rdf;
        }
    }

    sta.push(l);
    sta.push(j);
    sta.push(j+1);
    sta.push(r);

    

   }

}



int* getRand(int length)
{
    int* n = new int[length];
    int i;
    for(i=0;i<length;i++){
        n[i] = rand();
    }
    return n;
}

int compare(const void *a, const void *b)
{
    int *pa = (int*)a;
    int *pb = (int*)b;
    return (*pa )- (*pb);  //從小到大排序
}






void mysort(int *n,int l){
    quick_sort2(n,0,l-1);

}

void comprehensiveTest()
{// 進行100次測試   算平均時間  計算性能提升
    double cAllTime = 0;
    double myAllTime = 0;
    int i,j;
    int total = testLength;
    for(i=0;i<testNum;i++){
        int *num1 = getRand(total);
        int* num2 = new int[total];
        for(j=0;j<total;j++){
            num2[j] = num1[j];
        }

        auto start1 = std::chrono::high_resolution_clock::now(); // 記錄開始時間
        qsort(num1, total, sizeof(int), compare);
        auto end1 = std::chrono::high_resolution_clock::now(); // 記錄結束時間

        auto start2 = std::chrono::high_resolution_clock::now(); // 記錄開始時間
        mysort(num2 , total);
        auto end2 = std::chrono::high_resolution_clock::now(); // 記錄結束時間
        for(j=0;j<total;j++){
            if(num1[i] !=num2[i]){
                cout << "出錯了" << endl;
                break;
            }
        }
        delete[] num1;
        delete[] num2; 
        std::chrono::duration<double, std::milli> cTime = end1 - start1; // 計算執行時間
        std::chrono::duration<double, std::milli> myTime = end2 - start2; // 計算執行時間
        std::cout << "c++程序執行時間:" << cTime.count() << " 毫秒" <<  "    " << "我的程序執行時間:" << myTime.count() << " 毫秒" ;
        double gap = cTime.count()-myTime.count();
        if(gap>0){
            cout << "                 快了  "  << gap << "  " <<endl;
        }else{
            cout << "                 慢了  "  << -1*gap << "  " <<endl;
        }
        cAllTime +=cTime.count();
        myAllTime+=myTime.count();
    }
    cAllTime/=testNum;
    myAllTime/=testNum;
    cout << "平均快了   " << cAllTime-myAllTime << endl;
    cout << "提升比例   " << (cAllTime-myAllTime)/cAllTime << endl;

    


}

void compareTest(){
    int count = 7;
    int allLen[count] = {10000,50000,100000,1000000 , 5000000,8000000 , 10000000};
    int myScore;
    int cScore = myScore = 0;
    int i,j;
    for(i=0;i<count;i++){
        int *num1 = getRand(allLen[i]);
        int* num2 = new int[allLen[i]];
        for(j=0;j<allLen[i];j++){
            num2[j] = num1[j];
        }

        auto start1 = std::chrono::high_resolution_clock::now(); // 記錄開始時間
        qsort(num1, allLen[i], sizeof(int), compare);
        auto end1 = std::chrono::high_resolution_clock::now(); // 記錄結束時間

        auto start2 = std::chrono::high_resolution_clock::now(); // 記錄開始時間
        mysort(num2 , allLen[i]);
        auto end2 = std::chrono::high_resolution_clock::now(); // 記錄結束時間
        for(j=0;j<allLen[i];j++){
            if(num1[i] !=num2[i]){
                cout << "出錯了" << endl;
                break;
            }
        }
        delete[] num1;
        delete[] num2; 
        std::chrono::duration<double, std::milli> cTime = end1 - start1; // 計算執行時間
        std::chrono::duration<double, std::milli> myTime = end2 - start2; // 計算執行時間
        std::cout << "c++程序執行時間:" << cTime.count() << " 毫秒" <<  "    " << "我的程序執行時間:" << myTime.count() << " 毫秒" ;
        double gap = cTime.count()-myTime.count();
        if(gap>0){
            cout << "                 快了  "  << gap << "  " <<endl;
        }else{
            cout << "                 慢了  "  << -1*gap << "  " <<endl;
        }
    }

}

int main()
{
    srand(time(0));

    // compareTest();
    comprehensiveTest();

	

    return 0;
}

性能比較輸出:

PS E:\c++_project\test\算法實驗1\output> & .\'solution2.exe'
c++程序執行時間:80.02 毫秒    我的程序執行時間:81.006 
毫秒                 慢了  0.986
c++程序執行時間:81.984 毫秒    我的程序執行時間:80.97 
毫秒                 快了  1.014
c++程序執行時間:79.043 毫秒    我的程序執行時間:78.169 毫秒                 快了  0.874
c++程序執行時間:78.602 毫秒    我的程序執行時間:80.156 毫秒                 慢了  1.554
c++程序執行時間:79.379 毫秒    我的程序執行時間:81.455 毫秒                 慢了  2.076
c++程序執行時間:78.129 毫秒    我的程序執行時間:80.998 毫秒                 慢了  2.869
c++程序執行時間:77.955 毫秒    我的程序執行時間:80.001 毫秒                 慢了  2.046
c++程序執行時間:78.999 毫秒    我的程序執行時間:83.083 毫秒                 慢了  4.084
c++程序執行時間:77.839 毫秒    我的程序執行時間:80.166 毫秒                 慢了  2.327
c++程序執行時間:77.955 毫秒    我的程序執行時間:81.564 毫秒                 慢了  3.609
c++程序執行時間:79.192 毫秒    我的程序執行時間:83.518 毫秒                 慢了  4.326
c++程序執行時間:83.464 毫秒    我的程序執行時間:79.676 毫秒                 快了  3.788
c++程序執行時間:80.032 毫秒    我的程序執行時間:79.001 毫秒                 快了  1.031
c++程序執行時間:78.992 毫秒    我的程序執行時間:82.914 毫秒                 慢了  3.922
c++程序執行時間:78.137 毫秒    我的程序執行時間:78 毫
秒                 快了  0.137
平均快了   -1.397
提升比例   -0.0176134

solution3:

//  多線程之雙線程

#include <iostream>
#include <chrono>
#include<stack>//使用stack時需要的頭文件 
#include<mingw.thread.h> // 我的vscode   如果是別的編譯器直接用thread包就可以
using namespace std;

int testLength = 10000000;// 測試數據長度
int testNum = 15;// 測試次數



void threadFunctionA(int q[], int ll, int rr){
//    int ind = 0;
   int l,r;
   stack<int> sta;
   // 也可以用數組    不過還是略慢

//    sta[ind++] = ll;
//    sta[ind++] = rr;
    sta.push(ll);
    sta.push(rr);
    
   
   while(!sta.empty()){
    // r = sta[--ind];
    // l = sta[--ind];
    r = sta.top();
    sta.pop();
    l = sta.top();
    sta.pop();
    

    if (l >= r) continue;
    if(r-l+1<=20){
        for (int i = l+1; i <= r; i++) {
        int key = q[i];
        int j = i - 1;
        
        while (j >= l && q[j] > key) {
            q[j + 1] = q[j];
            j--;
        }
        
        q[j + 1] = key;
        }
        continue;
    }

    int i = l - 1, j = r + 1, x =(l + r) >> 1;

    // 多元取中
    int lll = 5;
    for (int i = l+1; i <= l+lll; i++) {
        int key = q[i];
        int j = i - 1;
        
        while (j >= l && q[j] > key) {
            q[j + 1] = q[j];
            j--;
        }
        
        q[j + 1] = key;
    }
    int te = q[l+lll];
    q[l+lll] = q[x];
    q[x] = te;
    i = l+lll-1;

    x = q[x];


    while (i < j)
    {
        do i ++ ; while (q[i] < x);
        do j -- ; while (q[j] > x);
        if (i < j){
            int rdf = q[i];
            q[i] = q[j];
            q[j] = rdf;
        }
    }
    // sta[ind++] =l ;
    // sta[ind++] =j ;
    // sta[ind++] =j+1 ;
    // sta[ind++] =r ;
    sta.push(l);
    sta.push(j);
    sta.push(j+1);
    sta.push(r);

    

   }

}

void quick_sort3(int q[], int l, int r)
{
    // 多線程
    if (l >= r) return;
    if(r-l+1<=10){
        for (int i = l+1; i <= r; i++) {
        int key = q[i];
        int j = i - 1;
        
        while (j >= l && q[j] > key) {
            q[j + 1] = q[j];
            j--;
        }
        
        q[j + 1] = key;
        }
        return;
    }

    int i = l - 1, j = r + 1, x =(l + r) >> 1;



    // 另一種取中
    int lll = 5;
    for (int i = l+1; i <= l+lll; i++) {
        int key = q[i];
        int j = i - 1;
        
        while (j >= l && q[j] > key) {
            q[j + 1] = q[j];
            j--;
        }
        
        q[j + 1] = key;
    }
    int te = q[l+lll];
    q[l+lll] = q[x];
    q[x] = te;


    x = q[x];
    i = l+lll-1;


    while (i < j)
    {
        do i ++ ; while (q[i] < x);
        do j -- ; while (q[j] > x);
        if (i < j){
            int rdf = q[i];
            q[i] = q[j];
            q[j] = rdf;
        }
    }
    // quick_sort(q, l, j), quick_sort(q, j + 1, r);
    thread newTh1(threadFunctionA, q, l,j);
    thread newTh2(threadFunctionA, q, j+1,r);
    // 這里是拆分為兩個線程
    newTh1.join();
    newTh2.join(); 
}



int* getRand(int length)
{
    int* n = new int[length];
    int i;
    for(i=0;i<length;i++){
        n[i] = rand();
    }
    return n;
}

int compare(const void *a, const void *b)
{
    int *pa = (int*)a;
    int *pb = (int*)b;
    return (*pa )- (*pb);  //從小到大排序
}



void mysort(int *n,int l){
    quick_sort3(n,0,l-1);

}

void comprehensiveTest()
{// 進行100次測試   算平均時間  計算性能提升
    double cAllTime = 0;
    double myAllTime = 0;
    int i,j;
    int total = testLength;
    for(i=0;i<testNum;i++){
        int *num1 = getRand(total);
        int* num2 = new int[total];
        for(j=0;j<total;j++){
            num2[j] = num1[j];
        }

        auto start1 = std::chrono::high_resolution_clock::now(); // 記錄開始時間
        qsort(num1, total, sizeof(int), compare);
        auto end1 = std::chrono::high_resolution_clock::now(); // 記錄結束時間

        auto start2 = std::chrono::high_resolution_clock::now(); // 記錄開始時間
        mysort(num2 , total);
        auto end2 = std::chrono::high_resolution_clock::now(); // 記錄結束時間
        for(j=0;j<total;j++){
            if(num1[i] !=num2[i]){
                cout << "出錯了" << endl;
                break;
            }
        }
        delete[] num1;
        delete[] num2; 
        std::chrono::duration<double, std::milli> cTime = end1 - start1; // 計算執行時間
        std::chrono::duration<double, std::milli> myTime = end2 - start2; // 計算執行時間
        std::cout << "c++程序執行時間:" << cTime.count() << " 毫秒" <<  "    " << "我的程序執行時間:" << myTime.count() << " 毫秒" ;
        double gap = cTime.count()-myTime.count();
        if(gap>0){
            cout << "                 快了  "  << gap << "  " <<endl;
        }else{
            cout << "                 慢了  "  << -1*gap << "  " <<endl;
        }
        cAllTime +=cTime.count();
        myAllTime+=myTime.count();
    }
    cAllTime/=testNum;
    myAllTime/=testNum;
    cout << "平均快了   " << cAllTime-myAllTime << endl;
    cout << "提升比例   " << (cAllTime-myAllTime)/cAllTime << endl;

    


}

void compareTest(){
    int count = 7;
    int allLen[count] = {10000,50000,100000,1000000 , 5000000,8000000 , 10000000};
    // int myScore;
    // int cScore = myScore = 0;
    int i,j;
    for(i=0;i<count;i++){
        int *num1 = getRand(allLen[i]);
        int* num2 = new int[allLen[i]];
        for(j=0;j<allLen[i];j++){
            num2[j] = num1[j];
        }

        auto start1 = std::chrono::high_resolution_clock::now(); // 記錄開始時間
        qsort(num1, allLen[i], sizeof(int), compare);
        auto end1 = std::chrono::high_resolution_clock::now(); // 記錄結束時間

        auto start2 = std::chrono::high_resolution_clock::now(); // 記錄開始時間
        mysort(num2 , allLen[i]);
        auto end2 = std::chrono::high_resolution_clock::now(); // 記錄結束時間
        for(j=0;j<allLen[i];j++){
            if(num1[i] !=num2[i]){
                cout << "出錯了" << endl;
                break;
            }
        }
        delete[] num1;
        delete[] num2; 
        std::chrono::duration<double, std::milli> cTime = end1 - start1; // 計算執行時間
        std::chrono::duration<double, std::milli> myTime = end2 - start2; // 計算執行時間
        std::cout << "c++程序執行時間:" << cTime.count() << " 毫秒" <<  "    " << "我的程序執行時間:" << myTime.count() << " 毫秒" ;
        double gap = cTime.count()-myTime.count();
        if(gap>0){
            cout << "                 快了  "  << gap << "  " <<endl;
        }else{
            cout << "                 慢了  "  << -1*gap << "  " <<endl;
        }
    }

}

int main()
{
    srand(time(0));

    // compareTest();
    comprehensiveTest();

	

    return 0;
}

性能比較輸出:

PS E:\c++_project\test\算法實驗1\output> & .\'solution3.exe'
c++程序執行時間:77.988 毫秒    我的程序執行時間:74.044 毫秒                 快了  3.944
c++程序執行時間:83.498 毫秒    我的程序執行時間:79.803 毫秒                 快了  3.695
c++程序執行時間:79.749 毫秒    我的程序執行時間:52.482 毫秒                 快了  27.267
c++程序執行時間:77.736 毫秒    我的程序執行時間:47.673 毫秒                 快了  30.063
c++程序執行時間:78.066 毫秒    我的程序執行時間:62.493 毫秒                 快了  15.573
c++程序執行時間:80.071 毫秒    我的程序執行時間:78.52 
毫秒                 快了  1.551
c++程序執行時間:78.476 毫秒    我的程序執行時間:79.85 
毫秒                 慢了  1.374
c++程序執行時間:79.398 毫秒    我的程序執行時間:75.689 毫秒                 快了  3.709
c++程序執行時間:79.142 毫秒    我的程序執行時間:80.422 毫秒                 慢了  1.28
c++程序執行時間:81.046 毫秒    我的程序執行時間:74.736 毫秒                 快了  6.31
c++程序執行時間:79.603 毫秒    我的程序執行時間:52.47 
毫秒                 快了  27.133
c++程序執行時間:79.955 毫秒    我的程序執行時間:57.383 毫秒                 快了  22.572
c++程序執行時間:84.608 毫秒    我的程序執行時間:75.01 
毫秒                 快了  9.598
c++程序執行時間:79.721 毫秒    我的程序執行時間:67.263 毫秒                 快了  12.458
c++程序執行時間:82.756 毫秒    我的程序執行時間:77.532 毫秒                 快了  5.224
平均快了   11.0962
提升比例   0.138493

solution4:

// 四線程并發

#include <iostream>
#include <chrono>
#include<stack>//使用stack時需要的頭文件 
#include<mingw.thread.h> // 我的vscode   如果是別的編譯器直接用thread包就可以
using namespace std;
int testLength = 1000000;// 測試數據長度
int testNum = 15;// 測試次數


int compare(const void *a, const void *b)
{
    int *pa = (int*)a;
    int *pb = (int*)b;
    return (*pa )- (*pb);  //從小到大排序
}

int* getRand(int length)
{
    int* n = new int[length];
    int i;
    for(i=0;i<length;i++){
        n[i] = rand();
    }
    return n;
}


void threadForSort(int q[], int ll, int rr)
{
    // 消遞歸
   int ind = 0;
   int l,r;
   int* sta1 = new int[1000000]; // 也可以用stack  沒太大差別 所以暫時沒優化
   sta1[ind++] = ll;
   sta1[ind++] = rr;
   
   while(ind>0){
    r = sta1[--ind];
    l = sta1[--ind];
    

    if (l >= r) continue;
    if(r-l+1<=20){
        for (int i = l+1; i <= r; i++) {
        int key = q[i];
        int j = i - 1;
        
        while (j >= l && q[j] > key) {
            q[j + 1] = q[j];
            j--;
        }
        
        q[j + 1] = key;
        }
        continue;
    }

    int i = l - 1, j = r + 1, x =(l + r) >> 1;

    // 另一種取中
    int lll = 5;
    for (int i = l+1; i <= l+lll; i++) {
        int key = q[i];
        int j = i - 1;
        
        while (j >= l && q[j] > key) {
            q[j + 1] = q[j];
            j--;
        }
        
        q[j + 1] = key;
    }
    int te = q[l+lll];
    q[l+lll] = q[x];
    q[x] = te;
    i = l+lll-1;

    x = q[x];


    while (i < j)
    {
        do i ++ ; while (q[i] < x);
        do j -- ; while (q[j] > x);
        if (i < j){
            int rdf = q[i];
            q[i] = q[j];
            q[j] = rdf;
        }
    }
    sta1[ind++] =l ;
    sta1[ind++] =j ;
    sta1[ind++] =j+1 ;
    sta1[ind++] =r ;
    
    
    // sta.push(l);
    // sta.push(j);
    // sta.push(j+1);
    // sta.push(r);
    

   }
   delete[] sta1;


}


// 元素互換
void swap(int* arr,int i,int j) {
	int temp = arr[i];
	arr[i] = arr[j];
	arr[j] = temp;
}

// 數組分區
int partition(int* arr, int strat, int end) {
	// 選取一個分區的-支點
	int pivot = arr[strat];
 
	// 左右指針指向
	int left = strat, right = end;
 
	while (left < right)
	{
		// 分別從左右兩邊遍歷數組
		while (arr[left] <= pivot && left < right)
			left++;
		while (arr[right] >= pivot && left < right)
			right--;
 
		// 交換左右指針的值
		swap(arr, left, right);
	}
 
	if (arr[left] < pivot)
	{
		swap(arr, strat, left);
		return left;
	}
	else if (arr[left] > pivot)
	{
		swap(arr, strat, left - 1);
		return left - 1;
	}
}
 




// 四線程
// 定義快速排序函數,遞歸實現
void quick_sort4(int* q, int l, int r) {
	// 前提條件
	if (l >= r)
		return;
 

	// 分區,返回分區下標
	int mid = partition(q, l, r);

    // 現在 拆成四個線程

 
	// 遞歸調用
	// quickSort(q, l, mid - 1); // 這里對應兩個線程
    int mid1 = partition(q, l, mid - 1);
    thread newTh1(threadForSort, q, l,mid1-1);
    thread newTh2(threadForSort, q, mid1+1,mid-1);
	// quickSort(q, mid + 1, r);// 這里也對應兩個線程
    mid1 = partition(q, mid + 1, r);
    thread newTh3(threadForSort, q, mid+1,mid1-1);
    thread newTh4(threadForSort, q, mid1+1,r);
    newTh1.join();
    newTh2.join();
    newTh3.join();
    newTh4.join();
    
 
}
 

void mysort(int *n,int l){
    quick_sort4(n,0,l-1);

}



void comprehensiveTest()
{// 進行100次測試   算平均時間  計算性能提升
    double cAllTime = 0;
    double myAllTime = 0;
    int i,j;
    int total = testLength;
    for(i=0;i<testNum;i++){
        int *num1 = getRand(total);
        int* num2 = new int[total];
        for(j=0;j<total;j++){
            num2[j] = num1[j];
        }

        auto start1 = std::chrono::high_resolution_clock::now(); // 記錄開始時間
        qsort(num1, total, sizeof(int), compare);
        auto end1 = std::chrono::high_resolution_clock::now(); // 記錄結束時間

        auto start2 = std::chrono::high_resolution_clock::now(); // 記錄開始時間
        mysort(num2 , total);
        auto end2 = std::chrono::high_resolution_clock::now(); // 記錄結束時間
        for(j=0;j<total;j++){
            if(num1[i] !=num2[i]){
                cout << "出錯了" << endl;
                break;
            }
        }
        delete[] num1;
        delete[] num2; 
        std::chrono::duration<double, std::milli> cTime = end1 - start1; // 計算執行時間
        std::chrono::duration<double, std::milli> myTime = end2 - start2; // 計算執行時間
        std::cout << "c++程序執行時間:" << cTime.count() << " 毫秒" <<  "    " << "我的程序執行時間:" << myTime.count() << " 毫秒" ;
        double gap = cTime.count()-myTime.count();
        if(gap>0){
            cout << "                 快了  "  << gap << "  " <<endl;
        }else{
            cout << "                 慢了  "  << -1*gap << "  " <<endl;
        }
        cAllTime +=cTime.count();
        myAllTime+=myTime.count();
    }
    cAllTime/=testNum;
    myAllTime/=testNum;
    cout << "平均快了   " << cAllTime-myAllTime << endl;
    cout << "提升比例   " << (cAllTime-myAllTime)/cAllTime << endl;

    


}

void compareTest(){
    int count = 7;
    int allLen[count] = {10000,50000,100000,1000000 , 5000000,8000000 , 10000000};
    // int myScore;
    // int cScore = myScore = 0;
    int i,j;
    for(i=0;i<count;i++){
        int *num1 = getRand(allLen[i]);
        int* num2 = new int[allLen[i]];
        for(j=0;j<allLen[i];j++){
            num2[j] = num1[j];
        }

        auto start1 = std::chrono::high_resolution_clock::now(); // 記錄開始時間
        qsort(num1, allLen[i], sizeof(int), compare);
        auto end1 = std::chrono::high_resolution_clock::now(); // 記錄結束時間

        auto start2 = std::chrono::high_resolution_clock::now(); // 記錄開始時間
        mysort(num2 , allLen[i]);
        auto end2 = std::chrono::high_resolution_clock::now(); // 記錄結束時間
        for(j=0;j<allLen[i];j++){
            if(num1[i] !=num2[i]){
                cout << "出錯了" << endl;
                break;
            }
        }
        delete[] num1;
        delete[] num2; 
        std::chrono::duration<double, std::milli> cTime = end1 - start1; // 計算執行時間
        std::chrono::duration<double, std::milli> myTime = end2 - start2; // 計算執行時間
        std::cout << "c++程序執行時間:" << cTime.count() << " 毫秒" <<  "    " << "我的程序執行時間:" << myTime.count() << " 毫秒" ;
        double gap = cTime.count()-myTime.count();
        if(gap>0){
            cout << "                 快了  "  << gap << "  " <<endl;
        }else{
            cout << "                 慢了  "  << -1*gap << "  " <<endl;
        }
    }

}

int main()
{
    srand(time(0));

    // compareTest();
    comprehensiveTest();


    return 0;
}

性能比較輸出:

PS E:\c++_project\test\算法實驗1\output> & .\'solution4.exe'
c++程序執行時間:79.005 毫秒    我的程序執行時間:45.277 毫秒                 快了  33.728
c++程序執行時間:80.556 毫秒    我的程序執行時間:42.003 毫秒                 快了  38.553
c++程序執行時間:79.536 毫秒    我的程序執行時間:39.296 毫秒                 快了  40.24
c++程序執行時間:77.783 毫秒    我的程序執行時間:41.132 毫秒                 快了  36.651
c++程序執行時間:80.678 毫秒    我的程序執行時間:41.417 毫秒                 快了  39.261
c++程序執行時間:79.392 毫秒    我的程序執行時間:46.027 毫秒                 快了  33.365
c++程序執行時間:77.973 毫秒    我的程序執行時間:62.482 毫秒                 快了  15.491
c++程序執行時間:78.536 毫秒    我的程序執行時間:44.406 毫秒                 快了  34.13
c++程序執行時間:79.521 毫秒    我的程序執行時間:49.285 毫秒                 快了  30.236
c++程序執行時間:78.469 毫秒    我的程序執行時間:42.266 毫秒                 快了  36.203
c++程序執行時間:79.798 毫秒    我的程序執行時間:48.401 毫秒                 快了  31.397
c++程序執行時間:83.086 毫秒    我的程序執行時間:41.221 毫秒                 快了  41.865
c++程序執行時間:80.128 毫秒    我的程序執行時間:34.254 毫秒                 快了  45.874
c++程序執行時間:83.818 毫秒    我的程序執行時間:35.591 毫秒                 快了  48.227
c++程序執行時間:87.433 毫秒    我的程序執行時間:37.273 毫秒                 快了  50.16
平均快了   37.0254
提升比例   0.460625

solution5:

// 動態進行多線程劃分

#include <iostream>
#include <chrono>
#include<stack>//使用stack時需要的頭文件 
#include<mingw.thread.h> // 我的vscode   如果是別的編譯器直接用thread包就可以
using namespace std;
int maxLength = 1000000;// 測試數據長度
int devideSize = maxLength/100; // 開新線程標準 防止產生太多線程   數據長度大于此數時開啟新線程
int testNum = 15;// 測試次數
// volatile int maxThread

int compare(const void *a, const void *b)
{
    int *pa = (int*)a;
    int *pb = (int*)b;
    return (*pa )- (*pb);  //從小到大排序
}

int* getRand(int length)
{
    
    int* n = new int[length];
    int i;
    for(i=0;i<length;i++){
        n[i] = rand();
    }
    return n;
}


void threadForSort(int q[], int ll, int rr)
{
    // thread* all[10000];
    // int thNum = 0;
    // 消遞歸
   int ind = 0;
   int l,r;
   int* sta1 = new int[1000000]; // 也可以用stack  沒太大差別 所以暫時沒優化
   sta1[ind++] = ll;
   sta1[ind++] = rr;
   
   while(ind>0){
    r = sta1[--ind];
    l = sta1[--ind];
    

    if (l >= r) continue;
    if(r-l+1<=20){
        for (int i = l+1; i <= r; i++) {
        int key = q[i];
        int j = i - 1;
        
        while (j >= l && q[j] > key) {
            q[j + 1] = q[j];
            j--;
        }
        
        q[j + 1] = key;
        }
        continue;
    }

    int i = l - 1, j = r + 1, x =(l + r) >> 1;

    // 另一種取中
    int lll = 5;
    for (int i = l+1; i <= l+lll; i++) {
        int key = q[i];
        int j = i - 1;
        
        while (j >= l && q[j] > key) {
            q[j + 1] = q[j];
            j--;
        }
        
        q[j + 1] = key;
    }
    int te = q[l+lll];
    q[l+lll] = q[x];
    q[x] = te;
    i = l+lll-1;

    x = q[x];


    while (i < j)
    {
        do i ++ ; while (q[i] < x);
        do j -- ; while (q[j] > x);
        if (i < j){
            int rdf = q[i];
            q[i] = q[j];
            q[j] = rdf;
        }
    }
    // thread* point1 = NULL;
    // thread* point2 = NULL;
    
    if( j-l>devideSize ){
        thread newTh1(threadForSort, q, l,j);
        // all[thNum++] = &newTh1;
        // point1 = &newTh1;
        newTh1.join();
    
    }else{
        sta1[ind++] =l ;
        sta1[ind++] =j ;
    }
    if( r-j>devideSize ){
        thread newTh1(threadForSort, q, l,j);
        // point2 = &newTh1;
        newTh1.join();
        
        // all[thNum++] = &newTh1;
    }else{
        sta1[ind++] =j+1 ;
        sta1[ind++] =r ;
    }
    

   }
   delete[] sta1;


}


// 元素互換
void swap(int* arr,int i,int j) {
	int temp = arr[i];
	arr[i] = arr[j];
	arr[j] = temp;
}

void mysort(int *n,int l){
    threadForSort(n,0,l-1);
}



void comprehensiveTest()
{// 進行100次測試   算平均時間  計算性能提升
    double cAllTime = 0;
    double myAllTime = 0;
    int i,j;
    int total = maxLength;
    for(i=0;i<testNum;i++){
        int *num1 = getRand(total);
        int* num2 = new int[total];
        for(j=0;j<total;j++){
            num2[j] = num1[j];
        }

        auto start1 = std::chrono::high_resolution_clock::now(); // 記錄開始時間
        qsort(num1, total, sizeof(int), compare);
        auto end1 = std::chrono::high_resolution_clock::now(); // 記錄結束時間

        auto start2 = std::chrono::high_resolution_clock::now(); // 記錄開始時間
        mysort(num2 , total);
        auto end2 = std::chrono::high_resolution_clock::now(); // 記錄結束時間
        for(j=0;j<total;j++){
            if(num1[i] !=num2[i]){
                cout << "出錯了" << endl;
                break;
            }
        }
        delete[] num1;
        delete[] num2; 
        std::chrono::duration<double, std::milli> cTime = end1 - start1; // 計算執行時間
        std::chrono::duration<double, std::milli> myTime = end2 - start2; // 計算執行時間
        std::cout << "c++程序執行時間:" << cTime.count() << " 毫秒" <<  "    " << "我的程序執行時間:" << myTime.count() << " 毫秒" ;
        double gap = cTime.count()-myTime.count();
        if(gap>0){
            cout << "                 快了  "  << gap << "  " <<endl;
        }else{
            cout << "                 慢了  "  << -1*gap << "  " <<endl;
        }
        cAllTime +=cTime.count();
        myAllTime+=myTime.count();
    }
    cAllTime/=testNum;
    myAllTime/=testNum;
    cout << "平均快了   " << cAllTime-myAllTime << endl;
    cout << "提升比例   " << (cAllTime-myAllTime)/cAllTime << endl;

    


}

void compareTest(){
    int count = 7;
    int allLen[count] = {10000,50000,100000,1000000 , 5000000,8000000 , 10000000};
    // int myScore;
    // int cScore = myScore = 0;
    int i,j;
    for(i=0;i<count;i++){
        int *num1 = getRand(allLen[i]);
        int* num2 = new int[allLen[i]];
        for(j=0;j<allLen[i];j++){
            num2[j] = num1[j];
        }

        auto start1 = std::chrono::high_resolution_clock::now(); // 記錄開始時間
        qsort(num1, allLen[i], sizeof(int), compare);
        auto end1 = std::chrono::high_resolution_clock::now(); // 記錄結束時間

        auto start2 = std::chrono::high_resolution_clock::now(); // 記錄開始時間
        mysort(num2 , allLen[i]);
        auto end2 = std::chrono::high_resolution_clock::now(); // 記錄結束時間
        for(j=0;j<allLen[i];j++){
            if(num1[i] !=num2[i]){
                cout << "出錯了" << endl;
                break;
            }
        }
        delete[] num1;
        delete[] num2; 
        std::chrono::duration<double, std::milli> cTime = end1 - start1; // 計算執行時間
        std::chrono::duration<double, std::milli> myTime = end2 - start2; // 計算執行時間
        std::cout << "c++程序執行時間:" << cTime.count() << " 毫秒" <<  "    " << "我的程序執行時間:" << myTime.count() << " 毫秒" ;
        double gap = cTime.count()-myTime.count();
        if(gap>0){
            cout << "                 快了  "  << gap << "  " <<endl;
        }else{
            cout << "                 慢了  "  << -1*gap << "  " <<endl;
        }
    }

}

int main()
{
    srand(time(0));

    // compareTest();
    comprehensiveTest();


    return 0;
}

性能比較輸出:

PS E:\c++_project\test\算法實驗1\output> cd 'e:\c++_project\test\算法實驗1\output'
PS E:\c++_project\test\算法實驗1\output> & .\'solution5.exe'
c++程序執行時間:79.938 毫秒    我的程序執行時間:30.877 毫秒                 快了  49.061
c++程序執行時間:77.712 毫秒    我的程序執行時間:34.406 毫秒                 快了  43.306
c++程序執行時間:80.698 毫秒    我的程序執行時間:28.973 毫秒                 快了  51.725
c++程序執行時間:77.65 毫秒    我的程序執行時間:30.457 
毫秒                 快了  47.193
c++程序執行時間:78.662 毫秒    我的程序執行時間:31.154 毫秒                 快了  47.508
c++程序執行時間:79.299 毫秒    我的程序執行時間:22.993 毫秒                 快了  56.306
c++程序執行時間:79.999 毫秒    我的程序執行時間:26.001 毫秒                 快了  53.998
c++程序執行時間:78.309 毫秒    我的程序執行時間:24.786 毫秒                 快了  53.523
c++程序執行時間:79.532 毫秒    我的程序執行時間:31.678 毫秒                 快了  47.854
c++程序執行時間:79.489 毫秒    我的程序執行時間:22.993 毫秒                 快了  56.496
c++程序執行時間:79.261 毫秒    我的程序執行時間:20.153 毫秒                 快了  59.108
c++程序執行時間:79.368 毫秒    我的程序執行時間:26.855 毫秒                 快了  52.513
c++程序執行時間:77.946 毫秒    我的程序執行時間:31.01 
毫秒                 快了  46.936
c++程序執行時間:79 毫秒    我的程序執行時間:26.999 毫
秒                 快了  52.001
c++程序執行時間:78.758 毫秒    我的程序執行時間:19 毫
秒                 快了  59.758
平均快了   51.8191
提升比例   0.655594

總結

以上是生活随笔為你收集整理的快排优化的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

欧美日本日韩aⅴ在线视频 插插插色综合 | 天天弄天天操 | 亚洲 欧美 另类人妖 | 激情在线免费视频 | 色综合天天色 | 国产成人三级三级三级97 | 成 人 黄 色 视频 免费观看 | 久久综合之合合综合久久 | 日本久久久久久久久久久 | 国产日韩欧美在线观看视频 | 久草在线视频首页 | 久久久黄色 | 日韩欧美国产视频 | 久久精品一区二区三 | av一级一片 | 中文字幕成人av | 97人人添人澡人人爽超碰动图 | 国产成视频在线观看 | 91亚洲视频在线观看 | 欧美午夜精品久久久久久浪潮 | 波多野结衣一区二区三区中文字幕 | 免费看三级黄色片 | 激情综合五月 | 日韩av在线影视 | 日韩精品中文字幕久久臀 | 中文字幕在线中文 | 免费在线观看av片 | 在线观看精品视频 | 一本一本久久a久久精品综合妖精 | 一区免费在线 | 韩国视频一区二区三区 | 亚洲三级在线免费观看 | 精品欧美乱码久久久久久 | 99r在线视频 | 亚洲经典视频 | 五月激情天 | 国模视频一区二区三区 | 在线国产高清 | 麻豆国产在线视频 | 天天草天天干天天 | 欧美伦理电影一区二区 | www99久久 | 中文字幕在线观看播放 | 久久黄色小说视频 | 久久精品精品电影网 | 欧美日本不卡 | 黄色一级大片在线免费看产 | 久久久精品 | 精品91| 久久99精品久久久久久清纯直播 | 国产69精品久久久久久 | 黄色的视频网站 | 色婷婷六月天 | 伊人永久在线 | 日韩视频在线播放 | av在线播放快速免费阴 | 成人欧美一区二区三区黑人麻豆 | 亚洲一区尤物 | 国产精品一区二区三区在线看 | 精品福利视频在线观看 | 97在线播放| 亚洲精品视频在线观看免费 | 在线观看岛国 | 在线观看一级视频 | 久久精品一二区 | 亚洲人成人99网站 | 中文字幕久久精品一区 | 久草在线欧美 | 欧美精品免费在线 | 四虎欧美 | 国内精品一区二区 | 日韩在线视频国产 | 99视频免费看 | 国产成人亚洲在线电影 | 国产明星视频三级a三级点| 字幕网在线观看 | 精品一区 精品二区 | 中文字幕一区二区三区乱码不卡 | 欧美性生活免费 | 日日爽日日操 | 亚洲乱码国产乱码精品天美传媒 | 亚洲91视频 | 欧美激情第八页 | 国产精品不卡 | 91看片在线免费观看 | 在线成人观看 | 国产精品女人久久久 | 日韩在线观看免费 | av中文字幕在线免费观看 | 国产电影一区二区三区四区 | 亚洲五月激情 | 丝袜美腿在线 | 欧美日韩国产精品一区二区三区 | 美女黄频在线观看 | 狠狠色丁香婷婷 | 在线欧美日韩 | 色综合在 | 超碰在线人人草 | 69国产精品视频免费观看 | 亚洲精品久久久久999中文字幕 | 日韩二区三区 | 久久最新视频 | 久久观看最新视频 | 欧美少妇影院 | 久久久久久久久久久影视 | 女人18毛片a级毛片一区二区 | av资源免费在线观看 | 成人免费在线观看电影 | 亚洲欧美日韩一二三区 | 欧美在线观看禁18 | 99精品免费久久久久久久久 | 精品国产一区二区三区四区vr | 国产日韩精品久久 | 欧美一级免费 | 91精品国自产拍天天拍 | 免费一级片在线 | 日本精品中文字幕在线观看 | 日韩网站免费观看 | 香蕉影院在线 | 国产精品a久久久久 | 亚洲国产精品成人va在线观看 | 日韩在线免费看 | 日韩色中色 | 成人亚洲综合 | 欧美一区二区三区特黄 | 91精品国产一区二区三区 | 少妇自拍av | 欧美性生活一级片 | 中文字幕a∨在线乱码免费看 | 国产精品第54页 | 精品久久精品 | 久久免费的视频 | 日韩欧美高清免费 | 天天操天天怕 | 九九在线国产视频 | 天天综合色 | 午夜视频在线观看一区二区三区 | 亚洲成人av一区 | 免费网站在线观看人 | 成年人免费看片网站 | 午夜视频二区 | 中文字幕成人网 | 超碰电影在线观看 | 日韩美一区二区三区 | 天天摸夜夜添 | 国产欧美精品在线观看 | 天天天操天天天干 | 99精品热视频只有精品10 | 国产美女视频网站 | 欧美成人999 | 九九视频免费在线观看 | 精品久久国产一区 | 国产福利在线 | 亚洲电影影音先锋 | 精品国产一区二区三区免费 | 99视频久| 免费91麻豆精品国产自产在线观看 | 色爱区综合激月婷婷 | 中文字幕丰满人伦在线 | 精品成人久久 | 在线观看av大片 | 五月婷婷一区 | 在线成人国产 | 国内精品久久久久影院一蜜桃 | 999久久 | 亚洲欧洲精品视频 | 久久乱码卡一卡2卡三卡四 五月婷婷久 | 黄色av免费电影 | 婷婷www| 国产高清在线免费视频 | 国产一级一片免费播放放a 一区二区三区国产欧美 | 色婷婷综合久久久 | 天堂av在线网 | 99久久精品国产亚洲 | 丰满少妇一级 | 天天干,夜夜爽 | 日韩精品视频久久 | 探花系列在线 | 久久精品免费电影 | 天堂av在线网址 | 超级碰碰碰视频 | 国产视频美女 | 香蕉看片 | 91x色| 国产不卡高清 | 欧美日韩免费视频 | 99久久国产免费,99久久国产免费大片 | 国产高清av | 国内精品久久天天躁人人爽 | 精品人人爽 | 日精品| 日韩精品视频在线免费观看 | 午夜精品久久久 | 久久精品爱视频 | 99在线精品视频在线观看 | 国产只有精品 | 啪啪肉肉污av国网站 | 精品国产伦一区二区三区观看体验 | 五月激情丁香婷婷 | 免费av片在线| 婷婷色五 | 夜色资源站国产www在线视频 | 99久久99久国产黄毛片 | 午夜三级在线 | www日韩视频 | 久久 国产一区 | 亚洲一级二级 | 免费成人在线网站 | 久久国产精品二国产精品中国洋人 | 久青草视频在线观看 | 婷婷网站天天婷婷网站 | 园产精品久久久久久久7电影 | 天天干天天操天天搞 | 色婷婷丁香| 手机av永久免费 | 有码中文在线 | 久久国产精品一区二区三区 | 精品一区二区影视 | 伊人婷婷在线 | 亚洲理论在线观看 | 成人免费在线观看av | 久草在线观看 | www.国产在线视频 | 99国产成+人+综合+亚洲 欧美 | 日本在线观看中文字幕无线观看 | 亚洲激精日韩激精欧美精品 | 亚洲精品视频在线播放 | 91麻豆视频 | 亚洲一区二区黄色 | 在线 国产 亚洲 欧美 | 国产精品久久久久久高潮 | 粉嫩aⅴ一区二区三区 | 国产中文字幕在线免费观看 | 性色av香蕉一区二区 | 久久激情视频免费观看 | 日本公妇在线观看高清 | 五月婷婷香蕉 | 久久日韩精品 | 欧美国产日韩久久 | 免费麻豆 | 久久官网 | 欧美性高跟鞋xxxxhd | 日韩一区视频在线 | 911免费视频 | 久久久久观看 | 久久免费试看 | 精品不卡av| 国产精品福利小视频 | 国产成人一区二区在线观看 | 亚洲免费在线看 | 国产专区视频 | 亚洲精品视频在线观看网站 | 日韩在线免费电影 | 国际精品久久久久 | 日韩在线视频线视频免费网站 | 看污网站 | 最近免费在线观看 | 欧美成年网站 | 香蕉久草 | 精品国产免费久久 | 国产免码va在线观看免费 | 99精品美女 | 日日干夜夜草 | 日韩欧美在线影院 | 黄色的视频网站 | 91一区啪爱嗯打偷拍欧美 | 亚洲日本成人 | 久久99久久精品国产 | 91久久久国产精品 | 国产五月婷婷 | 中文字幕在线免费看线人 | av看片在线 | 日韩成人精品一区二区 | 狠狠色丁香婷婷综合久小说久 | 精品在线二区 | 人人干狠狠操 | 免费在线观看日韩欧美 | av电影久久 | 91九色国产蝌蚪 | 毛片激情永久免费 | 国产无套一区二区三区久久 | 中文字幕免费高清av | 久久久国产精品成人免费 | 一区二区视频播放 | 免费观看黄 | 国产91精品一区二区麻豆亚洲 | 99热国内精品 | 男女拍拍免费视频 | 制服丝袜天堂 | 99久久精品免费看国产 | 午夜三级在线 | 人人玩人人添人人澡97 | 人人讲下载 | 日韩精品免费在线视频 | 四虎国产精品成人免费4hu | 深爱综合网 | 欧美性粗大hdvideo | 久久婷亚洲五月一区天天躁 | 在线视频 区 | 国产v在线播放 | 在线综合 亚洲 欧美在线视频 | 久久经典国产 | 国产精品久久久久毛片大屁完整版 | 麻豆系列在线观看 | 欧美性超爽 | 嫩嫩影院理论片 | 免费三级a | 亚洲欧洲精品一区二区精品久久久 | 日本在线成人 | 免费99| 欧美激情精品久久久久久 | 国色天香永久免费 | 国产午夜精品视频 | 天天色图 | 国产九色在线播放九色 | 国产操在线 | 处女av在线 | 欧美日本不卡高清 | 一区二区三区中文字幕在线观看 | 精品女同一区二区三区在线观看 | 久久精品久久久久久久 | 中文字幕色在线视频 | 久久黄色片 | 韩国av一区二区三区在线观看 | 久久久精品一区二区三区 | 久久久久久免费网 | 久久久久电影网站 | 久久久久中文 | 91人人人 | 黄色国产高清 | 在线免费视频一区 | 亚洲禁18久人片 | 日韩一区视频在线 | 最新久久免费视频 | 亚洲精品免费在线观看 | 免费久久99精品国产婷婷六月 | 天天综合操 | 亚洲一二视频 | 欧美美女视频在线观看 | 亚洲精品久久久蜜桃 | 西西444www高清大胆 | 亚洲精品影院在线观看 | 狠狠久久综合 | 91电影福利| 精品一区三区 | 国产三级久久久 | 最新超碰 | 国产精品色 | 亚洲国产天堂av | 蜜臀久久99精品久久久无需会员 | 国产成人一区二区三区免费看 | 久久艹艹| 免费aa大片 | 中文在线亚洲 | 中文在线中文a | 日韩字幕在线 | 国产福利在线免费 | 国产理论一区二区三区 | 久久国产亚洲精品 | 欧美日韩xxxxx | 日韩一区二区三区在线看 | 亚洲欧洲中文日韩久久av乱码 | 激情久久一区二区三区 | 中文字幕在线一区二区三区 | 国产亚洲综合在线 | 色偷偷88888欧美精品久久久 | 久久激情小视频 | 99久久免费看 | 亚洲美女免费精品视频在线观看 | 97精品国产一二三产区 | 精品久久五月天 | 欧美激情第28页 | 香蕉久久久久 | 午夜精品久久久久久久99婷婷 | 四虎国产精品成人免费4hu | 欧美视频xxx| av黄色大片| 日韩免费电影网 | 国产精品高潮呻吟久久av无 | 国产视频欧美视频 | 久久在线影院 | 日韩在线观看一区二区三区 | 天天艹日日干 | 久草视频99| 99r在线播放 | 探花在线观看 | aa级黄色大片 | 国产在线精品一区二区 | 精品国产精品国产偷麻豆 | 欧美一级性生活片 | 在线观看视频你懂的 | 成人av片免费观看app下载 | 色综合 久久精品 | 精品伊人久久久 | 韩国av三级 | 五月天综合色激情 | 国产一区在线免费观看 | 在线看av的网址 | 五月婷婷综| 久草资源免费 | 人人澡人人爽 | 18久久久久| 国产精品久久久久久久久毛片 | 狠狠精品 | 日韩视频一二三区 | 国产视频在线播放 | 99热这里只有精品久久 | 免费亚洲婷婷 | 夜夜骑天天操 | 2019久久精品| 91探花国产综合在线精品 | 久久高清毛片 | 六月色| 成年人三级网站 | 亚洲精品乱码久久久久久 | 亚洲精品国产精品久久99 | 九九在线视频免费观看 | 波多在线视频 | 国产成人精品久久久久蜜臀 | 日韩日韩日韩日韩 | 美女久久久 | 韩国在线一区二区 | 人人dvd| 麻豆国产网站 | 五月花激情 | 激情影院在线 | 精品久久久久国产免费第一页 | 96av麻豆蜜桃一区二区 | 国产视频高清 | 成人97视频一区二区 | 国产精品毛片一区视频播 | 日韩三级在线 | 96亚洲精品久久 | 国产视频欧美视频 | 天天爱天天草 | 成人羞羞视频在线观看免费 | 成年人视频在线免费播放 | 天天舔夜夜操 | 女人18毛片a级毛片一区二区 | 黄色综合| 81精品国产乱码久久久久久 | 99视频精品 | 日韩av影视在线 | 国产精品网红直播 | 欧美日韩国产综合一区二区 | 一本一道久久a久久精品蜜桃 | 成人在线观看免费视频 | 久久精品国产第一区二区三区 | 中文字幕人成不卡一区 | 国产成人精品久久二区二区 | 伊人影院av | 999久久国精品免费观看网站 | 又黄又爽又湿又无遮挡的在线视频 | 一级成人在线 | 国产日产欧美在线观看 | 国产精品视频在线观看 | 射久久 | 国产成人精品一区二 | 日韩精品视频在线观看免费 | 在线看黄网站 | 在线岛国av | 亚洲,播放 | 久久精品视频观看 | 精品一二三四五区 | 久久精品婷婷 | 国产精品久久久久久久久久久久午 | 97超碰在线免费观看 | 在线亚洲天堂网 | 一区二区精 | 中文字幕精品一区久久久久 | 日韩欧美高清在线 | 成人久久精品视频 | 激情丁香综合五月 | 久久久91精品国产一区二区精品 | 天堂av一区二区 | 免费在线观看国产精品 | 狠狠操狠狠干天天操 | 91av在线国产| 麻豆久久一区 | 亚洲色图美腿丝袜 | 91精品1区 | 久久99国产精品自在自在app | 91免费观看 | 91在线麻豆 | 久久这里只有精品久久 | 久久99在线观看 | 91一区啪爱嗯打偷拍欧美 | 国产精品久久精品国产 | 日韩av视屏在线观看 | 91福利区一区二区三区 | 色婷婷88av视频一二三区 | 最近乱久中文字幕 | 亚洲日韩精品欧美一区二区 | 欧亚日韩精品一区二区在线 | 激情欧美一区二区免费视频 | 色综合天天色 | 99久久精品免费看国产四区 | 91社区国产高清 | 911精品美国片911久久久 | 国产高清视频 | 欧美精品九九99久久 | 久久a v视频 | 色噜噜狠狠狠狠色综合 | 在线视频精品 | 欧美精品在线免费 | 国产精品入口麻豆www | 日韩欧美视频一区二区三区 | 日本丰满少妇免费一区 | 国产中文伊人 | 国产精品久久久久久久午夜片 | 色欧美日韩 | 精品字幕 | 国产一区二区三区高清播放 | 精品国产资源 | 亚洲免费成人av电影 | 欧美日韩国产页 | 日韩视频一区二区在线 | 97av在线视频免费播放 | 欧美性生爱 | 免费av小说 | 久久久久免费精品 | 字幕网在线观看 | av福利超碰网站 | 国产中文在线字幕 | 四虎www com | 在线播放国产一区二区三区 | 欧洲精品视频一区 | 六月激情婷婷 | 色九九视频 | 亚洲久草在线视频 | 色狠狠综合| 欧美日韩二区在线 | 亚洲高清免费在线 | 韩国视频一区二区三区 | 国产一区二区在线免费播放 | 国产又粗又猛又黄又爽的视频 | 91精品中文字幕 | 午夜国产福利视频 | 超碰人人国产 | av在线网站观看 | www国产精品com | 日韩精品一区二区三区高清免费 | 九色视频自拍 | 日本夜夜草视频网站 | 日本黄区免费视频观看 | 国产精品久久久久aaaa九色 | 日韩美一区二区三区 | 国产精品久久久久久久久久妇女 | 精品一区二区在线看 | 在线a人片免费观看视频 | 欧美激情精品久久久久久变态 | 国产特黄色片 | 久久午夜网| 国产系列 在线观看 | 五月丁香 | 一区二区电影在线观看 | 99福利片| 激情伊人 | 日韩在线观看的 | 成人在线一区二区三区 | 成人免费观看电影 | 免费av观看网站 | 激情欧美一区二区三区免费看 | 日本精品二区 | 久久久久国产视频 | 免费一级毛毛片 | 国产精品毛片久久久久久久久久99999999 | 天天插狠狠插 | 天天干天天草天天爽 | 天天亚洲 | 国产视频在线一区二区 | 成人一级免费电影 | 亚洲 欧美日韩 国产 中文 | 日韩在线观看不卡 | 亚洲精品视频网站在线观看 | av免费观看网址 | 深夜免费小视频 | 91九色视频在线播放 | 亚洲国产精品久久久久婷婷884 | 日三级在线 | 亚洲激情 欧美激情 | 九九九电影免费看 | a天堂一码二码专区 | 欧美精品国产精品 | 麻豆va一区二区三区久久浪 | 国偷自产视频一区二区久 | 中文字幕在线观看视频一区二区三区 | 天天伊人网 | 国产精品12 | 久久第四色 | 中文字幕永久 | 六月丁香激情综合色啪小说 | 欧美不卡视频在线 | 好看av在线| 色五丁香| 亚洲欧美日本A∨在线观看 青青河边草观看完整版高清 | 欧美极品在线播放 | 欧美综合在线视频 | 日韩网站免费观看 | 成片免费观看视频999 | 亚洲视频在线观看免费 | 干干夜夜 | 中文字幕亚洲高清 | 2021国产视频 | 久免费视频 | 91精品在线视频观看 | 香蕉视频在线免费看 | 精品一区二区在线看 | 亚洲欧洲精品一区二区 | 五月婷婷黄色 | 精品久久久久久久久久久久 | 夜夜看av | 久久综合久久88 | 日韩av线观看| 日韩国产精品一区 | 精品免费一区二区三区 | 亚洲片在线资源 | 久久夜色精品亚洲噜噜国4 午夜视频在线观看欧美 | 国产成人精品一区二区三区网站观看 | 色姑娘综合网 | 97精品国产91久久久久久 | 日韩欧美电影 | 在线国产一区二区 | 丁香视频全集免费观看 | 亚洲激情五月 | 国产日韩欧美在线一区 | 欧美色图狠狠干 | 91成年人网站 | 一区二区三区免费 | 一级黄色片在线播放 | 久久国产精品99国产 | 国产精品午夜免费福利视频 | 亚洲精品99久久久久中文字幕 | 亚洲精品在线电影 | 亚洲欧洲日韩在线观看 | 国产视频 亚洲精品 | 黄色三级网站 | 在线精品视频免费观看 | 国产精品一区二区在线免费观看 | 美女免费电影 | 欧美一级免费高清 | 中文字幕高清在线播放 | 欧美巨乳网 | 在线观av| 国产一级一片免费播放放a 一区二区三区国产欧美 | 美女免费视频网站 | 91福利免费 | 欧美午夜性 | 久久久久女教师免费一区 | 这里有精品在线视频 | 国产免费视频在线 | 少妇搡bbbb搡bbb搡aa | 一区二区三区四区精品视频 | 9幺看片 | 亚洲v欧美v国产v在线观看 | 黄色国产成人 | 黄色av影院 | 欧美日韩在线播放 | 黄色毛片电影 | 国产色婷婷精品综合在线手机播放 | 在线日韩中文 | 天天天干夜夜夜操 | 天天天综合网 | 国产精品福利无圣光在线一区 | 久久这里只有精品9 | 国产麻豆剧传媒免费观看 | 2022久久国产露脸精品国产 | 五月婷av| 久久久鲁| av在线网站大全 | 亚洲国产欧美一区二区三区丁香婷 | 天天操天天爱天天爽 | 日韩三级一区 | 国产99久久久国产精品免费看 | 三级在线视频播放 | 婷婷成人亚洲综合国产xv88 | 国内精品视频免费 | av中文字幕亚洲 | 在线观看的黄色 | 久久久午夜精品理论片中文字幕 | 五月天久久狠狠 | 亚洲一区二区三区毛片 | 亚洲伊人第一页 | 久久久福利| 亚洲国产成人久久综合 | 国产精品一区在线播放 | 999成人 | 亚洲天堂网视频 | 欧美激情视频久久 | 激情丁香| 人人超碰97 | 免费人做人爱www的视 | www日韩在线观看 | 国产精品一区二区三区观看 | 国产精品av在线免费观看 | 欧美日一级片 | 亚洲欧美日韩在线一区二区 | 日韩电影在线观看一区二区 | 久草视频在线新免费 | 日韩欧美精品在线观看视频 | 一区二区三区四区在线免费观看 | 午夜精品一区二区三区免费 | 欧美日本在线观看视频 | aaa毛片视频 | 91av视频免费观看 | 国产精品国产亚洲精品看不卡15 | 麻豆视频在线播放 | 国产精品一区二区在线观看免费 | 不卡的一区二区三区 | 国产精品一区免费在线观看 | av短片在线观看 | 91成人精品国产刺激国语对白 | 亚洲综合小说 | 国产精品日韩欧美 | 国产精品国产三级国产aⅴ9色 | 六月久久婷婷 | 国产精品99久久久久久宅男 | 91网址在线看 | 亚洲精品美女久久17c | 久精品在线观看 | 在线观看中文字幕dvd播放 | 91xav| 日本最新一区二区三区 | 亚洲一区日韩精品 | 天天曰 | 菠萝菠萝蜜在线播放 | 久久综合五月婷婷 | 久久伊人精品天天 | 国产午夜精品一区二区三区嫩草 | 久草在线观 | 91麻豆精品国产91久久久无限制版 | 中国精品一区二区 | 在线性视频日韩欧美 | 欧美另类老妇 | 伊人久久在线观看 | 国产又粗又硬又爽的视频 | 91成人免费电影 | av成人在线网站 | av免费看网站 | 久久精品99国产精品酒店日本 | 国产福利一区二区三区在线观看 | 久久精品电影院 | 99在线视频网站 | 亚洲婷婷在线视频 | 欧美a性| av高清网站在线观看 | 国产免码va在线观看免费 | 美女视频一区 | 天天干天天搞天天射 | 亚洲 欧洲 国产 日本 综合 | 免费黄色在线播放 | 欧美二区视频 | 国产乱对白刺激视频不卡 | 二区视频在线观看 | 九九视频这里只有精品 | 精品国产一区二区三区久久久蜜臀 | 国产高清成人 | 国产精品 视频 | 国产一二三精品 | 日本精品一区二区在线观看 | 国产午夜三级 | 涩涩爱夜夜爱 | 成人黄在线 | 色婷婷在线观看视频 | 日韩欧美黄色网址 | 狠狠干在线播放 | 在线午夜 | 中文字幕日本在线 | 久久久999免费视频 日韩网站在线 | 精品国产一区二区三区四区在线观看 | 国产精品 中文在线 | 五月婷婷色综合 | 久久久久国产成人免费精品免费 | 91精品国产乱码在线观看 | 狠狠网| 日韩欧美视频免费在线观看 | 国产高清视频色在线www | 99久热在线精品视频 | 九九免费在线观看视频 | 色中射| 国产成人亚洲在线观看 | 一本色道久久综合亚洲二区三区 | 97香蕉久久超级碰碰高清版 | 免费人成网 | 欧美日韩国产一区二区在线观看 | 日韩成人在线一区二区 | 黄色成人影视 | 亚洲天堂免费视频 | 五月亚洲综合 | 最新av在线网站 | 亚洲精品一区二区三区四区高清 | 国产免费xvideos视频入口 | 国产精品久久久久久久久岛 | 91漂亮少妇露脸在线播放 | 99久久精品国产毛片 | 久久精品国产精品 | 久久久久二区 | 亚洲在线综合 | 国产一区二区精品久久91 | 最近更新好看的中文字幕 | 欧美日一级片 | 激情五月婷婷综合 | 五月亚洲综合 | 日韩大片免费在线观看 | 黄色软件大全网站 | 国产一级黄色免费看 | 黄色片免费在线 | 日韩黄色免费 | 91成版人在线观看入口 | 精品国产区 | 99国产情侣在线播放 | 摸bbb搡bbb搡bbbb | 久久久午夜精品福利内容 | 97超碰色| 日韩欧美在线高清 | av在线播放中文字幕 | 丝袜网站在线观看 | 成年人看片网站 | 日韩成人av在线 | 中文字幕av在线免费 | 黄色a级片在线观看 | 伊人影院99 | 国内精品久久久久久久影视麻豆 | 久久久久www | 国产视频在线观看一区 | 日韩欧美一区二区三区黑寡妇 | 91精品网站在线观看 | 最近日本中文字幕 | 天天射天天干天天插 | 国产成人精品一区二区 | 亚洲国产福利视频 | 日日操操 | 夜夜干夜夜 | 精品国产欧美一区二区三区不卡 | 亚洲精品视频在线免费 | 不卡中文字幕av | 亚洲精品美女久久久久 | 色视频在线免费观看 | 人人人爽| 日韩欧美国产成人 | 久久精品www人人爽人人 | 久久免费看 | 精品国产免费观看 | 国产精品涩涩屋www在线观看 | 国产999精品视频 | 久久综合日 | 国产精品97| 九九久久久久久久久激情 | 麻豆传媒视频观看 | 97综合网 | 精品视频在线免费 | 成片免费观看视频 | 亚洲aⅴ在线观看 | 免费看成年人 | 欧美另类交人妖 | 99精品视频在线观看视频 | 亚洲国产高清在线观看视频 | 欧美韩国日本在线 | 午夜精品视频一区 | 国产91在线观看 | 久久精品网| 精品美女在线观看 | 亚洲欧美一区二区三区孕妇写真 | 97色在线观看 | 国产精品久久久久毛片大屁完整版 | 国产精品99久久久久人中文网介绍 | 成年人在线看片 | 久久久96 | 亚洲欧美日韩国产一区二区三区 | 看毛片网站 | 日韩一区二区三区高清免费看看 | 人人澡人人爱 | 天天爱天天操 | 国产黄色一级大片 | 成人小视频免费在线观看 | 在线三级av | 中文字幕 国产视频 | 亚洲va男人天堂 | 四虎影视av| 国产黄色精品在线 | 一区二区欧美激情 | 全久久久久久久久久久电影 | 国产在线视频在线观看 | 99这里只有精品视频 | 九草视频在线 | a级国产乱理伦片在线播放 久久久久国产精品一区 | 亚洲桃花综合 | 婷婷丁香在线 | 免费色网| 黄色一区三区 | 超碰97在线资源 | 麻豆国产精品永久免费视频 | 久久综合中文色婷婷 | 黄色影院在线免费观看 | 探花视频在线版播放免费观看 | 首页国产精品 | av激情五月 | 日本中文在线播放 | 大型av综合网站 | 国内久久精品视频 | 久久久久久久久久免费 | 夜夜操狠狠干 | 观看免费av | 亚洲天堂精品视频 | 911精品美国片911久久久 | 成人久久久电影 | 午夜视频在线观看一区 | 亚洲国产精选 | 精品国产成人 | 国产69久久 | 欧美少妇bbwhd | 亚洲高清不卡av | 欧美性爽爽 | 69久久夜色精品国产69 | 国产精品美女久久久久久免费 | 国内一级片在线观看 | 久久公开视频 | av丝袜在线| 国产福利在线 | 色综合久久五月 | 日本最新中文字幕 | av不卡免费看 | 人人插人人澡 | 久久久黄色免费网站 | 久久精品一二三区 | 91人人澡| 久久综合爱 | 久久久伊人网 | wwxxxx日本| 欧美ⅹxxxxxx| 国产一区二区网址 | 青青草国产精品 | 欧美综合在线视频 | 亚洲视频在线看 | 激情综合网五月激情 | 国产热re99久久6国产精品 | 99色精品视频 | 黄色大片视频网站 | 国产精品久久久久久久久久久久久久 | 国产精品久久久久久久久久免费 | 国产电影黄色av | 人人爽人人爱 | 亚洲精品乱码久久久久久按摩 | 亚洲欧美视屏 | 成人性生爱a∨ | 波多野结衣亚洲一区二区 | 色婷婷丁香 | 亚洲欧美日韩中文在线 | 91最新在线观看 | 麻豆视频免费版 | 九九在线播放 | 992tv在线观看 | 国产精品影音先锋 | 精品黄色片 | 国产成人一区二区三区久久精品 | 999久久| 在线免费观看黄色大片 | 国产最顶级的黄色片在线免费观看 | 人人爽人人澡人人添人人人人 | 欧美极品少妇xxxx | www.com久久 | 色婷婷狠狠操 | 国产精品久久久久久久av电影 | 久久a v视频| 中文字幕av一区二区三区四区 | 91av视频免费观看 | 久久精品久久99精品久久 | 热re99久久精品国产66热 | 国产一区二区在线免费播放 | 美女免费网视频 | 日韩精品视频网站 | 日本性xxx| 91精品办公室少妇高潮对白 | 天天天综合网 | 在线观看免费91 | 亚洲精品综合在线 | 免费特级黄色片 | 手机成人在线电影 | 18+视频网站链接 | 五月婷婷综合在线视频 | 日韩精品视 | 亚洲国产中文字幕在线视频综合 | 国产精品一区二区三区观看 | 亚洲黄色免费网站 | 国产精品成人a免费观看 | 天天干天天操天天射 | 麻豆果冻剧传媒在线播放 | 91少妇精拍在线播放 | 日本女人在线观看 | 天天综合色网 | 中文字幕av网站 | 亚洲女欲精品久久久久久久18 | 97视频在线观看网址 | 日韩aa视频 | 亚洲电影院 | 日韩高清在线一区 | 99re久久精品国产 | 中午字幕在线 |