1. 程式人生 > >快速排序兩種方式實現及優化總結

快速排序兩種方式實現及優化總結

 今天看了快速排序,現在對自己的已知的方法進行總結,歡迎拍磚。

        快速排序被認為是20世紀十大演算法之一,在排序中,快速排序其實就是我們前面認為最慢的氣泡排序的升級,它們都屬於交換排序類。即快排也是通過不斷比較和移動交換來實現排序的,不過它的實現,增大了記錄的比較和移動的距離,將關鍵字較大的記錄從前面直接移動到後面,關鍵字較小的從後面直接移動到前面,從而減少了總的比較次數和移動交換次數。

        在這裡,我們假設對"6,1,2,7,9,3,4,5,10,8"這10個數進行排序。首先在這個序列中隨便找一個數作為基準數,在這裡為了方便,我們直接選取第一個數作為基準數,(在後面的優化中,會對基準數的選取做出優化),接下來需要將這個序列中所有比基準數大的數放在6的右邊,基準數小的數放在6的左邊,轉變成這樣:3  1  2 5  4  

6  9 7  10  8;接下來再對6左邊和6右邊的元素進行相同操作的遞迴。

        快排方法(一)和方法(二)在實現方式中有些差別,我們首先對於方法(一)的過程分析:

        首先分別對原始序列的兩端進行探測,先從右往左找一個比6小的數,再從左向右找一個比6大的數,(在後面會說明為什麼先要從6 的右邊向左開始找)然後進行交換,直至當左向標等於右向標,然後將其共同指向的數與這輪的基準值進行交換,交換完畢後,分別從left到i-1的序列和從i+1到right進行遞迴,直至完全排序。

        NOTE:

 在實現快排方法(一)之前,我們先對快排一中為什麼必須首先從右邊開始向左邊找做一個說明^_^

        如果我們在上述過程中,首先從左開始向右查詢比6大的值,開始的左右互換不會出現問題,但是在最後與基準值交換就會出現問題!比如我們現在已經換到了這樣的序列:6,1,2,7,9;此時若i從左向右進行查詢, i到了7的位置會停下,j從右向左進行查詢,j到了7的位置,和i相同,也會停下,這時6會與7進行交換,嘿嘿,這時7居然跑到了基準值6的右邊!導致了結果錯誤,所以開始必須從右開始向左查詢比基準值小的數。

    快排(一)實現具體如下:

#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,j,t; 
    //讀入資料 
    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]); 
    getchar();getchar(); 
    return 0; 
} 
    

下面我們來總結一下快排方法(二)的過程:

  快排方法二的總體其實和快排方法一是一樣的,只是在迴圈條件和到每一輪最後中和基準值交換的時候有些不同。快排二是首先從左向右找出大值,接著再從右向左找出較小的值,(仔細想想與前面的順序不同,接著是怎樣來處理的)。因為快排方法一中的分析,我們可以瞭解到,如果是首先從左到右進行搜尋時,會出現最後交換值的問題,為了避免交換值的問題,其中的一種思路是採用先從右向左搜尋的方式,第二種思路則是依然是先從左到右搜尋,但是在每一輪中跳出迴圈後,不是將左邊left下標指向的值與基準值進行交換,而是將右邊right下標指向的值與基準值進行交換,這樣就可以避免最後在交換時出現最後將基準值換錯的問題。

        快排(二)實現具體如下:

#include <stdio.h>
int a[101],n;//定義全域性變數,這兩個變數需要在子函式中使用 
int Patition(int a[],int p,int r)
{
	int i=p,j=r+1;
	int tt;
	int x = a[p];
	while(true){
		while(a[++i]<x&&i<r);
		while(a[--j]>x);
		if(i>=j) break;
	    tt=a[i];
	    a[i]=a[j];
	    a[j]=tt;
	}
	a[p] = a[j];
	a[j] = x;
	return j;
}
void QuickSort(int a[],int p,int r)
{
	if(p<r){
		int q = Patition(a,p,r);
		QuickSort(a,p,q-1);
		QuickSort(a,q+1,r); 
	}
}
int main(){
	int i,j,t; 
    //讀入資料 
    scanf("%d",&n); 
    for(i=1;i<=n;i++) 
      scanf("%d",&a[i]); 
    QuickSort(a,1,n); //快速排序呼叫                 
    //輸出排序後的結果 
    for(i=1;i<=n;i++) 
        printf("%d ",a[i]); 
    getchar();getchar(); 
	return 0;
}


       快排的優化

       今天天色已晚,關於快排的優化,明天再做下總結 

相關推薦

快速排序方式實現優化總結

 今天看了快速排序,現在對自己的已知的方法進行總結,歡迎拍磚。         快速排序被認為是20世紀十大演算法之一,在排序中,快速排序其實就是我們前面認為最慢的氣泡排序的升級,它們都屬於交換排序類。即快排也是通過不斷比較和移動交換來實現排序的,不過它的實現,增大了記

遞迴和迭代方式實現歸併排序(Java版)

遞迴版 package MergeSort; import Utils.SortUtils; /** * 歸併排序遞迴版 * @author liguodong */ pub

java 方式實現自定義排序

package test; //Comparable 使物件本身具有可比性,這種方式稱為元素的自然順序或預設順序 //Comparator 元素自身不具備比較性或者比較性不是所需要的,在集合初始化讓其具有比較性 (更實用) import java.util.*; //cl

方式實現sticky footer絕對底部

gin 實現 add charset 什麽是 主體 ica min direction 一、什麽是sticky footer 如果頁面內容不夠長的時候,頁腳塊粘貼在視窗底部;如果內容足夠長時,頁腳塊會被內容向下推送,我們看到的效果就如下面兩張圖這樣。這種效果基本

php 方式實現求 斐波那契數

機器 XP 方式 一個 urn 性能 耗時 exec [1] 使用遞歸方式。 //使用遞歸方式求斐波那契數 public function fb($n){ // if( $n <=2){ return 1;

詳解Nginx方式實現訪問控制

vfk 用戶 用戶輸入 bfd pcre 效果 sys ado 密碼認證 簡介 基於用戶的訪問控制就是對網頁目錄進行認證配置,用戶輸入用戶名密碼之後才能訪問網頁基於IP的訪問控制即使可以通過配置基於ip的訪問控制,達到讓某些ip能夠訪問,限制哪些ip不能訪問的效果 實驗環境

方式實現求n的階乘

pri n) 通過 return 階乘 turn for n-1 方式 # 通過遞歸實現求n的階乘 def my_test(n): if n is 0: return 1 else: return n*my_test(n-1)

9.10 路由控制之反向解析--【別名】html和views方式實現

com 反向 技術分享 http mage login gin bsp 分享圖片 1. 在html裏反向解析 給路徑起別名,修改路徑時,不用每個地方都修改。 {% url ‘Log‘ %} : 就會去找別名為Log的URL,找到 "login/"後把"logi

leetCode 349號題目詳解 個陣列的交集 ,python3方式實現, 複雜度分別為O(n^2) 和 O(n)

給定兩個陣列,編寫一個函式來計算它們的交集。 示例 1: 輸入: nums1 = [1,2,2,1], nums2 = [2,2] 輸出: [2] 示例 2: 輸入: nums1 = [4,9,5], nums2 = [9,4,9,8,4] 輸出: [9,4] 說明: 輸出結果中的每個元素一

java實現二分查詢演算法,方式實現,非遞迴和遞迴

java實現二分查詢演算法 1、概念 2、前提 3、思想 4、過程 4、複雜度 5、實現方式 1. 非遞迴方式 2. 遞迴方式

[轉載]MarkDown技巧:方式實現頁內跳轉

MarkDown技巧:兩種方式實現頁內跳轉 本文轉載自:https://www.cnblogs.com/JohnTsai/p/4027229.html?tdsourcetag=s_pctim_aiomsg 文章頭部在這裡 寫文章時,突然發現如果寫了一篇很長的文章,要是

MySQL修改資料庫表的預設空間配置(方式實現)

一:問題背景介紹.      1. MySQL插入1000W條資料的時候因資料量大於單表預設資料量而報錯.(MySQL 5.7)           

leetCode 349號題目 個陣列的交集 ,方式實現, 複雜度分別為O(n^2) 和 O(n)

給定兩個陣列,編寫一個函式來計算它們的交集。 示例 1: 輸入: nums1 = [1,2,2,1], nums2 = [2,2] 輸出: [2] 示例 2: 輸入: nums1 = [4,9,5], nums2 = [9,4,9,8,4] 輸出: [9,4] 說明:

智聯招聘抓取---scrapy框架和requests庫方式實現

#首先分析目標站點,分析得出結果是在json接口裡,然後抓取企業資訊需要再次請求頁面進行抓取 #1.直接requests請求進行抓取儲存 ##需要注意點: 可能不同企業單頁排版不一樣,需要判斷採取不同形式 儲存為csv檔案注意格式,保證資料表格不換行需要新增

Android使用方式實現類似三隻松鼠首頁圖片滑動居中效果

       昨天做商城專案第2版,UI給出一個了設計圖,商品圖片可以左右滑動對齊,剛開始以為一個Recyclerview加個方向滑動一下就搞定了,做出來後UI說效果不對,參考三隻松鼠商城首頁效果,研究了一下,效果就是每次不管左滑還是右滑圖片都是處於居中位置的,使用了Gall

spring之AOP操作(基於aspectJ實現)--配置檔案和註解方式實現

AOP概念   1 aop:面向切面(方面)程式設計,擴充套件功能不修改原始碼實現     2  AOP採取橫向抽取機制,取代了傳統縱向繼承體系重複性程式碼     3 aop底層使用動態代理實現     (1)第一種情況,有介面情況,使用動態代理建立介面實現類代理物

【轉載】快速排序(三演算法實現和非遞迴實現)

原文地址 python實現: import random a = [4,1,7,6,9,2,2,3,5,7,8,9,3,1,2,3,4,5,8,0,3,5] b = [4,1,7,6,9,2,8,0,3,5] def twoPointerSort(nums,le

Unity3D方式實現遊戲視訊播放

轉至https://www.cnblogs.com/zerotoinfinity/p/6604150.html 準備工作   由於Unity中能夠識別的視訊格式主要有:.mov, .mpg, .mpeg, .mp4, .avi, .asf,但是其實最後這些格式的時候在匯入到Unity中的時候

Java和PHP方式實現上傳圖片到新浪微博的圖床

這幾天遇到一個需求,需要將圖片上傳到新浪微博的圖傳,研究了一下, 特此記錄1.模擬登陸,獲取cookie登入地址為:https://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.15)&_=140313

基於陣列和連結串列方式實現

棧是一種先進後出的資料結構,在實際程式設計棧有很廣泛的用處,Java棧已經幫我們實現好了stack類。 實現棧的兩種方式,基於陣列實現和基於連結串列實現。 1.stack介面 public interface StackADT { //入棧操作 public voi