日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

C++STL函數和排序算法的快排以及歸并排序詳解_C 語言

作者:披星戴月的賈維斯 ? 更新時間: 2022-05-03 編程語言

一、隊列是什么?

頭文件queue主要包括循環隊列queue和優先隊列priority_queue兩個容器。

像棧一樣,隊列(queue)也是一種線性表,它的特性是先進先出,插入在一端,刪除在另一端。就像排隊一樣,剛來的人入隊(push)要排在隊尾(rear),每次出隊(pop)的都是隊首(front)的人。

就像管道一樣先進先出。

隊列的相關概念:

1.隊頭與隊尾: 允許元素插入的一端稱為隊尾,允許元素刪除的一端稱為隊頭。

2.入隊:隊列的插入操作。

3.出隊:隊列的刪除操作。

隊列的聲明:? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

#include
#include//隊列的頭文件
using namespace std;
int main ()
{
    queue a;//隊列的聲明
    priority_queue q;  //大根堆
    priority_queue, greater> q;   // 小根堆
    struct Rec//結構體rec中大根堆要定義小于號,小根堆要定義大于號
    {
        int x,y;
        bool operator >(const Rec &t) const
        {
            return x > t.x;
        }
    };
    queue q;
    return 0;
}

(1)循環隊列 queue

  • push ? ?// 從隊尾插入
  • pop ? ? // 從隊頭彈出
  • front ? // 返回隊頭元素
  • back ? ?// 返回隊尾元素

(2)優先隊列 priority_queue

  • ?push ? ?// 把元素插入堆
  • pop ? ? // 刪除堆頂元素
  • top ? ? // 查詢堆頂元素(最大值)
#include
#include//隊列的頭文件
using namespace std;
int main ()
{
    queue a;//隊列的聲明
    a.push(1);//在隊頭插入一個新元素;
    a.pop();//彈出隊尾元素
    a.front();//返回隊頭
    a.back();//返回隊尾
    //優先隊列中
    a.top();//取最大值
    a.pop();//去最大值
    //注意:隊列沒有clear 函數
    q = queue();//重新初始化一個隊列,起到清除隊列的效果。
    return 0;
}

二、排序算法

1.快速排序

主要思想:分治

解題步驟:

1、確定分界點,如果數據量比較大,到一百萬之類的,建議分界點取中間。

2、調整區間,分為>=x,和<=x兩個部分。

3、遞歸處理左右兩段。

##include
using namespace std;
const int N = 1e6 + 10;
int q[N];
int n;
void quick_sort(int q[], int l, int r)
{
    if( l >= r) return;//判斷數組是否只有1位數或為空
    int x = q[l + r >> 1], i = l - 1, j = r + 1;//設置分界點以及i,j兩個“指針”;
    while( i < j)
    {
        do i++; while(q[i] < x);
        do j--; while(q[j] > x);
        if(i < j) //特判如果i,j兩指針都不滿足i<=x,j>=x這個條件時,交換兩個值
        {
            int t= q[i];
            q[i] = q[j];
            q[j] =t;
        }
    }
    quick_sort(q,l,j);
    quick_sort(q,j+1,r);//遞歸處理左右兩段
}
int main ()
{
    scanf("%d", &n);
    for(int i = 0; i < n; i++) scanf("%d", &q[i]);
    quick_sort(q, 0, n - 1);
    for(int i = 0; i < n; i++) printf("%d ",q[i]);
    return 0;
}

快速排序例題:第k個數?

#include
using namespace std;
int n , k;
const int N = 100010;
int q[N];
int quick_sort(int l, int r,int k)
{
    if(l == r) return q[l];//特判如果只有一個數,返回這個數
    int x = q[l + r >> 1], i = l - 1, j = r + 1;// 
    while(i < j)
    {
        do i++; while(q[i] < x);
        do j--; while(q[j] > x);
        if(i < j) swap(q[i], q[j]);
    }
    int sl = j - l + 1;
    if(k <= sl) return quick_sort(l, j , k);//遞歸左邊
    return quick_sort(j + 1, r, k - sl);//遞歸右邊
}
int main ()
{
    cin >> n >> k;
    for(int i = 0; i < n; i++) scanf("%d", &q[i]);
    cout << quick_sort(0, n - 1, k) << endl;
    return 0;
}

2、歸并排序

主要思想:分治

1、確定分界點mid = (l+r)/2。

2、遞歸排序左右兩邊left,right。

3、歸并、合二為一(難點)。

??#include
using namespace std;
const int N = 100010;
int n;
int q[N], tmp[N];
void merge_sort(int q[], int l, int r)
{
    if(l >= r) return;// 特判區間內如果只有一個數或者為空時,直接return;
    int mid = l + r >> 1;//確定分界點mid
    merge_sort(q, l, mid), merge_sort(q, mid+1, r);//遞歸排序兩邊
    int k = 0, i = l, j = mid + 1;
    while(i <= mid && j <= r)//歸并,合并兩邊
        if(q[i] <= q[j]) tmp[k++] = q[i++];
        else tmp[k++] = q[j++];
        while(i <= mid) tmp[k++] = q[i++];//再次查看左邊區間是否還有剩余
        while(j <= r) tmp[k++] = q[j++];//再次查看右邊區間是否還有剩余
        for (i = l, j = 0; i <= r; i++, j++) q[i] = tmp[j];//把tmp[i] 存到q[j]里
}
int main ()
{
    scanf("%d", &n);
    for(int i = 0; i < n; i++) scanf("%d", &q[i]);
    merge_sort(q, 0, n - 1);
    for(int i = 0; i < n; i++) printf("%d ", q[i]);
    return 0;
}

總結

原文鏈接:https://blog.csdn.net/qq_62662919/article/details/123160725

欄目分類
最近更新