演算法導論_第八章_線性時間排序
演算法導論_第八章_線性時間排序
排序演算法的下界
決策樹模型
決策樹是一顆完全二叉樹
決策樹的每個節點代表需要比較的兩個數,葉節點為一個數的排序。所以任何正確的排
序,n個元
素的n!個排列情況都應該出現在葉節點上。
比較排序的最壞情況出現在比較次數為決策樹的高度,而決策數的高度
h<=lg(n!)=Ω(n*lg(n))
堆排序和歸併排序都是漸進最優的比較排序演算法
其執行時間上界為O(n*lg(n))
計數排序:
基本思想:
對於每一個輸入的元素x,確定小於x的元素個數。利用這一資訊可以直接把x放到它在輸出
陣列中的位置上。
下面來看程式碼:
/*************************************************************************
> File Name: counting_sort.cpp
> Author:chudongfang
> Mail:1149669942@qq.com
> Created Time: 2016年06月29日 星期三 08時42分35秒
************************************************************************/
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include <algorithm>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
void counting_sort(int a[],int b[],int n,int k);
int main(int argc,char *argv[])
{
int a[100],b[100];
int n;
int max=-INF;
printf("please input the number of array:");
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
if(max<a[i]) max=a[i];//確定輸入元素的最大值,便於開闢c陣列
}
counting_sort(a,b,n,max);
for(int i=1;i<=n;i++)
printf("%d ",b[i]);
return 0;
}
//a陣列表示要排序的陣列,
//b表示排序過後的陣列,
//c表示a陣列元素在b陣列中的位置。
void counting_sort(int a[],int b[],int n,int k)
{
int c[1000];
for(int i=0;i<=k;i++)
c[i]=0;
for(int i=1;i<=n;i++)
c[a[i]]++;//初始化為1代表有1個元素與其相等,為其本身
/*******important**************/
for(int i=1;i<=k;i++)//確定比其小或等於的元素的個數
c[i]+=c[i-1];
for(int j=n;j>=1;j--)
{
b[c[a[j]]]=a[j];//確定位置
c[a[j]]--;//若有重複,則位置減1
//在這裡,其保證瞭如果多個元素相同,其在b陣列中的順序與其
//在a陣列中的順序相同,就保證了其穩定性。
}
/*****************************/
}
據計算其時間複雜度為Θ(n)
計數排序不涉及到比較,所以其脫離比較模型,時間複雜度可以降低很多,再者其具有
穩定性,對於附帶衛星資料來說,比較重要。
不過當k非常大時,可能導致記憶體空間利用過多。
基數排序:
排序思想:
假定要對一個有10位的十進位制的數排序,那麼就從最低有效位開始進行排序,就是先對個位數進行排序,
然後十位,百位……直到排序完成,在排序過程中衛星資料順序不變,所以需要穩定的排序演算法。
這裡可以採用基數排序
下面上具體程式碼:
/*************************************************************************
> File Name: radix_sort.cpp
> Author:chudongfang
> Mail:1149669942@qq.com
> Created Time: 2016年06月29日 星期三 09時46分44秒
************************************************************************/
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include <algorithm>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
typedef struct node
{
int ge;
int shi;
int bai;
}NODE;
void counting_sort_ge(NODE a[],NODE b[],int n,int k);
void counting_sort_shi(NODE a[],NODE b[],int n,int k);
void counting_sort_bai(NODE a[],NODE b[],int n,int k);
int main(int argc,char *argv[])
{
NODE a[100];
NODE b[100];
a[1].ge=1;
a[1].shi=2;
a[1].bai=3;
a[2].ge=2;
a[2].shi=2;
a[2].bai=2;
a[3].ge=7;
a[3].shi=2;
a[3].bai=3;
a[4].ge=3;
a[4].shi=1;
a[4].bai=2;
a[5].ge=5;
a[5].shi=2;
a[5].bai=3;
int n=5,d=3;
int max_ge=7;
int max_shi=2;
int max_bai=3;
counting_sort_ge(a,b,n,max_ge);
counting_sort_shi(b,a,n,max_shi);
counting_sort_bai(a,b,n,max_bai);
for (int i = 1; i <=5; ++i)
{
printf("%d%d%d\n",b[i].bai,b[i].shi,b[i].ge);
}
return 0;
}
void counting_sort_ge(NODE a[],NODE b[],int n,int k)
{
int c[1000];
for(int i=0;i<=k;i++)
c[i]=0;
for(int i=1;i<=n;i++)
c[a[i].ge]++;//初始化為1代表有1個元素與其相等,為其本身
/*******important**************/
for(int i=1;i<=k;i++)//確定比其小或等於的元素的個數
c[i]+=c[i-1];
for(int j=n;j>=1;j--)
{
b[c[a[j].ge]]=a[j];//確定位置
c[a[j].ge]--;//若有重複,則位置減1
//在這裡,其保證瞭如果多個元素相同,其在b陣列中的順序與其
//在a陣列中的順序相同,就保證了其穩定性。
}
/*****************************/
}
void counting_sort_shi(NODE a[],NODE b[],int n,int k)
{
int c[1000];
for(int i=0;i<=k;i++)
c[i]=0;
for(int i=1;i<=n;i++)
c[a[i].shi]++;//初始化為1代表有1個元素與其相等,為其本身
/*******important**************/
for(int i=1;i<=k;i++)//確定比其小或等於的元素的個數
c[i]+=c[i-1];
for(int j=n;j>=1;j--)
{
b[c[a[j].shi]]=a[j];//確定位置
c[a[j].shi]--;//若有重複,則位置減1
//在這裡,其保證瞭如果多個元素相同,其在b陣列中的順序與其
//在a陣列中的順序相同,就保證了其穩定性。
}
/*****************************/
}
void counting_sort_bai(NODE a[],NODE b[],int n,int k)
{
int c[1000];
for(int i=0;i<=k;i++)
c[i]=0;
for(int i=1;i<=n;i++)
c[a[i].bai]++;//初始化為1代表有1個元素與其相等,為其本身
/*******important**************/
for(int i=1;i<=k;i++)//確定比其小或等於的元素的個數
c[i]+=c[i-1];
for(int j=n;j>=1;j--)
{
b[c[a[j].bai]]=a[j];//確定位置
c[a[j].bai]--;//若有重複,則位置減1
//在這裡,其保證瞭如果多個元素相同,其在b陣列中的順序與其
//在a陣列中的順序相同,就保證了其穩定性。
}
/*****************************/
}
其利用了計數排序,對n個d位數來說
其時間複雜度為:Θ(d*(n+k))
d為常數時且k=O(n),基數排序具有線性的時間代價
由於其不是原址排序,所以其會耗費大量記憶體空間,當記憶體非常珍貴的情況下,利用快排
桶排序:
桶排序假設輸入的資料服從均勻分佈,平均情況下,其時間代價為O(n)
桶排序將[0,1)區間劃分為n個相同大小的子區間上,或稱為桶,然後將n個輸入數分別放到各個桶中,先對
桶中的數進行排序,然後遍歷每個桶,按照次序把各個桶中的元素列出來。
下面看具體程式碼:
/*************************************************************************
> File Name: bucket_sort.cpp
> Author:chudongfang
> Mail:1149669942@qq.com
> Created Time: 2016年06月29日 星期三 10時50分26秒
************************************************************************/
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include <algorithm>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
void bucket_sort(float a[],float b[][100],int num[],int n,float max);
int main(int argc,char *argv[])
{
float a[100];//要排序的陣列
float b[100][100];//桶
int num[100];//桶內的元素
int n;
float max=-INF;
memset(num,0,sizeof(num));//賦值清零
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%f",&a[i]);
if(a[i]>max) max=a[i];//找到最大值
}
bucket_sort(a,b,num,n,max);//桶排序
for(int i=1;i<=n;i++)
{
for(int j=1;j<=num[i];j++)
printf("%g ",b[i][j]);
}
return 0;
}
void bucket_sort(float a[],float b[][100],int num[],int n,float max)
{
int i,j,k;
for(i=1;i<=n;i++)
{
j=(int)(a[i]/max*n);//找到其應該放入桶的下標
if(!j) j++; //如果為0,則變為1
num[j]++; //計數器加1
/*************插入排序_部分功能********************/
for(k=num[j];k>1&&b[j][k-1]>a[i];k--)
b[j][k]=b[j][k-1];
b[j][k]=a[i];
}
}
桶排序效率分析:
桶排序的時間代價為
T(n)=Θ(n)+sum(O(n[i]^2))
最後求得其時間複雜度為:Θ(n)
即使輸入資料不服從平均分佈桶排序也仍然可以線上性時間內完成。只要輸入資料滿足所有桶的大小的平
方和與總的元素呈線性關係。
相關文章
- 線性時間構造最大堆
- 排序演算法:堆排序的實現和時間複雜度分析排序演算法時間複雜度
- 快速排序平均時間複雜度O(nlogn)的推導排序時間複雜度
- 演算法概論 第八章第八題演算法
- 時間複雜度為 O(nlogn) 的排序演算法時間複雜度排序演算法
- 時間複雜度為O(nlogn)的排序演算法時間複雜度排序演算法
- 【Java資料結構與演算法】第八章 快速排序、歸併排序和基數排序Java資料結構演算法排序
- 演算法-圖論-拓撲排序演算法圖論排序
- 時間複雜度為 O (n^2) 的排序演算法時間複雜度排序演算法
- 時間複雜度為 O(n^2) 的排序演算法時間複雜度排序演算法
- 計量經濟學導論08:平穩時間序列
- 【演算法學習筆記】Meissel-Lehmer 演算法 (亞線性時間找出素數個數)演算法筆記
- List根據時間排序排序
- js根據時間排序JS排序
- Java實現:排序演算法--時間複雜度為O(n² )Java排序演算法時間複雜度
- Lamport時間戳與一致性演算法LAMP時間戳演算法
- 演算法導論-第6章演算法
- 線性迴歸推導
- 線性建堆法與堆排序排序
- 實時插入排序演算法排序演算法
- 【C語言學習筆記】再論快速排序的重要性與妙用空間C語言筆記排序
- 論文---時間序列----TimeLLM
- 論文---時間序列--DLinear
- 學演算法要讀《演算法導論》嗎?演算法
- 時間線自制
- 線性時間選擇(含平均情況O(n)和最壞情況O(n)演算法)演算法
- Map集合的按時間排序方法排序
- swift4.0 物件資料來源根據屬性分組,時間排序Swift物件排序
- 檔案時間屬性
- 《快速排序》引發關於演算法的討論排序演算法
- 氣泡排序時間複雜度分析排序時間複雜度
- 時間線測試
- 線性迴歸演算法演算法
- 用一個測試類簡化排序演算法時間複雜度的研究排序演算法時間複雜度
- 【演算法】【線性表】【陣列】買賣股票的最佳時機演算法陣列
- 演算法分析__時間估算演算法
- 如何不用演算法對陣列進行(0時間複雜度,0空間複雜度)排序?演算法陣列時間複雜度排序
- 演算法資料結構 | 圖論基礎演算法——拓撲排序演算法資料結構圖論排序
- SAS EM(六)時間序列理論