一 插入排序
1.1 直接插入排序
- //直接順序排序
- void InsertSort(int r[], int n)
- {
- for (int i=2; i<n; i++)
- {
- r[0]=r[i]; //設置哨兵
- for (int j=i-1; r[0]<r[j]; j--) //尋找插入位置
- r[j+1]=r[j]; //記錄後移
- r[j+1]=r[0];
- }
- for(int k=1;k<n;k++)
- cout<<r[k]<<" ";
- cout<<"\n";
- }
1.2 希爾排序
- <span style="font-size:14px;">//希爾排序
- void ShellSort(int r[], int n)
- {
- int i;
- int d;
- int j;
- for (d=n/2; d>=1; d=d/2) //以增量爲d進行直接插入排序
- {
- for (i=d+1; i<n; i++)
- {
- r[0]=r[i]; //暫存被插入記錄
- for (j=i-d; j>0 && r[0]<r[j]; j=j-d)
- r[j+d]=r[j]; //記錄後移d個位置
- r[j+d]=r[0];
- }
- }
- for(i=1;i<n;i++)
- cout<<r[i]<<" ";
- cout<<"\n";
- }</span>
二 交換排序
2.1 起泡排序
- <span style="font-size:14px;">//起泡排序
- void BubbleSort(int r[], int n)
- {
- int temp;
- int exchange;
- int bound;
- exchange=n-1; //第一趟起泡排序的範圍是r[0]到r[n-1]
- while (exchange) //僅當上一趟排序有記錄交換才進行本趟排序
- {
- bound=exchange;
- exchange=0;
- for (int j=0; j<bound; j++) //一趟起泡排序
- if (r[j]>r[j+1])
- {
- temp=r[j];
- r[j]=r[j+1];
- r[j+1]=temp;
- exchange=j; //記錄每一次發生記錄交換的位置
- }
- }
- for(int i=0;i<n;i++)
- cout<<r[i]<<" ";
- cout<<"\n";
- }</span>
2.2快速排序
- //快速排序一次劃分
- int Partition(int r[], int first, int end)
- {
- int i=first; //初始化
- int j=end;
- int temp;
- while (i<j)
- {
- while (i<j && r[i]<= r[j])
- j--; //右側掃描
- if (i<j)
- {
- temp=r[i]; //將較小記錄交換到前面
- r[i]=r[j];
- r[j]=temp;
- i++;
- }
- while (i<j && r[i]<= r[j])
- i++; //左側掃描
- if (i<j)
- {
- temp=r[j];
- r[j]=r[i];
- r[i]=temp; //將較大記錄交換到後面
- j--;
- }
- }
- return i; //i爲軸值記錄的最終位置
- }
- //快速排序
- void QuickSort(int r[], int first, int end)
- {
- if (first<end)
- { //遞歸結束
- int pivot=Partition(r, first, end); //一次劃分
- QuickSort(r, first, pivot-1);//遞歸地對左側子序列進行快速排序
- QuickSort(r, pivot+1, end); //遞歸地對右側子序列進行快速排序
- }
- }
三 選擇排序
3.1 簡單選擇排序
- //簡單選擇排序
- void SelectSort(int r[ ], int n)
- {
- int i;
- int j;
- int index;
- int temp;
- for (i=0; i<n-1; i++) //對n個記錄進行n-1趟簡單選擇排序
- {
- index=i;
- for (j=i+1; j<n; j++) //在無序區中選取最小記錄
- if (r[j]<r[index])
- index=j;
- if (index!=i)
- {
- temp=r[i];
- r[i]=r[index];
- r[index]=temp;
- }
- }
- for(i=0;i<n;i++)
- cout<<r[i]<<" ";
- cout<<"\n";
- }
3.2 堆排序
堆的定義
堆是具有下列性質的完全二叉樹:每個結點的值都小於或等於其左右孩子結點的值(小根堆);或者每個結點的值都大於或等於其左右孩子結點的值(大根堆)。
假設當前要篩選結點的編號爲k,堆中最後一個結點的編號爲m,並且結點k的左右子樹均是堆(即r[k+1] ~ r[m]滿足堆的條件),則篩選算法用僞代碼可描述爲:
具體的篩選代碼如下:
- //篩選法調整堆
- void Sift(int r[], int k, int m)
- {
- int i;
- int j;
- int temp;
- i=k;
- j=2*i+1; //置i爲要篩的結點,j爲i的左孩子
- while (j<=m) //篩選還沒有進行到葉子
- {
- if (j<m && r[j]<r[j+1])
- j++; //比較i的左右孩子,j爲較大者
- if (r[i]>r[j]) break; //根結點已經大於左右孩子中的較大者
- else
- {
- temp=r[i];
- r[i]=r[j];
- r[j]=temp; //將根結點與結點j交換
- i=j;
- j=2*i+1; //被篩結點位於原來結點j的位置
- }
- }
- }
堆排序
堆排序的基本思想是:首先將待排序的記錄序列構造成一個堆,此時,選出了堆中所有記錄的最大者即堆頂記錄,然後將它從堆中移走(通常將堆頂記錄和堆中最後一個記錄交換),並將剩餘的記錄再調整成堆,這樣又找出了次大的記錄,以此類推,直到堆中只有一個記錄爲止。
- //堆排序
- void HeapSort(int r[ ], int n)
- {
- int i;
- int temp;
- for (i=n/2; i>=0; i--) //初始建堆,從最後一個非終端結點至根結點
- Sift(r, i, n) ;
- for (i=n-1; i>0; i--) //重複執行移走堆頂及重建堆的操作
- {
- temp=r[i];
- r[i]=r[0];
- r[0]=temp;
- Sift(r, 0, i-1);
- }
- for(i=0;i<n;i++)
- cout<<r[i]<<" ";
- cout<<"\n";
- }
四 歸併排序
- //一次歸併
- void Merge(int r[], int r1[], int s, int m, int t)
- {
- int i=s;
- int j=m+1;
- int k=s;
- while (i<=m && j<=t)
- {
- if (r[i]<=r[j])
- r1[k++]=r[i++]; //取r[i]和r[j]中較小者放入r1[k]
- else
- r1[k++]=r[j++];
- }
- if (i<=m)
- while (i<=m) //若第一個子序列沒處理完,則進行收尾處理
- r1[k++]=r[i++];
- else
- while (j<=t) //若第二個子序列沒處理完,則進行收尾處理
- r1[k++]=r[j++];
- }
- //一趟歸併
- void MergePass(int r[ ], int r1[ ], int n, int h)
- {
- int i=0;
- int k;
- while (i<=n-2*h) //待歸併記錄至少有兩個長度爲h的子序列
- {
- Merge(r, r1, i, i+h-1, i+2*h-1);
- i+=2*h;
- }
- if (i<n-h)
- Merge(r, r1, i, i+h-1, n); //待歸併序列中有一個長度小於h
- else for (k=i; k<=n; k++) //待歸併序列中只剩一個子序列
- r1[k]=r[k];
- }
- //歸併排序的非遞歸算法
- void MergeSort1(int r[ ], int r1[ ], int n )
- {
- int h=1;
- int i;
- while (h<n)
- {
- MergePass(r, r1, n-1, h); //歸併
- h=2*h;
- MergePass(r1, r, n-1, h);
- h=2*h;
- }
- for(i=0;i<n;i++)
- cout<<r[i]<<" ";
- cout<<"\n";
- }
- //歸併排序的遞歸算法
- void MergeSort2(int r[], int r1[], int r2[],int s, int t)
- {
- int m;
- if (s==t)
- {
- r1[s]=r[s];
- }
- else
- {
- m=(s+t)/2;
- MergeSort2(r, r2, r1, s, m); //歸併排序前半個子序列
- MergeSort2(r, r2, r1, m+1, t); //歸併排序後半個子序列
- Merge(r2, r1, s, m, t); //將兩個已排序的子序列歸併
- }
- }