亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C語言實現(xiàn)交換排序算法(冒泡,快速排序)的示例代碼

 更新時間:2022年07月07日 15:09:03   作者:白滴岑  
這篇文章主要為大家詳細介紹了如何利用C語言實現(xiàn)交換排序算法(冒泡排序、快速排序),文中的示例代碼講解詳細,感興趣的小伙伴可以了解一下

前言

查找和排序是數(shù)據(jù)結(jié)構(gòu)與算法中不可或缺的一環(huán),是前輩們在算法道路上留下的重要且方便的一些技巧,學習這些經(jīng)典的查找和排序也能讓我們更好和更快的解決問題。在這個專欄中我們會學習六大查找和十大排序的算法與思想,而本篇將詳細講解其中的交換排序——冒泡排序和快速排序;

注意:本文中所有排序按照升序排序,降序只需要把邏輯反過來即可!

一、冒泡排序

1.基本思想

對于很多同學來說冒泡排序是再熟悉不過了,冒泡的思想在于:不斷的比較兩個元素并交換,大的在右邊,小的在左邊;

 有一個數(shù)組{5, 1, 4, 2, 8, 4}

第一輪

  • arr[0] = 5和 arr[1] = 1比較 5 > 1,交換;
  • arr[2] = 4和 arr[1] = 5比較 5 > 4,交換;
  • arr[2] = 5和 arr[3] = 2比較 5 > 2,交換;
  • arr[3] = 5和 arr[4] = 8比較 5 < 8,不交換;
  • arr[4] = 8和 arr[5] = 4比較 8 > 4,交換;

第二輪

從arr[1]開始重復上述的步驟;

... ...直到循環(huán) N - 1 次,排序結(jié)束;

#include <stdio.h>
#include<stdlib.h>
 
//冒泡排序
void bubbleSort(int a[], int n)
{
    //一共要掃描n-1趟
    for(int i = 0; i < n - 1; i++)
    {
        //用來比較 交換
        for(int j = 0; j < n - i - 1; j++)
        {
            if(a[j] > a[j + 1])
            {
                int temp = a[j + 1];
                a[j + 1] = a[j];
                a[j] = temp; 
            }
        }
    }
}
 
int main()
{
    int arr[] = {5, 1, 4, 2, 8, 4};
    int length = sizeof(arr) / sizeof(arr[0]);
    bubbleSort(arr, length);
    for(int i = 0; i < length; i++)
    {
        printf("%d", arr[i]);
    }
    system("pause");
    return 0;
}

那么問題來了,問題一:這里我們發(fā)現(xiàn)對于這個數(shù)組而言在第二輪排序就已經(jīng)排好了整體甚至穩(wěn)定的有序,剩下的循環(huán)就相當于浪費了,那么有沒有一種方法能夠判斷數(shù)組已經(jīng)有序?

還有這樣一個數(shù)組{4, 2, 1, 5, 6, 8}

問題二:我們發(fā)現(xiàn){5, 6, 8}的部分是已經(jīng)有序了的,對于已經(jīng)有序的部分還要繼續(xù)比較,那么能不能確定出有序的部分和無序的部分的邊界呢?

2.優(yōu)化

針對問題一,我們可以添加一個標志,用來標識數(shù)組是否有序:當某一輪排序沒有發(fā)生交換,就可以認為數(shù)組已經(jīng)有序了;

針對問題二,我們可以記錄冒泡排序的過程中最后一次發(fā)生交換的地方index,如在下圖中index==1,每一次后面的排序只要從第一個到index就可以了;

值得注意的是,不管怎樣去優(yōu)化,最壞情況的時間復雜度都是O(n^2),即數(shù)組逆序的情況;

3.擴展

雖然用棧實現(xiàn)冒泡排序可能在實際中沒有應用場景(也沒必要用),但是可能會有面試的時候要求用?;蛘咂渌慕Y(jié)構(gòu)去實現(xiàn)冒泡排序來考查對算法和思想熟練度,所以這里也提供用棧實現(xiàn)冒泡排序的思路;

void bubbleSort(int a[], int n)
{
    //定義兩個棧S1和S2
    stack<int>stk1, stk2;
    //將數(shù)組中的所有元素入棧S1
    for (int i = 0; i < n; i++)
    {
        stk1.push(a[i]);
    }
    //循環(huán)N次 每一次找出最大的元素(就像真冒泡一樣 最大的元素浮在最上面)
    for (int i = 0; i < n; i++)
    {
        //如果S1不為空
        while (!stk1.empty())
        {
            //如果S2為空就把棧S1頂?shù)脑厝霔2
            if (stk2.empty())
            {
                stk2.push(stk1.top());
                stk1.pop();
            }
            else
            {
                int temp = 0;//用于接收需要交換的元素
                if (stk1.top() < stk2.top())
                {
                    //如果S1的棧頂小于S2的棧頂 把S1的棧頂壓在S2的棧頂下面
                    temp = stk2.top();
                    stk2.pop();
                    stk2.push(stk1.top());
                    stk1.pop();
                    stk2.push(temp);
                }
                else
                {
                    stk2.push(stk1.top());
                    stk1.pop();
                }
            }
        }
        //把最大的元素從后往前更新回原數(shù)組中
        a[n - i - 1] = stk2.top();
        stk2.pop();
        //把剩下的元素倒棧 重復
        for (int j = stk2.size(); j > 0; j--)
        {
            stk1.push(stk2.top());
            stk2.pop();
        }
    }
}

二、快速排序

1.基本思想

選取一個基準(可以認為是要放到排序以后正確的位置的元素,可以是第一個元素、最后一個 中間的、隨機的都可以);

把數(shù)組中的元素做一個劃分,每一趟劃分將作為基準的值x放到排序后數(shù)組正確的位置,并將所有比x小的放到左邊,比x大的放到右邊;

有一個數(shù)組{1, 8, 3, 9, 4, 5, 4, 7}

假定選擇元素arr[7] = 7為基準,就是要把7放在正確的位置,那么只有兩種情況:

要么7本身就是正確的位置,要么就在前面;

第一步:初始化指針 i = -1,j = 0,把 j 指向的元素和7比較 ,當1 < 7,將 i++, 交換 i 和 j 指向的元素,j++;

第二步:把 j 指向的元素和7比較 ,當8 > 7,將 j++;

第三步:把 j 指向的元素和7比較 ,當3 < 7,將 i++, 交換 i 和 j 指向的元素,j++;

第四步:把 j 指向的元素和7比較 ,當4 < 7,將 i++, 交換 i 和 j 指向的元素,j++;

第五步:把 j 指向的元素和7比較 ,當5 < 7,將 i++, 交換 i 和 j 指向的元素,j++;

第五步:把 j 指向的元素和7比較 ,當4 < 7,將 i++, 交換 i 和 j 指向的元素,j++;

第六步:當j到7遍歷結(jié)束,讓i++的位置和7交換,第一趟排序結(jié)束;

如此一來,基準7就找到了它在數(shù)組中的正確位置,并且把數(shù)組劃分成了兩邊【0,5)和(5,7】這時再選一個基準再進行上述步驟,如下圖所示: 

是不是覺得很眼熟?沒錯這就是一棵二叉樹:

2.優(yōu)化

既然是二叉樹,那么排出一棵斜樹自然就是最壞的情況;要緩解這個問題,可以以中間的值為基準來減少這種情況的發(fā)生;

即復雜度與數(shù)組長度和基準的選擇有關,尾基準是O(n^2)因為n趟每一趟劃分需要O(n),而平衡樹是O(nlogn),通過數(shù)學方法能夠得到更優(yōu)的基準選擇,但無論選什么為基準都應該能滿足:基準左邊小、右邊大;

我們之前說過,快速排序其實是一個不穩(wěn)定排序(不穩(wěn)定的排序就意味著交換的次數(shù)多,如果需要按多條件排序就會亂),而我們又說過任何一個不穩(wěn)定的排序算法都有辦法使其變得穩(wěn)定,用到的是以空間換時間的思想;

也就是我們可以用一個變量對原來的順序做標記;

3.代碼

既然是通過不斷劃分數(shù)組來減少比較的次數(shù),這一聽就知道用到了分治的思想,也就是可以用遞歸來實現(xiàn)代碼:

#include <stdio.h>
#include<stdlib.h>
 
//快排
void quickSort(int a[], int low, int high)
{
   if(low < high)
   {
        int i = low;//這里以i下標的值為基準
        int j = high;
        int k = a[low];//k是用來記錄基準的值
        while(i < j)
        {
            //從右往左找第一個比k要小的值
            while(i < j && a[j] >= k)
            {
                j--;
            }
            if(i < j)
            {
                a[i++] = a[j];
            }
            //從左往右找第一個比k要大的值
            while(i < j && a[i] < k)
            {
                i++;
            }
            if(i < j)
            {
                a[j--] = a[i];
            }
        }
        a[i] = k;
        //遞歸
        quickSort(a, low, i - 1);
        quickSort(a, i + 1, high);
   }
}
 
int main()
{
    int arr[] = {1, 8, 3, 9, 4, 5, 4, 7};
    int length = sizeof(arr) / sizeof(arr[0]);
    quickSort(arr, 0, length - 1);
    for(int i = 0; i < length; i++)
    {
        printf("%d ", arr[i]);
    }
    system("pause");
    return 0;
}

運行結(jié)果

到此這篇關于C語言實現(xiàn)交換排序算法(冒泡,快速排序)的示例代碼的文章就介紹到這了,更多相關C語言交換排序算法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Matlab實現(xiàn)三維投影繪制的示例代碼

    Matlab實現(xiàn)三維投影繪制的示例代碼

    這篇文章系小編為大家?guī)砹艘粋€三維投影繪制函數(shù)(三視圖繪制),函數(shù)支持三維曲線、曲面、三維多邊形、參數(shù)方程曲線、參數(shù)方程曲面的投影繪制,需要的可以參考一下
    2022-08-08
  • C++中賦值運算符與逗號運算符的用法詳解

    C++中賦值運算符與逗號運算符的用法詳解

    這篇文章主要介紹了C++中賦值運算符與逗號運算符的用法詳解,是C++入門學習中的基礎知識,需要的朋友可以參考下
    2015-09-09
  • C++ DLL動態(tài)庫的創(chuàng)建與調(diào)用(類庫,隱式調(diào)用)

    C++ DLL動態(tài)庫的創(chuàng)建與調(diào)用(類庫,隱式調(diào)用)

    本文主要介紹了C++ DLL動態(tài)庫的創(chuàng)建與調(diào)用(類庫,隱式調(diào)用),文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • C語言實現(xiàn)飛機訂票系統(tǒng)

    C語言實現(xiàn)飛機訂票系統(tǒng)

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)飛機訂票系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-12-12
  • C++ 如何實現(xiàn)順序棧(使用模板類)

    C++ 如何實現(xiàn)順序棧(使用模板類)

    這篇文章主要介紹了C++ 如何實現(xiàn)順序棧(使用模板類),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • QT連接Mysql數(shù)據(jù)庫的實現(xiàn)步驟

    QT連接Mysql數(shù)據(jù)庫的實現(xiàn)步驟

    本文主要介紹了QT連接Mysql數(shù)據(jù)庫的實現(xiàn)步驟,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-06-06
  • C語言實現(xiàn)的PNPoly算法代碼例子

    C語言實現(xiàn)的PNPoly算法代碼例子

    這篇文章主要介紹了C語言實現(xiàn)的PNPoly算法代碼例子,PNPoly算法j是判斷一個坐標點是否在不規(guī)則多邊形內(nèi)部的算法,需要的朋友可以參考下
    2014-07-07
  • C語言文件操作函數(shù)freopen詳細解析

    C語言文件操作函數(shù)freopen詳細解析

    替換一個流,或者說重新分配文件指針,實現(xiàn)重定向。如果stream流已經(jīng)打開,則先關閉該流。如果該流已經(jīng)定向,則freopen將會清除該定向。此函數(shù)一般用于將一個指定的文件打開一個預定義的流:標準輸入、標準輸出或者標準出錯
    2013-10-10
  • C++實現(xiàn)LeetCode(143.鏈表重排序)

    C++實現(xiàn)LeetCode(143.鏈表重排序)

    這篇文章主要介紹了C++實現(xiàn)LeetCode(143.鏈表重排序),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • C++ 實現(xiàn)2048游戲示例

    C++ 實現(xiàn)2048游戲示例

    《2048》是比較流行的一款數(shù)字游戲。原版2048首先在github上發(fā)布,原作者是Gabriele Cirulli。它是基于《1024》和《小3傳奇》的玩法開發(fā)而成的新型數(shù)字游戲。
    2014-06-06

最新評論