国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【QT深入理解】QT中的幾種常用的排序函數(shù)

這篇具有很好參考價(jià)值的文章主要介紹了【QT深入理解】QT中的幾種常用的排序函數(shù)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

第一章:排序函數(shù)的概述

排序函數(shù)是一種在編程中常用的函數(shù),它可以對(duì)一個(gè)序列(如數(shù)組,列表,向量等)中的元素進(jìn)行排序,使其按照一定的順序排列。排序函數(shù)可以根據(jù)不同的排序算法,如冒泡排序,選擇排序,插入排序,快速排序,歸并排序,堆排序等,實(shí)現(xiàn)不同的排序效果。排序函數(shù)的作用有以下幾點(diǎn):

  • 提高查找效率。當(dāng)一個(gè)序列中的元素是有序的,就可以使用一些高效的查找算法,如二分查找,插值查找,斐波那契查找等,來快速地找到目標(biāo)元素。
  • 方便數(shù)據(jù)分析。當(dāng)一個(gè)序列中的元素是有序的,就可以方便地進(jìn)行一些數(shù)據(jù)分析,如求最大值,最小值,中位數(shù),眾數(shù),分位數(shù),頻率分布,直方圖等。
  • 增加數(shù)據(jù)可讀性。當(dāng)一個(gè)序列中的元素是有序的,就可以增加數(shù)據(jù)的可讀性,使其更容易被人理解和比較。

QT是一個(gè)跨平臺(tái)的應(yīng)用程序開發(fā)框架,它提供了一些常用的排序函數(shù),可以對(duì)QT中的一些容器類(如QList,QVector,QMap,QSet等)中的元素進(jìn)行排序。QT中提供的排序函數(shù)有以下幾種:

  • qSort:這是一個(gè)通用的排序函數(shù),它使用快速排序算法,可以對(duì)任何可隨機(jī)訪問的序列進(jìn)行排序。它可以指定一個(gè)比較函數(shù)或者一個(gè)比較對(duì)象,來自定義排序的規(guī)則。它的排序結(jié)果是不穩(wěn)定的,也就是說,如果序列中有相等的元素,它們的相對(duì)位置可能會(huì)改變。
  • qStableSort:這是一個(gè)穩(wěn)定的排序函數(shù),它使用歸并排序算法,可以對(duì)任何可隨機(jī)訪問的序列進(jìn)行排序。它可以指定一個(gè)比較函數(shù)或者一個(gè)比較對(duì)象,來自定義排序的規(guī)則。它的排序結(jié)果是穩(wěn)定的,也就是說,如果序列中有相等的元素,它們的相對(duì)位置不會(huì)改變。
  • qPartialSort:這是一個(gè)部分排序函數(shù),它使用堆排序算法,可以對(duì)任何可隨機(jī)訪問的序列進(jìn)行部分排序。它可以指定一個(gè)范圍,只對(duì)序列中的這個(gè)范圍內(nèi)的元素進(jìn)行排序,而不影響其他元素。它可以指定一個(gè)比較函數(shù)或者一個(gè)比較對(duì)象,來自定義排序的規(guī)則。它的排序結(jié)果是不穩(wěn)定的。
  • qHeapSort:這是一個(gè)堆排序函數(shù),它使用堆排序算法,可以對(duì)任何可隨機(jī)訪問的序列進(jìn)行排序。它可以指定一個(gè)比較函數(shù)或者一個(gè)比較對(duì)象,來自定義排序的規(guī)則。它的排序結(jié)果是不穩(wěn)定的。它的特點(diǎn)是,它可以在不使用額外空間的情況下,對(duì)序列進(jìn)行原地排序,也就是說,它不需要?jiǎng)?chuàng)建一個(gè)新的序列來存儲(chǔ)排序結(jié)果,而是直接在原序列上進(jìn)行操作。
  • qLowerBound和qUpperBound:這不是排序函數(shù),而是查找函數(shù),它們可以在一個(gè)有序的序列中,查找一個(gè)給定的元素的下界和上界。下界是指序列中第一個(gè)不小于給定元素的位置,上界是指序列中第一個(gè)大于給定元素的位置。它們可以指定一個(gè)比較函數(shù)或者一個(gè)比較對(duì)象,來自定義查找的規(guī)則。它們的查找效率是對(duì)數(shù)級(jí)別的,也就是說,它們使用二分查找算法,每次查找都可以將查找范圍縮小一半。

第二章:qSort函數(shù)

qSort函數(shù)是QT中提供的一個(gè)通用的排序函數(shù),它使用快速排序算法,可以對(duì)任何可隨機(jī)訪問的序列進(jìn)行排序??焖倥判蛩惴ǖ幕舅枷胧?,選擇一個(gè)基準(zhǔn)元素,將序列分為兩個(gè)子序列,一個(gè)子序列中的元素都小于或等于基準(zhǔn)元素,另一個(gè)子序列中的元素都大于基準(zhǔn)元素,然后對(duì)這兩個(gè)子序列遞歸地進(jìn)行快速排序,最后將兩個(gè)子序列合并成一個(gè)有序的序列??焖倥判蛩惴ǖ钠骄鶗r(shí)間復(fù)雜度是O(nlogn),最壞情況下的時(shí)間復(fù)雜度是O(n^2),空間復(fù)雜度是O(logn)。

qSort函數(shù)的函數(shù)原型如下

template <typename RandomAccessIterator>
void qSort(RandomAccessIterator begin, RandomAccessIterator end);

template <typename RandomAccessIterator, typename LessThan>
void qSort(RandomAccessIterator begin, RandomAccessIterator end, LessThan lessThan);

qSort函數(shù)的功能參數(shù)

對(duì)從begin到end(不包括end)的元素進(jìn)行排序。

第一個(gè)參數(shù)begin是指向序列開始位置的迭代器

第二個(gè)參數(shù)end是指向序列結(jié)束位置的迭代器

第三個(gè)參數(shù)lessThan是一個(gè)比較函數(shù)或者一個(gè)比較對(duì)象,它可以自定義排序的規(guī)則,它接受兩個(gè)元素作為參數(shù),返回一個(gè)布爾值,表示第一個(gè)元素是否小于第二個(gè)元素。如果沒有指定第三個(gè)參數(shù),qSort函數(shù)會(huì)使用默認(rèn)的比較規(guī)則,即使用元素的<運(yùn)算符進(jìn)行比較。

qSort函數(shù)的用法示例

  • 如果要對(duì)一個(gè)數(shù)組進(jìn)行排序,可以直接傳入數(shù)組的首地址和尾地址作為參數(shù),例如:
int arr[] = {5, 3, 7, 1, 9, 4, 6, 8, 2};
qSort(arr, arr + 9); // 對(duì)arr數(shù)組進(jìn)行升序排序
  • 如果要對(duì)一個(gè)QList或者QVector進(jìn)行排序,可以使用它們的begin()和end()方法來獲取迭代器,例如:
QList<int> list;
list << 5 << 3 << 7 << 1 << 9 << 4 << 6 << 8 << 2;
qSort(list.begin(), list.end()); // 對(duì)list進(jìn)行升序排序
  • 如果要對(duì)一個(gè)QMap或者QSet進(jìn)行排序,可以使用它們的keys()或者values()方法來獲取一個(gè)QList,然后對(duì)QList進(jìn)行排序,例如:
QMap<QString, int> map;
map["Alice"] = 90;
map["Bob"] = 80;
map["Charlie"] = 85;
map["David"] = 95;
QList<QString> names = map.keys(); // 獲取map的鍵的列表
qSort(names.begin(), names.end()); // 對(duì)names進(jìn)行升序排序
  • 如果要自定義排序的規(guī)則,可以傳入一個(gè)比較函數(shù)或者一個(gè)比較對(duì)象作為第三個(gè)參數(shù),例如:
// 定義一個(gè)比較函數(shù),按照字符串的長(zhǎng)度進(jìn)行比較
bool compareByLength(const QString &a, const QString &b)
{
    return a.length() < b.length();
}

// 定義一個(gè)比較對(duì)象,按照學(xué)生的成績(jī)進(jìn)行比較
struct compareByScore
{
    bool operator()(const Student &a, const Student &b)
    {
        return a.score > b.score; // 降序排序
    }
};

QList<QString> words;
words << "apple" << "banana" << "orange" << "pear" << "grape";
qSort(words.begin(), words.end(), compareByLength); // 按照單詞的長(zhǎng)度進(jìn)行升序排序

QList<Student> students;
students << Student("Alice", 90) << Student("Bob", 80) << Student("Charlie", 85) << Student("David", 95);
qSort(students.begin(), students.end(), compareByScore()); // 按照學(xué)生的成績(jī)進(jìn)行降序排序

qSort函數(shù)注意事項(xiàng)

  • begin和end必須指向同一個(gè)序列,否則會(huì)導(dǎo)致未定義的行為。
  • begin和end之間的元素必須能夠被交換,否則會(huì)導(dǎo)致編譯錯(cuò)誤。
  • begin和end之間的元素必須能夠被比較,否則會(huì)導(dǎo)致編譯錯(cuò)誤或者運(yùn)行時(shí)錯(cuò)誤。
  • lessThan必須是一個(gè)嚴(yán)格弱序關(guān)系,也就是說,它必須滿足以下條件:
    • 對(duì)于任何元素x,lessThan(x, x)必須返回false。
    • 如果lessThan(x, y)返回true,那么lessThan(y, x)必須返回false。
    • 如果lessThan(x, y)和lessThan(y, z)都返回true,那么lessThan(x, z)也必須返回true。
  • qSort函數(shù)的排序結(jié)果是不穩(wěn)定的,也就是說,如果序列中有相等的元素(即lessThan(x, y)和lessThan(y, x)都返回false),它們的相對(duì)位置可能會(huì)改變。

以上就是qSort函數(shù)的介紹,下面我們將介紹qStableSort函數(shù)。

第三章:qStableSort函數(shù)

qStableSort函數(shù)是QT中提供的一個(gè)穩(wěn)定的排序函數(shù),它使用歸并排序算法,可以對(duì)任何可隨機(jī)訪問的序列進(jìn)行排序。歸并排序算法的基本思想是,將序列分為兩個(gè)子序列,對(duì)這兩個(gè)子序列分別進(jìn)行歸并排序,然后將兩個(gè)有序的子序列合并成一個(gè)有序的序列。歸并排序算法的時(shí)間復(fù)雜度是O(nlogn),空間復(fù)雜度是O(n)。

qStableSort函數(shù)的函數(shù)原型如下

template <typename RandomAccessIterator>
void qStableSort(RandomAccessIterator begin, RandomAccessIterator end);

template <typename RandomAccessIterator, typename LessThan>
void qStableSort(RandomAccessIterator begin, RandomAccessIterator end, LessThan lessThan);

qStableSort函數(shù)的功能參數(shù)

對(duì)從begin到end(不包括end)的元素進(jìn)行排序

第一個(gè)參數(shù)begin是指向序列開始位置的迭代器

第二個(gè)參數(shù)end是指向序列結(jié)束位置的迭代器

第三個(gè)參數(shù)lessThan是一個(gè)比較函數(shù)或者一個(gè)比較對(duì)象,它可以自定義排序的規(guī)則,它接受兩個(gè)元素作為參數(shù),返回一個(gè)布爾值,表示第一個(gè)元素是否小于第二個(gè)元素。如果沒有指定第三個(gè)參數(shù),qStableSort函數(shù)會(huì)使用默認(rèn)的比較規(guī)則,即使用元素的<運(yùn)算符進(jìn)行比較。

qStableSort函數(shù)的用法示例

qStableSort函數(shù)的用法和qSort函數(shù)的用法基本相同,只是qStableSort函數(shù)的排序結(jié)果是穩(wěn)定的,也就是說,如果序列中有相等的元素(即lessThan(x, y)和lessThan(y, x)都返回false),它們的相對(duì)位置不會(huì)改變。這一點(diǎn)在一些場(chǎng)景中是很重要的,例如,如果要對(duì)一個(gè)學(xué)生的列表按照姓名進(jìn)行排序,然后再按照成績(jī)進(jìn)行排序,如果使用qSort函數(shù),那么姓名相同的學(xué)生的成績(jī)順序可能會(huì)被打亂,而如果使用qStableSort函數(shù),那么姓名相同的學(xué)生的成績(jī)順序會(huì)保持不變。

代碼示例:

#include <QList>
#include <QString>
#include <QDebug>

// 定義一個(gè)學(xué)生類,包含姓名和成績(jī)兩個(gè)屬性
class Student
{
public:
    Student(const QString &name, int score) : name(name), score(score) {}
    QString name; // 姓名
    int score; // 成績(jī)
};

// 定義一個(gè)比較函數(shù),按照姓名進(jìn)行升序排序
bool compareByName(const Student &a, const Student &b)
{
    return a.name < b.name;
}

// 定義一個(gè)比較函數(shù),按照成績(jī)進(jìn)行降序排序
bool compareByScore(const Student &a, const Student &b)
{
    return a.score > b.score;
}


// 創(chuàng)建一個(gè)學(xué)生的列表
    QList<Student> students;
    students << Student("Alice", 90) << Student("Bob", 80) << Student("Charlie", 85) << Student("David", 95) << Student("Alice", 88) << Student("Bob", 82);

    // 使用qStableSort函數(shù)按照姓名進(jìn)行排序
    qStableSort(students.begin(), students.end(), compareByName);

    // 打印排序后的結(jié)果
    qDebug() << "Sorted by name:";
    for (const Student &s : students)
    {
        qDebug() << s.name << s.score;
    }

    // 使用qStableSort函數(shù)按照成績(jī)進(jìn)行排序
    qStableSort(students.begin(), students.end(), compareByScore);

    // 打印排序后的結(jié)果
    qDebug() << "Sorted by score:";
    for (const Student &s : students)
    {
        qDebug() << s.name << s.score;
    }


運(yùn)行這段代碼,可以得到以下輸出:

Sorted by name:
Alice 90
Alice 88
Bob 80
Bob 82
Charlie 85
David 95
Sorted by score:
David 95
Alice 90
Alice 88
Charlie 85
Bob 82
Bob 80

可以看到,qStableSort函數(shù)的排序結(jié)果是穩(wěn)定的,也就是說,姓名相同的學(xué)生的成績(jī)順序沒有改變,而是保持了原來的順序。這樣就可以方便地對(duì)數(shù)據(jù)進(jìn)行分組或者分析。

qStableSort函數(shù)注意事項(xiàng)

  • begin和end必須指向同一個(gè)序列,否則會(huì)導(dǎo)致未定義的行為。
  • begin和end之間的元素必須能夠被交換,否則會(huì)導(dǎo)致編譯錯(cuò)誤。
  • begin和end之間的元素必須能夠被比較,否則會(huì)導(dǎo)致編譯錯(cuò)誤或者運(yùn)行時(shí)錯(cuò)誤。
  • lessThan必須是一個(gè)嚴(yán)格弱序關(guān)系,也就是說,它必須滿足以下條件:
    • 對(duì)于任何元素x,lessThan(x, x)必須返回false。
    • 如果lessThan(x, y)返回true,那么lessThan(y, x)必須返回false。
    • 如果lessThan(x, y)和lessThan(y, z)都返回true,那么lessThan(x, z)也必須返回true。
  • qStableSort函數(shù)的排序結(jié)果是穩(wěn)定的,也就是說,如果序列中有相等的元素,它們的相對(duì)位置不會(huì)改變。

以上就是qStableSort函數(shù)的介紹,下面我們將介紹qPartialSort函數(shù)

第四章:qPartialSort函數(shù)

qPartialSort函數(shù)是QT中提供的一個(gè)部分排序函數(shù),它使用堆排序算法,可以對(duì)任何可隨機(jī)訪問的序列進(jìn)行部分排序。堆排序算法的基本思想是,將序列視為一個(gè)完全二叉樹,然后構(gòu)建一個(gè)最大堆或者最小堆,也就是說,每個(gè)節(jié)點(diǎn)的值都大于或者小于它的子節(jié)點(diǎn)的值。然后,將堆的根節(jié)點(diǎn)(也就是最大或者最小的元素)與堆的最后一個(gè)節(jié)點(diǎn)交換,然后將堆的大小減一,再調(diào)整堆的結(jié)構(gòu),重復(fù)這個(gè)過程,直到堆的大小等于指定的范圍。堆排序算法的時(shí)間復(fù)雜度是O(nlogn),空間復(fù)雜度是O(1)。

qPartialSort函數(shù)的函數(shù)原型

template <typename RandomAccessIterator>
void qPartialSort(RandomAccessIterator begin, RandomAccessIterator middle, RandomAccessIterator end);

template <typename RandomAccessIterator, typename LessThan>
void qPartialSort(RandomAccessIterator begin, RandomAccessIterator middle, RandomAccessIterator end, LessThan lessThan);

qPartialSort函數(shù)的功能參數(shù)

對(duì)從begin到end(不包括end)的元素進(jìn)行部分排序,使得從begin到middle(不包括middle)的元素是最小的或者最大的,而且是有序的,而從middle到end的元素是無序的。

第一個(gè)參數(shù)begin是指向序列開始位置的迭代器

第二個(gè)參數(shù)middle是指向序列中間位置的迭代器

第三個(gè)參數(shù)end是指向序列結(jié)束位置的迭代器

第四個(gè)參數(shù)lessThan是一個(gè)比較函數(shù)或者一個(gè)比較對(duì)象,它可以自定義排序的規(guī)則,它接受兩個(gè)元素作為參數(shù),返回一個(gè)布爾值,表示第一個(gè)元素是否小于第二個(gè)元素。如果沒有指定第四個(gè)參數(shù),qPartialSort函數(shù)會(huì)使用默認(rèn)的比較規(guī)則,即使用元素的<運(yùn)算符進(jìn)行比較。

qPartialSort函數(shù)的用法示例

  • 如果要對(duì)一個(gè)數(shù)組進(jìn)行部分排序,可以直接傳入數(shù)組的首地址,中間地址和尾地址作為參數(shù),例如:
int arr[] = {5, 3, 7, 1, 9, 4, 6, 8, 2};
qPartialSort(arr, arr + 3, arr + 9); // 對(duì)arr數(shù)組進(jìn)行部分排序,使得前三個(gè)元素是最小的,并且是有序的
  • 如果要對(duì)一個(gè)QList或者QVector進(jìn)行部分排序,可以使用它們的begin()和end()方法來獲取迭代器,例如:
QList<int> list;
list << 5 << 3 << 7 << 1 << 9 << 4 << 6 << 8 << 2;
qPartialSort(list.begin(), list.begin() + 3, list.end()); // 對(duì)list進(jìn)行部分排序,使得前三個(gè)元素是最小的,并且是有序的
  • 如果要對(duì)一個(gè)QMap或者QSet進(jìn)行部分排序,可以使用它們的keys()或者values()方法來獲取一個(gè)QList,然后對(duì)QList進(jìn)行部分排序,例如:
QMap<QString, int> map;
map["Alice"] = 90;
map["Bob"] = 80;
map["Charlie"] = 85;
map["David"] = 95;
QList<int> scores = map.values(); // 獲取map的值的列表
qPartialSort(scores.begin(), scores.begin() + 2, scores.end()); // 對(duì)scores進(jìn)行部分排序,使得前兩個(gè)元素是最小的,并且是有序的
  • 如果要自定義排序的規(guī)則,可以傳入一個(gè)比較函數(shù)或者一個(gè)比較對(duì)象作為第四個(gè)參數(shù),例如:
// 定義一個(gè)比較函數(shù),按照字符串的長(zhǎng)度進(jìn)行比較
bool compareByLength(const QString &a, const QString &b)
{
    return a.length() < b.length();
}

// 定義一個(gè)比較對(duì)象,按照學(xué)生的成績(jī)進(jìn)行比較
struct compareByScore
{
    bool operator()(const Student &a, const Student &b)
    {
        return a.score > b.score; // 降序排序
    }
};

QList<QString> words;
words << "apple" << "banana" << "orange" << "pear" << "grape";
qPartialSort(words.begin(), words.begin() + 2, words.end(), compareByLength); // 按照單詞的長(zhǎng)度進(jìn)行部分排序,使得前兩個(gè)元素是最短的,并且是有序的

QList<Student> students;
students << Student("Alice", 90) << Student("Bob", 80) << Student("Charlie", 85) << Student("David", 95);
qPartialSort(students.begin(), students.begin() + 2, students.end(), compareByScore()); // 按照學(xué)生的成績(jī)進(jìn)行部分排序,使得前兩個(gè)元素是最高的,并且是有序的

qPartialSort函數(shù)注意事項(xiàng)

  • begin,middle和end必須指向同一個(gè)序列,否則會(huì)導(dǎo)致未定義的行為。
  • begin,middle和end之間的元素必須能夠被交換,否則會(huì)導(dǎo)致編譯錯(cuò)誤。
  • begin,middle和end之間的元素必須能夠被比較,否則會(huì)導(dǎo)致編譯錯(cuò)誤或者運(yùn)行時(shí)錯(cuò)誤。
  • lessThan必須是一個(gè)嚴(yán)格弱序關(guān)系,也就是說,它必須滿足以下條件:
    • 對(duì)于任何元素x,lessThan(x, x)必須返回false。
    • 如果lessThan(x, y)返回true,那么lessThan(y, x)必須返回false。
    • 如果lessThan(x, y)和lessThan(y, z)都返回true,那么lessThan(x, z)也必須返回true。
  • qPartialSort函數(shù)的排序結(jié)果是不穩(wěn)定的,也就是說,如果序列中有相等的元素,它們的相對(duì)位置可能會(huì)改變。

以上就是qPartialSort函數(shù)的介紹,下面我們將介紹qHeapSort函數(shù)。

第五章:qHeapSort函數(shù)

qHeapSort函數(shù)是QT中提供的一個(gè)堆排序函數(shù),它使用堆排序算法,可以對(duì)任何可隨機(jī)訪問的序列進(jìn)行排序。堆排序算法的基本思想是,將序列視為一個(gè)完全二叉樹,然后構(gòu)建一個(gè)最大堆或者最小堆,也就是說,每個(gè)節(jié)點(diǎn)的值都大于或者小于它的子節(jié)點(diǎn)的值。然后,將堆的根節(jié)點(diǎn)(也就是最大或者最小的元素)與堆的最后一個(gè)節(jié)點(diǎn)交換,然后將堆的大小減一,再調(diào)整堆的結(jié)構(gòu),重復(fù)這個(gè)過程,直到堆的大小為零。堆排序算法的時(shí)間復(fù)雜度是O(nlogn),空間復(fù)雜度是O(1)。

qHeapSort函數(shù)的函數(shù)原型

template <typename RandomAccessIterator>
void qHeapSort(RandomAccessIterator begin, RandomAccessIterator end);

template <typename RandomAccessIterator, typename LessThan>
void qHeapSort(RandomAccessIterator begin, RandomAccessIterator end, LessThan lessThan);

qHeapSort函數(shù)的功能是參數(shù)

對(duì)從begin到end(不包括end)的元素進(jìn)行排序。

第一個(gè)參數(shù)begin是指向序列開始位置的迭代器

第二個(gè)參數(shù)end是指向序列結(jié)束位置的迭代器

第三個(gè)參數(shù)lessThan是一個(gè)比較函數(shù)或者一個(gè)比較對(duì)象,它可以自定義排序的規(guī)則,它接受兩個(gè)元素作為參數(shù),返回一個(gè)布爾值,表示第一個(gè)元素是否小于第二個(gè)元素。如果沒有指定第三個(gè)參數(shù),qHeapSort函數(shù)會(huì)使用默認(rèn)的比較規(guī)則,即使用元素的<運(yùn)算符進(jìn)行比較。

qHeapSort函數(shù)的用法示例

qSort函數(shù)的用法基本相同,只是qHeapSort函數(shù)的特點(diǎn)是,它可以在不使用額外空間的情況下,對(duì)序列進(jìn)行原地排序,也就是說,它不需要?jiǎng)?chuàng)建一個(gè)新的序列來存儲(chǔ)排序結(jié)果,而是直接在原序列上進(jìn)行操作。這樣就可以節(jié)省空間,提高效率。

代碼示例:

#include <QList>
#include <QString>
#include <QDebug>

// 定義一個(gè)學(xué)生類,包含姓名和成績(jī)兩個(gè)屬性
class Student
{
public:
    Student(const QString &name, int score) : name(name), score(score) {}
    QString name; // 姓名
    int score; // 成績(jī)
};

// 定義一個(gè)比較函數(shù),按照姓名進(jìn)行升序排序
bool compareByName(const Student &a, const Student &b)
{
    return a.name < b.name;
}

// 定義一個(gè)比較函數(shù),按照成績(jī)進(jìn)行降序排序
bool compareByScore(const Student &a, const Student &b)
{
    return a.score > b.score;
}


    // 創(chuàng)建一個(gè)學(xué)生的列表
    QList<Student> students;
    students << Student("Alice", 90) << Student("Bob", 80) << Student("Charlie", 85) << Student("David", 95);

    // 使用qHeapSort函數(shù)按照姓名進(jìn)行排序
    qHeapSort(students.begin(), students.end(), compareByName);

    // 打印排序后的結(jié)果
    qDebug() << "Sorted by name:";
    for (const Student &s : students)
    {
        qDebug() << s.name << s.score;
    }

    // 使用qHeapSort函數(shù)按照成績(jī)進(jìn)行排序
    qHeapSort(students.begin(), students.end(), compareByScore);

    // 打印排序后的結(jié)果
    qDebug() << "Sorted by score:";
    for (const Student &s : students)
    {
        qDebug() << s.name << s.score;
    }


?運(yùn)行這段代碼,可以得到以下輸出:

Sorted by name:
Alice 90
Bob 80
Charlie 85
David 95
Sorted by score:
David 95
Alice 90
Charlie 85
Bob 80

可以看到,qHeapSort函數(shù)的排序結(jié)果是不穩(wěn)定的,也就是說,姓名相同的學(xué)生的成績(jī)順序可能會(huì)改變,而且它可以在不使用額外空間的情況下,對(duì)序列進(jìn)行原地排序,也就是說,它不需要?jiǎng)?chuàng)建一個(gè)新的序列來存儲(chǔ)排序結(jié)果,而是直接在原序列上進(jìn)行操作。

qHeapSort函數(shù)的注意事項(xiàng)

  • begin和end必須指向同一個(gè)序列,否則會(huì)導(dǎo)致未定義的行為。
  • begin和end之間的元素必須能夠被交換,否則會(huì)導(dǎo)致編譯錯(cuò)誤。
  • begin和end之間的元素必須能夠被比較,否則會(huì)導(dǎo)致編譯錯(cuò)誤或者運(yùn)行時(shí)錯(cuò)誤。
  • lessThan必須是一個(gè)嚴(yán)格弱序關(guān)系,也就是說,它必須滿足以下條件:
    • 對(duì)于任何元素x,lessThan(x, x)必須返回false。
    • 如果lessThan(x, y)返回true,那么lessThan(y, x)必須返回false。
    • 如果lessThan(x, y)和lessThan(y, z)都返回true,那么lessThan(x, z)也必須返回true。
  • qHeapSort函數(shù)的排序結(jié)果是不穩(wěn)定的,也就是說,如果序列中有相等的元素,它們的相對(duì)位置可能會(huì)改變。

以上就是qHeapSort函數(shù)的介紹,下面我們將介紹qLowerBound和qUpperBound函數(shù)。

第六章:qLowerBound和qUpperBound函數(shù)

qLowerBound和qUpperBound函數(shù)是QT中提供的兩個(gè)查找函數(shù),它們可以在一個(gè)有序的序列中,查找一個(gè)給定的元素的下界和上界。下界是指序列中第一個(gè)不小于給定元素的位置,上界是指序列中第一個(gè)大于給定元素的位置。它們可以指定一個(gè)比較函數(shù)或者一個(gè)比較對(duì)象,來自定義查找的規(guī)則。它們的查找效率是對(duì)數(shù)級(jí)別的,也就是說,它們使用二分查找算法,每次查找都可以將查找范圍縮小一半。

qLowerBound和qUpperBound函數(shù)的函數(shù)原型

template <typename ForwardIterator, typename T>
ForwardIterator qLowerBound(ForwardIterator begin, ForwardIterator end, const T &value);

template <typename ForwardIterator, typename T, typename LessThan>
ForwardIterator qLowerBound(ForwardIterator begin, ForwardIterator end, const T &value, LessThan lessThan);

template <typename ForwardIterator, typename T>
ForwardIterator qUpperBound(ForwardIterator begin, ForwardIterator end, const T &value);

template <typename ForwardIterator, typename T, typename LessThan>
ForwardIterator qUpperBound(ForwardIterator begin, ForwardIterator end, const T &value, LessThan lessThan);

qLowerBound和qUpperBound函數(shù)的功能和參數(shù)

分別在從begin到end(不包括end)的元素中,查找value的下界和上界。

第一個(gè)參數(shù)begin是指向序列開始位置的迭代器

第二個(gè)參數(shù)end是指向序列結(jié)束位置的迭代器

第三個(gè)參數(shù)value是要查找的元素

第四個(gè)參數(shù)lessThan是一個(gè)比較函數(shù)或者一個(gè)比較對(duì)象,它可以自定義查找的規(guī)則,它接受兩個(gè)元素作為參數(shù),返回一個(gè)布爾值,表示第一個(gè)元素是否小于第二個(gè)元素。如果沒有指定第四個(gè)參數(shù),qLowerBound和qUpperBound函數(shù)會(huì)使用默認(rèn)的比較規(guī)則,即使用元素的<運(yùn)算符進(jìn)行比較。

qLowerBound和qUpperBound函數(shù)的用法示例

  • 如果要在一個(gè)數(shù)組中查找一個(gè)元素的下界和上界,可以直接傳入數(shù)組的首地址和尾地址作為參數(shù),例如:
int arr[] = {1, 2, 3, 3, 3, 4, 5};
int *lower = qLowerBound(arr, arr + 7, 3); // 查找3的下界
int *upper = qUpperBound(arr, arr + 7, 3); // 查找3的上界
qDebug() << "Lower bound of 3 is" << lower - arr; // 輸出3的下界的索引
qDebug() << "Upper bound of 3 is" << upper - arr; // 輸出3的上界的索引
  • 如果要在一個(gè)QList或者QVector中查找一個(gè)元素的下界和上界,可以使用它們的begin()和end()方法來獲取迭代器,例如:
QList<int> list;
list << 1 << 2 << 3 << 3 << 3 << 4 << 5;
QList<int>::iterator lower = qLowerBound(list.begin(), list.end(), 3); // 查找3的下界
QList<int>::iterator upper = qUpperBound(list.begin(), list.end(), 3); // 查找3的上界
qDebug() << "Lower bound of 3 is" << lower - list.begin(); // 輸出3的下界的索引
qDebug() << "Upper bound of 3 is" << upper - list.begin(); // 輸出3的上界的索引
  • 如果要在一個(gè)QMap或者QSet中查找一個(gè)元素的下界和上界,可以使用它們的keys()或者values()方法來獲取一個(gè)QList,然后在QList中查找,例如:
QMap<QString, int> map;
map["Alice"] = 90;
map["Bob"] = 80;
map["Charlie"] = 85;
map["David"] = 95;
QList<int> scores = map.values(); // 獲取map的值的列表
qSort(scores.begin(), scores.end()); // 對(duì)scores進(jìn)行排序
QList<int>::iterator lower = qLowerBound(scores.begin(), scores.end(), 85); // 查找85的下界
QList<int>::iterator upper = qUpperBound(scores.begin(), scores.end(), 85); // 查找85的上界
qDebug() << "Lower bound of 85 is" << lower - scores.begin(); // 輸出85的下界的索引
qDebug() << "Upper bound of 85 is" << upper - scores.begin(); // 輸出85的上界的索引

第七章:總結(jié)

本文介紹了QT中的幾種常用的排序函數(shù),包括qSort,qStableSort,qPartialSort,qHeapSort,qLowerBound和qUpperBound,它們可以對(duì)QT中的一些容器類中的元素進(jìn)行排序或者查找。

下面我們將比較一下不同排序函數(shù)的優(yōu)缺點(diǎn),以及給出一些使用建議:

  • qSort函數(shù)是一個(gè)通用的排序函數(shù),它使用快速排序算法,可以對(duì)任何可隨機(jī)訪問的序列進(jìn)行排序。它的優(yōu)點(diǎn)是,它的平均時(shí)間復(fù)雜度是O(nlogn),空間復(fù)雜度是O(logn),效率較高。它的缺點(diǎn)是,它的最壞情況下的時(shí)間復(fù)雜度是O(n^2),效率較低。另外,它的排序結(jié)果是不穩(wěn)定的,也就是說,如果序列中有相等的元素,它們的相對(duì)位置可能會(huì)改變。因此,如果要對(duì)一個(gè)序列進(jìn)行排序,可以使用qSort函數(shù),但是要注意避免最壞情況的發(fā)生,以及考慮是否需要保持元素的相對(duì)位置。
  • qStableSort函數(shù)是一個(gè)穩(wěn)定的排序函數(shù),它使用歸并排序算法,可以對(duì)任何可隨機(jī)訪問的序列進(jìn)行排序。它的優(yōu)點(diǎn)是,它的時(shí)間復(fù)雜度是O(nlogn),效率較高。另外,它的排序結(jié)果是穩(wěn)定的,也就是說,如果序列中有相等的元素,它們的相對(duì)位置不會(huì)改變。這一點(diǎn)在一些場(chǎng)景中是很重要的,例如,如果要對(duì)一個(gè)學(xué)生的列表按照姓名進(jìn)行排序,然后再按照成績(jī)進(jìn)行排序,如果使用qSort函數(shù),那么姓名相同的學(xué)生的成績(jī)順序可能會(huì)被打亂,而如果使用qStableSort函數(shù),那么姓名相同的學(xué)生的成績(jī)順序會(huì)保持不變。它的缺點(diǎn)是,它的空間復(fù)雜度是O(n),需要額外的空間來存儲(chǔ)排序結(jié)果。因此,如果要對(duì)一個(gè)序列進(jìn)行排序,而且需要保持元素的相對(duì)位置,可以使用qStableSort函數(shù),但是要注意空間的消耗。
  • qPartialSort函數(shù)是一個(gè)部分排序函數(shù),它使用堆排序算法,可以對(duì)任何可隨機(jī)訪問的序列進(jìn)行部分排序。它的優(yōu)點(diǎn)是,它可以指定一個(gè)范圍,只對(duì)序列中的這個(gè)范圍內(nèi)的元素進(jìn)行排序,而不影響其他元素。這樣就可以節(jié)省時(shí)間,提高效率。它的缺點(diǎn)是,它的排序結(jié)果是不穩(wěn)定的,也就是說,如果序列中有相等的元素,它們的相對(duì)位置可能會(huì)改變。另外,它的時(shí)間復(fù)雜度是O(nlogn),空間復(fù)雜度是O(1),效率和空間都不是最優(yōu)的。因此,如果要對(duì)一個(gè)序列進(jìn)行部分排序,可以使用qPartialSort函數(shù),但是要注意元素的相對(duì)位置,以及是否有更好的算法。
  • qHeapSort函數(shù)是一個(gè)堆排序函數(shù),它使用堆排序算法,可以對(duì)任何可隨機(jī)訪問的序列進(jìn)行排序。它的優(yōu)點(diǎn)是,它可以在不使用額外空間的情況下,對(duì)序列進(jìn)行原地排序,也就是說,它不需要?jiǎng)?chuàng)建一個(gè)新的序列來存儲(chǔ)排序結(jié)果,而是直接在原序列上進(jìn)行操作。這樣就可以節(jié)省空間,提高效率。它的缺點(diǎn)是,它的排序結(jié)果是不穩(wěn)定的,也就是說,如果序列中有相等的元素,它們的相對(duì)位置可能會(huì)改變。另外,它的時(shí)間復(fù)雜度是O(nlogn),空間復(fù)雜度是O(1),效率和空間都不是最優(yōu)的。因此,如果要對(duì)一個(gè)序列進(jìn)行排序,而且不需要保持元素的相對(duì)位置,也不需要額外的空間,可以使用qHeapSort函數(shù),但是要注意是否有更好的算法。
  • qLowerBound和qUpperBound函數(shù)是兩個(gè)查找函數(shù),它們可以在一個(gè)有序的序列中,查找一個(gè)給定的元素的下界和上界。它們的優(yōu)點(diǎn)是,它們的查找效率是對(duì)數(shù)級(jí)別的,也就是說,它們使用二分查找算法,每次查找都可以將查找范圍縮小一半。這樣就可以快速地找到目標(biāo)元素。它們的缺點(diǎn)是,它們的查找結(jié)果是一個(gè)迭代器,它可以用來訪問或者修改序列中的元素,也可以用來計(jì)算元素的位置或者個(gè)數(shù),但是它不能直接用來判斷元素是否存在于序列中,也不能直接用來獲取元素的值。因此,如果要在一個(gè)有序的序列中,查找一個(gè)給定的元素的下界和上界,可以使用qLowerBound和qUpperBound函數(shù),但是要注意如何使用查找結(jié)果。

?文章來源地址http://www.zghlxwxcb.cn/news/detail-771613.html

到了這里,關(guān)于【QT深入理解】QT中的幾種常用的排序函數(shù)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 常見的幾種排序

    常見的幾種排序

    ??博主主頁: @??. 一懷明月?? ????? 專欄系列: 線性代數(shù),C初學(xué)者入門訓(xùn)練,題解C,C的使用文章,「初學(xué)」C++ ?? 座右銘: “不要等到什么都沒有了,才下定決心去做” ??????大家覺不錯(cuò)的話,就懇求大家點(diǎn)點(diǎn)關(guān)注,點(diǎn)點(diǎn)小愛心,指點(diǎn)指點(diǎn)?????? 目錄 冒泡

    2024年02月15日
    瀏覽(16)
  • 常見的幾種排序算法

    常見的幾種排序算法

    目錄 一、插入排序 1、直接插入排序 1.1、排序方法 1.2、圖解分析 1.3、代碼實(shí)現(xiàn) 2、希爾排序 2.1、排序方法 2.2、圖解分析 2.3、代碼實(shí)現(xiàn) 二、選擇排序 1、直接選擇排序 1.1、排序方法 1.2、圖解分析 1.3、代碼實(shí)現(xiàn) 2、堆排序 2.1、排序方法 2.2、圖解分析 2.3、代碼實(shí)現(xiàn) 三、交換

    2024年02月09日
    瀏覽(22)
  • 常見的幾種排序方式

    常見的幾種排序方式

    排序: 所謂排序,就是使一串記錄,按照其中的某個(gè)或某些的大小,遞增或遞減的排列起來的操作 穩(wěn)定性: 假定在待排序的記錄序列中,存在多個(gè)具有相同的的記錄,若經(jīng)過排序,這些記錄的相對(duì)次序保持不變,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,而在

    2024年02月07日
    瀏覽(21)
  • 【Linux操作系統(tǒng)】深入理解系統(tǒng)調(diào)用中的read和write函數(shù)

    【Linux操作系統(tǒng)】深入理解系統(tǒng)調(diào)用中的read和write函數(shù)

    在操作系統(tǒng)中,系統(tǒng)調(diào)用是用戶程序與操作系統(tǒng)之間進(jìn)行交互的重要方式。其中,read和write函數(shù)是常用的系統(tǒng)調(diào)用函數(shù),用于在用戶程序和操作系統(tǒng)之間進(jìn)行數(shù)據(jù)的讀取和寫入。本文將深入介紹read和write函數(shù)的工作原理、用法以及示例代碼,以幫助讀者更好地理解和應(yīng)用這兩

    2024年02月13日
    瀏覽(20)
  • 【MySql】 深入理解SQL中的日期處理:NVL和TIMESTAMPDIFF函數(shù)的應(yīng)用

    還有多少個(gè)十年 能勇敢做熱血青年 還有多少個(gè)十年 能堅(jiān)持當(dāng)初的信念 還有多少個(gè)十年 能不忘懷回憶點(diǎn)點(diǎn) ??????????????????????? 《還有多少個(gè)十年》 在處理數(shù)據(jù)庫(kù)時(shí),日期和時(shí)間的操作是日常任務(wù)中最常見且關(guān)鍵的部分之一。無論是過濾數(shù)據(jù)、生成報(bào)告還是執(zhí)

    2024年04月25日
    瀏覽(19)
  • Hive的幾種排序方式、區(qū)別,使用場(chǎng)景

    Hive 支持兩種主要的排序方式: ORDER BY 和 SORT BY 。除此之外,還有 DISTRIBUTE BY 和 CLUSTER BY 語句,它們也在排序和數(shù)據(jù)分布方面發(fā)揮作用。 1. ORDER BY ORDER BY 在 Hive 中用于對(duì)查詢結(jié)果進(jìn)行全局排序,確保結(jié)果集是全局有序的。但是,使用 ORDER BY 時(shí),Hive 會(huì)將所有數(shù)據(jù)集中到一個(gè)

    2024年02月02日
    瀏覽(24)
  • Java實(shí)現(xiàn)字符串排序的幾種方式

    創(chuàng)建實(shí)體類(此處引入了lombok) 一、使用List集合中自帶的sort方法(字符串的位數(shù)保持一致,不一致的情況可以在左邊補(bǔ)0,也可以使用String.format()方法補(bǔ)全) 1、在對(duì)象排序中使用 2、在字符串排序中使用 二、使用Stream流(字符串的位數(shù)保持一致,不一致的情況可以在左邊補(bǔ)

    2024年02月11日
    瀏覽(19)
  • Java List 按指定條件排序的幾種方式

    ??在 Java 項(xiàng)目中,可能會(huì)遇到給出一些條件,將 List 元素按照給定條件進(jìn)行排序的情況。如下述場(chǎng)景。 一、排序場(chǎng)景 ??List 保存著一組亂序排列的字符串,Map 中保存著該組字符串各自的優(yōu)先級(jí)。優(yōu)先級(jí)數(shù)字從低到高表示優(yōu)先級(jí)依次遞減。要求將 List 中的字符串,按照優(yōu)

    2024年02月13日
    瀏覽(28)
  • Qt 播放音頻文件的幾種方式

    Qt 播放音頻文件的幾種方式

    : Qt 、 QSound 、 QSoundEffect 、 QMediaPlayer 、 multimedia 這篇文章至少拖了有一兩個(gè)月了,這不陽了,在家實(shí)在是難受的要死,無心處理工作的事情,那就寫寫博客吧,因?yàn)轫?xiàng)目中需要用到播放音頻的功能,CV了部分代碼,這里就簡(jiǎn)單的扯扯我對(duì) QSound 、 QSoundEffect 和 QMediaP

    2024年02月11日
    瀏覽(18)
  • Qt 多線程的幾種實(shí)現(xiàn)方式

    Qt 多線程的幾種實(shí)現(xiàn)方式

    Qt多線程的實(shí)現(xiàn)方式有: 1. 繼承QThread類,重寫run()方法 2. 使用moveToThread將一個(gè)繼承QObject的子類移至線程,內(nèi)部槽函數(shù)均在線程中執(zhí)行 3. 使用QThreadPool,搭配QRunnable(線程池) 4. 使用QtConcurrent(線程池) 為什么要用線程池? 創(chuàng)建和銷毀線程需要和OS交互,少量線程影響不大,

    2024年02月15日
    瀏覽(22)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包