1. 程式人生 > >常見幾種排序演算法的C++描述

常見幾種排序演算法的C++描述

首先看一下幾種常見排序的特性

這裡寫圖片描述

插入排序

void insertSort(vector<int> & arr)
{
    int sz = arr.size();
    int tmp;
    for (int i = 1; i < sz; ++i){
        tmp = arr[i];
        int j;
        for (j = i; j > 0 && tmp < arr[j - 1]; j--)
            arr[j] = arr[j - 1];
        arr[j] = tmp;
    }
}

快速排序

//注意如果採取的是三數中值分割法的時候需要,將頭,中,尾的三個值中間的轉移到陣列的頭部。這樣來進行partition
void quickSort(vector<int> & arr, int start, int end)
{
    if (start >= end)
        return;
    int pivot = getPartion(arr, start, end);
    quickSort(arr, start, pivot - 1);
    quickSort(arr, pivot + 1, end);
}


void
bubbleSort(vector<int> & arr) { int sz = arr.size(); for (int i = sz - 1; i > 0; --i){ for (int j = 0; j < i; ++j){ //邊界需要注意一下 if (arr[j] > arr[j + 1]) swap(arr[j], arr[j+1]); } } }

希爾排序

void shellSort(vector<int> & arr)
{
    int
sz = arr.size(); for (int gap = sz / 2; gap > 0; gap /= 2){ int tmp; for (int i = gap; i < sz; ++i){//每次和保證自己同樣的間隔組中資料是有序的,然後再使用插入排序的思想 tmp = arr[i]; int j; for (j = i; j >= gap && tmp < arr[j - gap]; j -= gap){ arr[j] = arr[j - gap]; } arr[j] = tmp; } } }

堆排序

int up(int i){
    return (i - 1) / 2; //堆節點從0開始計算
}

int down(int i){
    return i * 2 + 1; //左節點
}

//新增資料用
void minHeapFixUp(vector<int> & arr, int i)//i代表插入的位置
{
    int j = up(i);
    int tmp = arr[i];
    while (j >= 0 && i != 0){
        if (arr[j] <= arr[i])
            break; //停止調整
        arr[i] = arr[j];
        i = j;
        j = up(i);
    }
    arr[i] = tmp;
}

//刪除資料用,實際上是通過刪除操作來調整堆
void minHeapFixDown(vector<int> & arr, int i, int n)
{
    int tmp = arr[i];
    int j = down(i);
    while (j < n){
        if (j + 1 < n && arr[j] > arr[j + 1])
            j++;
        if (tmp <= arr[j])
            break;
        arr[i] = arr[j];
        i = j;
        j = down(j);
    }
    arr[i] = tmp;
}

void makeHeap(vector<int> & arr)
{
    int sz = arr.size();
    //從sz/2 - 1開始建堆的目的是因為對於堆來說,有sz/2 + 1個節點是葉子節點,
    //由於其左右不存在子節點,不需要向下調整,所以從非葉子節點開始向下調整
    for (int i = sz / 2 - 1; i >= 0; --i){
        minHeapFixDown(arr, i, sz);
    }
}

void heapSort(vector<int> & arr)//最小堆得到降序排序
{
    int sz = arr.size();
    makeHeap(arr);
    for (int i = sz - 1; i > 0; --i){
        swap(arr[0], arr[i]); //得到最小的一個數
        minHeapFixDown(arr, 0, i);
    }
}

歸併排序

void merge(vector<int> & arr, vector<int> & copy, int start, int mid, int end)
{
    int p = start, q = mid + 1, i = start;
    while (p <= mid && q <= end){
        if (arr[p] < arr[q])
            copy[i++] = arr[p++];
        else
            copy[i++] = arr[q++];
    }
    while (p <= mid)
        copy[i++] = arr[p++];
    while (q <= end)
        copy[i++] = arr[q++];
    while (start <= end){
        arr[start] = copy[start];
        start++; //注意這裡一定要分開寫  而不要合在一起,容易加兩次出錯
    }
}

void mergeSort(vector<int> & arr, vector<int> & copy, int start, int end)
{
    if (start < end){
        int mid = (start + end) >> 1;
        mergeSort(arr, copy, start, mid);
        mergeSort(arr, copy, mid + 1, end);
        merge(arr, copy, start, mid, end);
    }
}

void mergeSort(vector<int> & arr)
{
    vector<int> copy(arr);
    int sz = arr.size();
    int mid = sz / 2;
    mergeSort(arr, copy, 0, mid);
    mergeSort(arr, copy, mid + 1, sz - 1);
    merge(arr, copy, 0, mid, sz - 1);
}

直接選擇排序

void selectSort(vector<int> & vec){
    int sz = vec.size();
    int minPos;
    for (int i = 0; i < sz - 1; ++i){
        minPos = i;
        for (int j = i + 1; j < sz; ++j){
            if (vec[j] < vec[minPos])
                minPos = j;
        }
        swap(vec[i], vec[minPos]);
    }
}

基數排序

  • 分別按照個位,十位,百位。。。來進行桶排序,得到最終結果就是正確的結果
public class RadixSort {
    // 獲取x這個數的d位數上的數字
    // 比如獲取123的1位數,結果返回3
    public int getDigit(int x, int d) {
        int a[] = {
                1, 1, 10, 100
        }; // 本例項中的最大數是百位數,所以只要到100就可以了
        return ((x / a[d]) % 10);
    }
    public void radixSort(int[] list, int begin, int end, int digit) {
        final int radix = 10; // 基數
        int i = 0, j = 0;
        int[] count = new int[radix]; // 存放各個桶的資料統計個數
        int[] bucket = new int[end - begin + 1];
        // 按照從低位到高位的順序執行排序過程
        for (int d = 1; d <= digit; d++) {
            // 置空各個桶的資料統計
            for (i = 0; i < radix; i++) {
                count[i] = 0;
            }
            // 統計各個桶將要裝入的資料個數
            for (i = begin; i <= end; i++) {
                j = getDigit(list[i], d);
                count[j]++;
            }
            // count[i]表示第i個桶的右邊界索引
            for (i = 1; i < radix; i++) {
                count[i] = count[i] + count[i - 1];
            }
            // 將資料依次裝入桶中
            // 這裡要從右向左掃描,保證排序穩定性
            for (i = end; i >= begin; i--) {
                j = getDigit(list[i], d); // 求出關鍵碼的第k位的數字, 例如:576的第3位是5
                bucket[count[j] - 1] = list[i]; // 放入對應的桶中,count[j]-1是第j個桶的右邊界索引
                count[j]--; // 對應桶的裝入資料索引減一
            }
            // 將已分配好的桶中資料再倒出來,此時已是對應當前位數有序的表
            for (i = begin, j = 0; i <= end; i++, j++) {
                list[i] = bucket[j];
            }
        }
    }
    public int[] sort(int[] list) {
        radixSort(list, 0, list.length - 1, 3);
        return list;
    }
    // 列印完整序列
    public void printAll(int[] list) {
        for (int value : list) {
            System.out.print(value + "\t");
        }
        System.out.println();
    }
    public static void main(String[] args) {
        int[] array = {
                50, 123, 543, 187, 49, 30, 0, 2, 11, 100
        };
        RadixSort radix = new RadixSort();
        System.out.print("排序前:\t\t");
        radix.printAll(array);
        radix.sort(array);
        System.out.print("排序後:\t\t");
        radix.printAll(array);
    }
}

相關推薦

常見排序演算法C++描述

首先看一下幾種常見排序的特性 插入排序 void insertSort(vector<int> & arr) { int sz = arr.size();

常見排序演算法(java和C++版)(參考《演算法》)

博主這裡要講的幾種排序演算法包括(從難到易):1.氣泡排序(最low的演算法) 2.插入排序 3.希爾排序 4.歸併排序 5.快速排序 6.快速排序的三項切分 氣泡排序: (1)簡介:這是最原始,最簡單的排序,幾乎不需要額外的空間 (2)基本原理:通過迴圈將最大的元素移到

11. 常見的有哪排序演算法,試比較其時間複雜度,以及是否穩定,及各自使用的情形

1、幾種常見排序演算法的時間複雜度 排序方法 平均情況 最好情況 最壞情況 直接插入排序 O(n2) O(n) O(n2) 起泡排序 O(n2) O(n) O(n2) 快速排序 O(nlog2n) O(nlog2n)

Java常見排序演算法-插入、選擇、冒泡、快排、堆排等

本文就是介紹一些常見的排序演算法。排序是一個非常常見的應用場景,很多時候,我們需要根據自己需要排序的資料型別,來自定義排序演算法,但是,在這裡,我們只介紹這些基礎排序演算法,包括:插入排序、選擇排序、氣泡排序、快速排序(重點)、堆排序、歸併排序等等。看下圖: 給定陣

常見排序演算法-插入、選擇、冒泡、快排、堆排等

作者:egg 郵箱:[email protected] 本文就是介紹一些常見的排序演算法。排序是一個非常常見的應用場景,很多時候,我們需要根據自己需要排序的資料型別,來自定義排序演算法,但是,在這裡,我們只介紹這些基礎排序演算法,包括

Java之常見排序演算法-插入、選擇、冒泡、快排、堆排等 .

本文就是介紹一些常見的排序演算法。排序是一個非常常見的應用場景,很多時候,我們需要根據自己需要排序的資料型別,來自定義排序演算法,但是,在這裡,我們只介紹這些基礎排序演算法,包括:插入排序、選擇排序、氣泡排序、快速排序(重點)、堆排序、歸併排序等等。看下圖: 給定陣

Java之常見排序演算法-插入、選擇、冒泡、快排、堆排等

Java面試寶典系列之基礎排序演算法 作者:egg 郵箱:[email protected] 本文就是介紹一些常見的排序演算法。排序是一個非常常見的應用場景,很多時候,我們需要根據自己需要排序的資料型別,來自

Java 常見排序演算法-插入、選擇、冒泡、快排、堆排等

本文就是介紹一些常見的排序演算法。排序是一個非常常見的應用場景,很多時候,我們需要根據自己需要排序的資料型別,來自定義排序演算法,但是,在這裡,我們只介紹這些基礎排序演算法,包括:插入排序、選擇排序、氣泡排序、快速排序(重點)、堆排序、歸併排序等等。看下圖:

隨機生成100個數,利用排序演算法對其實現排序C++)

#include<iostream> #include<cstdlib> #include<ctime> using namespace std; //交換 template<class T> void Swap(T &a,T &b) {

C++ 排序演算法詳解

排序的演算法有很多種,其關鍵在於根據待排序序列的特性選擇合適的排序方式。下面將介紹不同的排序方式。 基本排序演算法 基本排序演算法主要包括插入排序,快速排序,氣泡排序等三種排序方式,下面將對這三種排序演算法分別進行分析 插入排序 假定待排序陣列序列為:data[5,2

排序演算法,記錄一下

個人也就會四種排序(bubble,select,insert,quick),哈哈,看官大人可能有點失望。自己也看過幾種,不過一直沒寫過其他的,就記錄下這四種吧。 程式碼均可直接通過編譯。各種版本實現都有出入,不過思想都是一樣。工作這麼久還沒有一次性完全寫正確過,功力還是差點。 #includ

5 排序演算法--C語言連結串列

原始碼地址 GitHub:https://github.com/GYT0313/C-DataStructure/blob/master/sortIn5.c 包括: 氣泡排序 快速排序 選擇排序 插入排序 希爾排序 執行: 注意:

【python資料結構與演算法排序演算法:氣泡排序、快速排序

以下排序演算法,預設的排序結果是從小到大。 一.氣泡排序: 1.氣泡排序思想:越大的元素,就像越大的氣泡。最大的氣泡才能夠浮到最高的位置。 具體來說,即,氣泡排序有兩層迴圈,外層迴圈控制每一輪排序中操作元素的個數——氣泡排序每一輪都會找到遍歷到的元素的最大值,並把它放在最後,下一輪排序時

總結排序演算法的Java實現

1、氣泡排序 氣泡排序是一種交換排序,它的基本思想是:兩兩比較相鄰記錄的關鍵字,如果反序則交換,直到沒有反序的記錄為止。 Java程式碼: import java.util.Random; public class BubbleSort { /** * 改進的氣

排序演算法

本文轉載自碼農網:http://www.codeceo.com/article/10-sort-algorithm-interview.html#0-tsina-1-10490-397232819ff9a47a7b7e80a40613cfe1 查詢和排

排序演算法的Python形式

直接見程式碼吧,因為比較簡單 依次為 冒泡 選擇 快排 插入 歸併 堆排 桶排  class Sort: def bubble(self, nums): for i

自我整理:排序演算法的理解

簡單來自己做個筆記,溫故一下排序方法。 1.直接排序 顧名思義,直接排,怎麼直接排,每次迴圈找出最下的扔到第一個,或者找到最大的扔到最後一個,剩下的數字,繼續迴圈找最小的往前扔,暴力排完。簡單粗暴,居家

【資料結構】十一排序演算法C++實現

   練習了十一種排序演算法的C++實現:以下依次為,冒泡、選擇、希爾、插入、二路歸併、快排、堆排序、計數排序、基數排序、桶排序,可建立sort.h和main.cpp將程式碼放入即可執行。如有錯誤,請指出更正,謝謝交流。 // sort.h # include <

排序演算法java實現

沒有配圖,過幾天補上 package com.sort; public class Sort { /** * 插入排序 * 原理:往有序的子陣列選擇一個合適的位置插進去 * */ public void insertSort(int sort[

排序演算法實現以及穩定性

穩定性演算法:氣泡排序、插入排序、歸併排序、基數排序 不穩定性演算法:選擇排序、快速排序、堆排序、希爾排序、桶排序 /**  *   * @author huangsen  * 插入排序:一個有序陣列,一個無序陣列,將無序陣列插入到有序陣列中  *  */ public