排序

6.全國有10000人蔘加物理競賽,只錄取成績優異的前10名,並將他們從高分到低分輸出。而對落選的其他考生,不需排出名次,問此種情況下,用何種排序方法速度最快?爲什麼?
堆排序
在內部排序方法中,一趟排序後只有簡單選擇排序和冒泡排序可以選出一個最大(或最小)元素,並加入到已有的有序子序列中,但要比較n-1次。選次大元素要再比較n-2次,其時間複雜度是O(n2)。從10000個元素中選10個元素不能使用這種方法。而快速排序、插入排序、歸併排序、基數排序等時間性能好的排序,都要等到最後才能確定各元素位置。只有堆排序,在未結束全部排序前,可以有部分排序結果。建立堆後,堆頂元素就是最大(或最小,視大堆或小堆而定)元素,然後,調堆又選出次大(小)元素。凡要求在n個元素中選出k(k<<n,k>2)
個最大(或最小)元素,一般均使用堆排序。因爲堆排序建堆比較次數至多不超過4n,對深度爲k的堆,在調堆算法中進行的關鍵字的比較次數至多爲2(k-1)次,且輔助空間爲O(1)。
 
7. 給出一組關鍵字:29,18,25,47,58,12,51,10,分別寫出按下列各種排序方法進行排序時的變化過程:
(1) 歸併排序   每歸併一次書寫一個次序。
(2) 快速排序   每劃分一次書寫一個次序。
(3) 堆排序     先建成一個堆,然後每從堆頂取下一個元素後,將堆調整一次。
(1)2路歸併
第一趟:18,29,25,47,12,58,10,51;
第二趟:18,25,29,47,10,12,51,58;
第三趟:10,12,18,25,29,47,51,58
(2)快速排序
第一趟:10,18,25,12,29,58,51,47;
第二趟:10,18,25,12,29,47,51,88;
第三趟:10,12,18,25,29,47,51,88
(3)堆排序 建大堆
58,47,51,29,18,12,25,10;
①51,47,25,29,18,12,10,58;
②47,29,25,10,18,12,51,58;
③29,18,25,10,12,47,51,58;
④25,18,12,10,29,47,51,58;
⑤18,10,12,25,29,47,51,58;
⑥12,10,18,25,29,47,51,58;
⑦10,12,18,25,29,47,51,58
 
8.請寫出應填入下列敘述中( )內的正確答案。 
排序有各種方法,如插入排序、快速排序、堆排序等。
設一數組中原有數據如下:15,13,20,18,12,60。下面是一組由不同排序方法進行一遍排序後的結果。
(快速 )排序的結果爲:12,13,15,18,20,60
( 冒泡)排序的結果爲:13,15,18,12,20,60
(直接插入 )排序的結果爲:13,15,20,18,12,60
( 堆)排序的結果爲:12,13,20,18,15,60
 
 
五、算法設計題:
1.冒泡排序算法是把大的元素向上移(氣泡的上浮),也可以把小的元素向下移(氣泡的下沉)請給出上浮和下沉過程交替的冒泡排序算法。
void BubbleSort2(int a[],int n) //相鄰兩趟向相反方向起泡的冒泡排序算法
{ change=1;low=0;high=n-1; //冒泡的上下界
while(low<high && change)
{ change=0; //設不發生交換
for(i=low;i<high;i++) //從上向下起泡
if(a[i]>a[i+1]){a[i]<-->a[i+1];change=1;} //有交換,修改標誌change
high--; //修改上界
for(i=high;i>low;i--) //從下向上起泡
if(a[i]<a[i-1]){a[i]<-->a[i-1];change=1;}
low++; //修改下界
}//while
}//BubbleSort2
 
2.寫出一趟快速排序算法。
int Partition(RecType R[],int l,int h)
//一趟快速排序算法,樞軸記錄到位,並返回其所在位置,
{ int i=l; j=h; R[0] = R[i]; x =R[i].key;
while(i<j)
{ while(i<j && R[j].key>=x) j--;
if (i<j) R[i] = R[j];
while(i<j && R[i].key<=x) i++;
if (i<j) R[j] = R[i];
}//while
R[i]=R[0];
return i;
 
3.非遞歸的快速排序算法。
void QuickSort(rectype r[n+1]; int n)
// 對r[1..n]進行快速排序的非遞歸算法
{typedef struct
{ int low,high; }node
node s[n+1];//棧,容量足夠大
int quickpass(rectype r[],int,int); // 函數聲明
int top=1; s[top].low=1; s[top].high=n;
while (top>0)
{ss=s[top].low; tt=s[top].high; top--;
if (ss<tt)
{k=quickpass(r,ss,tt);
if (k-ss>1) {s[++top].low=ss; s[top].high=k-1;}
if (tt-k>1) {s[++top].low=k+1; s[top].high=tt;}
}
} // 算法結束
int quickpass(rectype r[];int s,t)
{i=s; j=t; rp=r[i]; x=r[i].key;
while (i<j)
{while (i<j && x<=r[j].key) j--;
if (i<j) r[i++]=r[j];
while (i<j && x>=r[j].key) i++;
if (i<j) r[j--]=r[i];;
]
r[i]=rp;
return (i);
} // 一次劃分算法結束
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章