這個是我女朋友整理的排序算法,恩,她去了哪?MARVELL
程序依然是簡單易懂,並且整理得當
#include <iostream>
using namespace std;
#define NUM 5
/**************************************************************
* 堆的定義 n 個元素的序列 {k1,k2,...,kn}當且僅當滿足下列關係時,
* 稱爲堆:
* ki<=k2i ki<=k2i+1 (i=1,2,...,n/2)
* 或
* ki>=k2i ki>=k2i+1 (i=1,2,...,n/2)
* 堆排序思路:
* 建立在樹形選擇排序基礎上;
* 將待排序列建成堆(初始堆生成)後,序列的第一個元素(堆頂元素)就一定是序列中的最大元素;
* 將其與序列的最後一個元素交換,將序列長度減一;
* 再將序列建成堆(堆調整)後,堆頂元素仍是序列中的最大元素,再次將其與序列最後一個元素交換並縮短序列長度;
* 反覆此過程,直至序列長度爲一,所得序列即爲排序後結果。
**************************************************************/
template<typename T>
void HeapAdjust(T a[],int s,int n) /* 排列成堆的形式 */
{
int i;
T temp = a[s-1];
for(i=s*2; i<=n; i*=2)
{
if(i<n && a[i-1]<a[i])//取較大孩子結點
i++;
if(temp>a[i-1])//如果父結點大於子結點,跳出循環
break;
a[s-1] = a[i-1]; /* “父節點”比“較大的孩子節點”大則互換 ,保證父節點比所有子節點都大(父節點存儲在前面)*/
s = i;//父節點移到被交換的子結點,遞歸向下檢查
}
a[s-1] = temp;
}
template<typename T>
void HeapSort(T a[],int n) /* 堆排序函數 */
{
int i;
T temp;
for(i=n/2; i>0; i--)//因爲當前樹不是堆,無序,所以從n/2處(n/2向後的結點的子樹可以看作堆),開始調整爲堆。
{
HeapAdjust(a, i, n);/* 處理後,a[i]是這個數組後半部分的最大值 */
}
for(i=n; i>1; i--)//排到前面的元素只剩一個就結束了
{
temp = a[0]; /* 把根元素(剩下元素中最大的那個)放到結尾 ,下一次只要排剩下的數就可以啦*/
a[0] = a[i-1];
a[i-1] = temp;
HeapAdjust(a, 1, i-1);
}
}
/*冒泡排序*/
template<typename T>
void BubbleSort(T a[],int n)
{
T temp;
int i,j;
int flag = 0;
for(i=1; i<n; i++)
{
flag = 0;
for(j=0; j<n-i; j++)
{
if(a[j]>a[j+1])
{
a[j] = a[j]^a[j+1];
a[j+1] = a[j]^a[j+1];
a[j] = a[j]^a[j+1];
flag = 1;
}
}
if(flag==0)
break;
}
}
//希爾排序
template<typename T>
void ShellSort(T a[],int n)
{
int gap;
int i,j,k;
T temp;
for(gap=n/2; gap>0; gap/=2)
{
for(i=gap; i<n; i+=gap)
{
temp = a[i];
k = i;
while((k>0) && (temp<a[k-gap]))
//while(temp<a[k-gap])
{
a[k] = a[k-gap];
k -= gap;
}
a[k] = temp;
}
}
}
/*快速排序*/
template<typename T>
void QuickSort(T a[], int low, int high)
{
T pivot;
int i,j;
if(low<high)
{
i = low;
j = high;
pivot = a[low];
while(i<j)
{
while((i<j)&&(pivot<=a[j]))
j--;
if(i<j)
a[i++] = a[j];
while((i<j)&&(a[i]<=pivot))
i++;
if(i<j)
a[j--] = a[i];
}
a[i] = pivot;
QuickSort(a,low,i-1);
QuickSort(a,i+1,high);
}
}
/*選擇排序 不穩定*/
template<typename T>
void SelectSort1(T a[],int n)
{
int i,j;
for(i=0; i<n-1; i++)
{
for(j=i+1; j<n; j++)
{
if(a[j]<a[i])
{
a[i] = a[i]^a[j];
a[j] = a[i]^a[j];
a[i] = a[i]^a[j];
}
}
}
}
template<typename T>
void SelectSort(T a[],int n)
{
int i,j,min;
T temp;
for(i=0; i<n-1; i++)
{
min = i;
for(j=i+1; j<n; j++)
{
if(a[j]<a[min])
{
min = j;
}
}
temp = a[i];
a[i] = a[min];
a[min] = temp;
}
}
/*簡單插入排序*/
template<typename T>
void InsertSort(T a[],int n)
{
T temp;
int i,j;
for(i=1; i<n; i++)
{
temp = a[i];
for(j=i; j>0 &&(temp<a[j-1]); j--)
{
a[j] = a[j-1];
}
a[j] = temp;//注意是a[j]
}
}
/*折半插入:用low和high標定查找界限,下一次的查找
範圍是上一次的一半*/
template<typename T>
void BiInsert_sort(T a[],int n)
{
int low,mid,high;
int i,j;
T temp;
for(i=1; i<n; i++)
{
low = 0;
high = i-1;
temp = a[i];
while(low<=high)
{
mid = (low+high)/2;
if(temp<=a[mid])
high = mid-1;
else
low = mid+1;
}
for(j=i; j>mid; j--)
a[j] = a[j-1];
a[low] = temp;////或者是high+1,不能是m
}
}
/*2-路插入排序是在折半插入排序的基礎上再改進之,
其目的是減少排序過程中移動記錄的次數,但爲此需
要n個記錄的輔助空間。時間複雜度爲O(n^2)。
理解:所謂的2-路,是指優先插入在序列前面或後面,
然後再考慮插入到中間。*/
template<typename T>
void TwoInsert_sort(T a[],T t[],int n)
{
int i;
int first=0, final=0;
t[0] = a[0];
for(i=1; i<n; i++)
{
if(a[i]<=t[first])
{
first = (first-1+n)%n;
t[first] = a[i];
}
else if(a[i]>=t[final])
{
final = final+1;
t[final] = a[i];
}
else
{
int j = final++;
while(a[i]<t[j])
{
t[(j+1+n)%n] = t[(j+n)%n];//
j = (j-1+n)%n;//
}
t[j+1] = a[i];//j+1
}
}
for(i=0; i<n; i++)
a[i] = t[(first+i)%n];
}
int main()
{
int a[NUM];
int b[NUM];
int i;
char s;
B: cout<<"Please input "<<NUM<<" integers:\n";
for(i=0; i<NUM; i++)
{
cin>>a[i];
}
cout<<"排序算法:\n";
cout<<"1: BubbleSort...\n";
cout<<"2: InsertSort...\n";
cout<<"3: BiInsert_sort...\n";
cout<<"4: TwoInsert_sort...\n";
cout<<"5: SelectSort...\n";
cout<<"6: SelectSort1...\n";
cout<<"7: QuickSort...\n";
cout<<"8: ShellSort...\n";
cout<<"9: HeapSort...\n";
cout<<"0: 重新輸入數組數據...\n";
while(1)
{
A: cout<<"請選擇排序算法,輸入編號:\n";
cin>>s;
switch(s)
{
case '1':
BubbleSort(a,NUM);
break;
case '2':
InsertSort(a,NUM);
break;
case '3':
BiInsert_sort(a,NUM);
break;
case '4':
TwoInsert_sort(a,b,NUM);
break;
case '5':
SelectSort(a,NUM);
break;
case '6':
SelectSort1(a,NUM);
break;
case '7':
QuickSort(a,0,NUM-1);
break;
case '8':
ShellSort(a,NUM);
break;
case '9':
HeapSort(a,NUM);
break;
case '0':
goto B;
//break;
default:
//cout<<"選擇無效!\n";
cout<<"選擇無效,請重新選擇!\n";
goto A;
}
cout<<"The result is:\n";
for(i=0; i<NUM; i++)
{
cout<<a[i]<<" ";
}
cout<<endl;
}
return 0;
}