『壹』 常見的排序演算法哪個效率最高
快速排序法。
『貳』 內存足夠大,用哪種排序演算法好
很可能答案是快速排序,基於以下幾點理由:
1.快速排序的概率時間是接近o(n)的,是幾種 n*logn中最好的
2.快速排序的空間復雜度是 o(n)的,優於歸並的 o(2*n)
3.內存的好處就是讀取存取速度快,而恰恰快排是依賴R/W的排序
『叄』 海量數據排序,內存足夠大,用哪種排序演算法好為什麼
歸並排序和堆排序吧,最壞時間復雜度最低的兩個,個人感覺;你說了是內存足夠大,不考慮空間復雜度,如果考慮的話我覺得是堆排序
『肆』 數據結構,排序演算法中使用內存量最大的是
你好!
幾個排序演算法的存儲空間都差不多吧,是復雜度才有比較意義啊
如果對你有幫助,望採納。
『伍』 的排序方法中,採用哪種方法最好
這個各取所需,根據不同的需要選取不同的方法。
我們通常所說的排序演算法往往指的是內部排序演算法,即數據記錄在內存中進行排序。
排序演算法大體可分為兩種:
一種是比較排序,時間復雜度O(nlogn) ~ O(n^2),主要有:冒泡排序,選擇排序,插入排序,歸並排序,堆排序,快速排序等。
另一種是非比較排序,時間復雜度可以達到O(n),主要有:計數排序,基數排序,桶排序等。
排序演算法穩定性的簡單形式化定義為:如果Ai = Aj,排序前Ai在Aj之前,排序後Ai還在Aj之前,則稱這種排序演算法是穩定的。通俗地講就是保證排序前後兩個相等的數的相對順序不變。
對於不穩定的排序演算法,只要舉出一個實例,即可說明它的不穩定性;而對於穩定的排序演算法,必須對演算法進行分析從而得到穩定的特性。需要注意的是,排序演算法是否為穩定的是由具體演算法決定的,不穩定的演算法在某種條件下可以變為穩定的演算法,而穩定的演算法在某種條件下也可以變為不穩定的演算法。
例如,對於冒泡排序,原本是穩定的排序演算法,如果將記錄交換的條件改成A[i] >= A[i + 1],則兩個相等的記錄就會交換位置,從而變成不穩定的排序演算法。
其次,說一下排序演算法穩定性的好處。排序演算法如果是穩定的,那麼從一個鍵上排序,然後再從另一個鍵上排序,前一個鍵排序的結果可以為後一個鍵排序所用。基數排序就是這樣,先按低位排序,逐次按高位排序,低位排序後元素的順序在高位也相同時是不會改變的。
『陸』 數據結構排序中快速排序和基數排序哪個需要的內存量最大
顯然是快速排序啦!
循環遞歸的內存開銷可想而知= =!看看數據結構或者演算法分析吧!
希望對你有幫助!
『柒』 幾種常用的排序演算法比較
排序,從小大,0坐標的在下面,即排序後小的在下面,大的在上面。
1,冒泡Bubble:從第0個開始,一直往上,與相鄰的元素比較,如果下面的大,則交換。
Analysis:
Implementation:
void BubbleSort(int *pData, int iNum)
2,插入Insertion:與打撲克牌時整理牌很想像,假定第一張牌是有序的,從第二張牌開始,拿出這張牌來,往下比較,如果有比這張牌大的,則把它撥到上一個位置,直到找到比手上的這張更小的(或到頂了),
則把手上的這張牌插入到這張更小的牌的後面。
Analysis:
Implementation:
void InsertionSort(int *list, int length)
{
int i, j, temp;
for (i = 1; i < length; i++)
{
temp = list[i];
j = i - 1;
while ((j >= 0) && (list[j] > temp))
{
list[j+1] = list[j];
j--;
}
list[j+1] = temp;
}
}
3,選擇Selection:從所有元素中找到最小的放在0號位置,從其它元素(除了0號元素)中再找到最小的,放到1號位置,......。
Analysis:
Implementation:
void SelectionSort(int data[], int count)
{
int i, j, min, temp;
for (i = 0; i < count - 1; i++)
{
/* find the minimum */
min = i;
for (j = i+1; j < count; j++)
{
if (data[j] < data[min])
{
min = j;
}
}
/* swap data[i] and data[min] */
temp = data[i];
data[i] = data[min];
data[min] = temp;
}
}
4,快速Quick:先拿出中間的元素來(值保存到temp里),設置兩個索引(index or pointer),一個從0號位置開始往最大位置尋找比temp大的元素;一個從最大號位置開始往最小位置尋找比temp小的元素,找到了或到頂了,則將兩個索引所指向的元素
互換,如此一直尋找交換下去,直到兩個索引交叉了位置,這個時候,從0號位置到第二個索引的所有元素就都比temp小,從第一個索引到最大位置的所有元素就都比temp大,這樣就把所有元素分為了兩塊,然後採用前面的辦法分別排序這兩個部分。總的來
說,就是隨機找一個元素(通常是中間的元素),然後把小的放在它的左邊,大的放右邊,對左右兩邊的數據繼續採用同樣的辦法。只是為了節省空間,上面採用了左右交換的方法來達到目的。
Analysis:
Implementation:
void QuickSort(int *pData, int left, int right)
{
int i, j;
int middle, iTemp;
i = left;
j = right;
middle = pData[(left + right) / 2]; //求中間值
do
{
while ((pData[i] < middle) && (i < right)) //從左掃描大於中值的數
i++;
while ((pData[j] > middle) && (j > left)) //從右掃描小於中值的數
j--;
if (i <= j) //找到了一對值
{
//交換
iTemp = pData[i];
pData[i] = pData[j];
pData[j] = iTemp;
i++;
j--;
}
} while (i <= j); //如果兩邊掃描的下標交錯,就停止(完成一次)
//當左邊部分有值(left<j),遞歸左半邊
if(left < j)
QuickSort(pData, left, j);
//當右邊部分有值(right>i),遞歸右半邊
if(right > i)
QuickSort(pData, i, right);
}
5,希爾Shell:是對Insertion Sort的一種改進,在Insertion Sort中,從第2個位置開始取出數據,每次都是與前一個(step/gap==1)進行比較。Shell Sort修改為,在開始時採用較大的步長step,
從第step位置開始取數據,每次都與它的前step個位置上的數據進行比較(如果有8個數據,初始step==4,那麼pos(4)與pos(0)比較,pos(0)與pos(-4),pos(5)與pos(1),pos(1)與pos(-3),
...... pos(7)與pos(3),pos(3)與pos(-1)),然後逐漸地減小step,直到step==1。step==1時,排序過程與Insertion Sort一樣,但因為有前面的排序,這次排序將減少比較和交換的次數。
Shell Sort的時間復雜度與步長step的選擇有很大的關系。Shell排序比冒泡排序快5倍,比插入排序大致快2倍。Shell排序比起QuickSort,MergeSort,HeapSort慢很多。但是它相對比較簡單,它適合
於數據量在5000以下並且速度並不是特別重要的場合。它對於數據量較小的數列重復排序是非常好的。
Analysis:
Implementation:
template<typename RandomIter, typename Compare>
void ShellSort(RandomIter begin, RandomIter end, Compare cmp)
{
typedef typename std::iterator_traits<RandomIter>::value_type value_type;
typedef typename std::iterator_traits<RandomIter>::difference_type diff_t;
diff_t size = std::distance(begin, end);
diff_t step = size / 2;
while (step >= 1)
{
for (diff_t i = step; i < size; ++i)
{
value_type key = *(begin+i);
diff_t ins = i; // current position
while (ins >= step && cmp(key, *(begin+ins-step)))
{
*(begin+ins) = *(begin+ins-step);
ins -= step;
}
*(begin+ins) = key;
}
if(step == 2)
step = 1;
else
step = static_cast<diff_t>(step / 2.2);
}
}
template<typename RandomIter>
void ShellSort(RandomIter begin, RandomIter end)
{
typedef typename std::iterator_traits<RandomIter>::value_type value_type;
ShellSort(begin, end, std::less<value_type>());
}
6,歸並Merge:先將所有數據分割成單個的元素,這個時候單個元素都是有序的,然後前後相鄰的兩個兩兩有序地合並,合並後的這兩個數據再與後面的兩個合並後的數據再次合並,充分前面的過程直到所有的數據都合並到一塊。
通常在合並的時候需要分配新的內存。
Analysis:
Implementation:
void Merge(int array[], int low, int mid, int high)
{
int k;
int *temp = (int *) malloc((high-low+1) * sizeof(int)); //申請空間,使其大小為兩個已經排序序列之和,該空間用來存放合並後的序列
int begin1 = low;
int end1 = mid;
int begin2 = mid + 1;
int end2 = high;
for (k = 0; begin1 <= end1 && begin2 <= end2; ++k) //比較兩個指針所指向的元素,選擇相對小的元素放入到合並空間,並移動指針到下一位置
{
if(array[begin1]<=array[begin2])
{
temp[k] = array[begin1++];
}
else
{
temp[k] = array[begin2++];
}
}
if(begin1 <= end1) //若第一個序列有剩餘,直接拷貝出來粘到合並序列尾
{
memcpy(temp+k, array+begin1, (end1-begin1+1)*sizeof(int));
}
if(begin2 <= end2) //若第二個序列有剩餘,直接拷貝出來粘到合並序列尾
{
memcpy(temp+k, array+begin2, (end2-begin2+1)*sizeof(int));
}
memcpy(array+low, temp, (high-low+1)*sizeof(int));//將排序好的序列拷貝回數組中
free(temp);
}
void MergeSort(int array[], unsigned int first, unsigned int last)
{
int mid = 0;
if (first < last)
{
mid = (first+last)/2;
MergeSort(array, first, mid);
MergeSort(array, mid+1,last);
Merge(array,first,mid,last);
}
}
『捌』 插入排序,選擇排序,快速排序,歸並排序,冒泡排序中哪個要求內存量最大為什麼
s the entry point for the console application.
//默認是從小到大排序
#include <time.h>
#include <iostream>
#include <iomanip>
using namespace std;
//要排序的數組的長度,以及取值的范圍
#define SIZE 10
#define MAX 10000
//---------------------------------插入排序----------------------------------------
//直接插入排序080201
//原理:每次將待排序的記錄,按其關鍵字大小插入到前邊已經排好序的子文件中的適當位置
int InsertSort(int arr[],int len){
int temp,j;
for(int i=1;i<len;i++){
if(arr[i]<arr[i-1]){
temp=arr[i];
j=i;
do{
arr[j]=arr[j-1];
j--;
}while(j>0&&arr[j-1]>temp);
arr[j] = temp;
}
}
return 0;
}
//SHELL排序 希爾排序 8.2.2
/*
先取一個小於n的整數d1作為第一個增量,把文件的全部記錄分成d1個組。
所有距離為dl的倍數的記錄放在同一個組中。先在各組內進行直接插人排序;
然後,取第二個增量d2<d1重復上述的分組和排序,直至所取的增量dt=1(dt<dt-l<…<d2<d1),
即所有記錄放在同一組中進行直接插入排序為止。
*/
int ModifiedInsertSort(int arr[],int n,int delta){
int temp;
for(int i=delta;i<n;i+=delta){
for(int j=i;j>=delta;j-=delta){
if(arr[j]<arr[j-delta]){
temp = arr[j];
arr[j] = arr[j-delta];
arr[j-delta] = temp;
}
}
}
return 0;
}
int ShellSort(int arr[],int len){
//
for(int delta=len/2;delta>0;delta/=2){
//分別對delta個子序列進行排序//
for(int j=0;j<delta;j++){
ModifiedInsertSort(&arr[j],len-j,delta);
}
}
return 0;
}
//1. 不設監視哨的演算法描述
////注意: 當增量d=1時,ShellPass和InsertSort基本一致,只是由於沒有哨兵而在內循環中增加了一個循環判定條件"j>0",以防下標越界。
void ShellPass(int *R,int n,int d)
{//希爾排序中的一趟排序,d為當前增量
int i,j;
for(i=d+1;i<=n;i++) //將R[d+1..n]分別插入各組當前的有序區
if(R[i] <R[i-d] ){
R[0]=R[i];j=i-d; //R[0]只是暫存單元,不是哨兵
do {//查找R[i]的插入位置
R[j+d]=R[j]; //後移記錄
j=j-d; //查找前一記錄
}while(j>0&&R[0] <R[j] );
R[j+d]=R[0]; //插入R[i]到正確的位置上
} //endif
} //ShellPass
void ShellSort11(int* R,int n)
{
int increment=n; //增量初值,不妨設n>0
do {
increment=increment/3+1; //求下一增量
ShellPass(R,n,increment); //一趟增量為increment的Shell插入排序
}while(increment>1);
} //ShellSort
/*
2.設監視哨的shell排序演算法
演算法分析
1.增量序列的選擇
Shell排序的執行時間依賴於增量序列。
好的增量序列的共同特徵:
① 最後一個增量必須為1;
② 應該盡量避免序列中的值(尤其是相鄰的值)互為倍數的情況。
有人通過大量的實驗,給出了目前較好的結果:當n較大時,比較和移動的次數約在nl.25到1.6n1.25之間。
2.Shell排序的時間性能優於直接插入排序
希爾排序的時間性能優於直接插入排序的原因:
①當文件初態基本有序時直接插入排序所需的比較和移動次數均較少。
②當n值較小時,n和n2的差別也較小,即直接插入排序的最好時間復雜度O(n)和最壞時間復雜度0(n2)差別不大。
③在希爾排序開始時增量較大,分組較多,每組的記錄數目少,故各組內直接插入較快,後來增量di逐漸縮小,分組數逐漸減少,而各組的記錄數目逐漸增多,但由於已經按di-1作為距離排過序,使文件較接近於有序狀態,所以新的一趟排序過程也較快。
因此,希爾排序在效率上較直接插人排序有較大的改進。
3.穩定性
希爾排序是不穩定的。參見上述實例,該例中兩個相同關鍵字49在排序前後的相對次序發生了變化。
*/
//---------------------------------交換排序----------------------------------------
//交換排序---冒泡排序,快速排序
//原理:兩兩比較待排序記錄的關鍵字,發現兩個記錄的次序相反時即進行交換,直到沒有反序的記錄為止。
//冒泡排序080301
int BubbleSort(int arr[],int len){
int k,temp ;
for(int i=0;i<len-1;i++){
k = i;
for(int j=i+1;j<len;j++){
if(arr[j]<arr[k])
k = j;
}
if(k!=i){
temp = arr[i];
arr[i] = arr[k];
arr[k] = temp;
}
}
return 0;
}
//優化的冒泡排序
int ImprovedBubbleSort(int arr[],int len){
bool noswap;
int temp;
for(int i=0;i<len;i++){
noswap = true;
for(int j=len-1;j>i;j--){
if(arr[j]<arr[j-1]){
temp = arr[j];
arr[j] = arr[j-1];
arr[j-1] = temp;
noswap = false;
}
}
if(noswap){
break;
}
}
return 0;
}
//快速排序080302
int Partition(int arr[],int len,int i,int j){
int pivot = arr[i];
while(i<j){
while(i<j&&arr[j]>=pivot){
j--;
}
if(i<j){
arr[i++] = arr[j];
}
while(i<j&&arr[i]<=pivot){
i++;
}
if(i<j){
arr[j--] = arr[i];
}
}
arr[i] = pivot;
return i;
}
int QuickSort(int arr[],int len,int low=0,int high=SIZE){
int pivotpos;
if(low<high){
pivotpos = Partition(arr,len,low,high);
QuickSort(arr,len,low,pivotpos-1);
QuickSort(arr,len,pivotpos+1,high);
}
return 0;
}
//---------------------------------選擇排序----------------------------------------
//直接選擇排序080401
//原理:每一趟從待排序的記錄中選出關鍵字最小的記錄,順序放到已排好序的子文件的最後
int StraightSelect(int arr[],int len){
int temp=0;
int k;
for(int i=0;i<len;i++){
k=i;
for(int j=k+1;j<len;j++){
if(arr[j]<arr[k]){
k = j;
}
}
if(k!=i){
temp = arr[k];
arr[k] = arr[i];
arr[i] = temp;
}
}
return 0;
}
//---------------------------------歸並排序----------------------------------------
//歸並排序:
int Merge(int arr[],int len){
return 0;
}
//---------------------------------分配排序----------------------------------------
//桶排序,箱排序8.6
//事先知道序列中的記錄都位於某個小區間段[0,m)內
// 將具有相同值的記錄都分配到同一個桶中,然後依次按照編號從桶中取出記錄,組成一個有序序列
int BucketSort(int arr[],int len){
int max = MAX;//最大值
int *count = new int[max];
int i;
for(i=0;i<max;i++){
count[i] = 0;
}
for(i=0;i<len;i++){
count[arr[i]]++;
}
for(i=0;i<len;){
for(int j=0;j<max;j++){
while(count[j]>0){
arr[i++] = j;
count[j]--;
}
}
}
return 0;
}
//列印數組
int printarr(int arr[],int len){
for(int i=0;i<len;i++){
if(i%10==0)
cout<<endl;
cout<<setw(4)<<arr[i]<<" ";
}
cout<<endl;
return 0;
}
int main()
{
int arr[SIZE];
int len = sizeof(arr)/sizeof(arr[0]);//SIZE
srand( (unsigned)time( NULL ) );
for(int i=0;i<len;i++){
arr[i] =rand()%MAX;
}
cout<<"生成數組:"<<endl;
printarr(arr,len);
// StraightSelect(arr,len);
// InsertSort(arr,len);
// BubbleSort(arr,len);
// QuickSort(arr,len);
// ImprovedBubbleSort(arr,len);
// ShellSort(arr,len);
BucketSort(arr,len);
cout<<endl<<"排序後得到的數組:"<<endl;
printarr(arr,len);
return 0;
}
『玖』 (54) 在下列幾種排序方法中,要求內存量最大的是______。 A. 插入排序 B. 選擇排序 C. 快速排序 D. 歸並排
(54)[答案]D
[考點]數據結構與演算法
[分析]
我們對比一個排序方法的優越性有"平均時間"、"最壞情況時間"和"輔助空間"。其中輔助空間一般是排序中需要額外的內存開銷,這些內存開銷一般據一些如中間變數(暫存變數)、比較與交換等等來決定。
插入排序和選擇排序的輔助空間都是o(1),快速排序是o(nlog2n),歸並排序是o(n)。
可知歸並排序要求內存量最大,我們也可以從其變數及循環個數也以看出歸並排序要求內存量最大。
『拾』 常見的排序演算法哪個效率最高
快速排序法。
java的排序演算法有哪些?
java的排序大的分類可以分為兩種:內排序和外排序。在排序過程中,全部記錄存放在內存,則稱為內排序,如果排序過程中需要使用外存,則稱為外排序。下面講的排序都是屬於內排序:
1.插入排序:直接插入排序、二分法插入排序、希爾排序。
2.選擇排序:簡單選擇排序、堆排序。
3.交換排序:冒泡排序、快速排序。
4.歸並排序。
5.基數排序。
java中的演算法,一共有多少種,哪幾種,怎麼分類?
1、演算法按實現方式分,有遞歸、迭代、平行、序列、過程、確定、不確定等。
2、演算法按設計范型分,有分治、動態、貪心、線性、圖論、簡化等。