紧接上次内容,把剩下四个排序算法贴上
快速排序
#include "iostream"
using namespace std;
int function(int a[],int left,int right) {
int keyValue = a[left]; //每次把数组第一个元素设为标记值
while (left < right) {
while (left < right && a[right] >= keyValue)
right--;
a[left] = a[right]; //从右往左,把比标记值小的记录移到低端
while (left < right && a[left] <= keyValue)
left++;
a[right] = a[left]; //从左往右,把比标记值大的记录移到高端
}
a[left] = keyValue; //把标记值移到最后的空缺位
return left; //返回标记值的索引
}
void sort(int a[],int left,int right) {
if (left < right) {
int keyIndex = function(a,left,right); //取到索引作为分界位
sort(a,left,keyIndex-1); //索引左部递归排序
sort(a,keyIndex+1,right); //索引右部递归排序
}
}
int main() {
int a[10] = {
5,4,6,8,1,3,9,10,2,7};
sort(a,0,9);
for(int i = 0;i < 10;i++)
cout<" ";
cout<return 0;
}
希尔排序
#include "iostream"
using namespace std;
void function(int a[],int n,int d) {
for(int i = d;i < n;i++) { //从第一个子序列的第二个元素开始遍历
if(a[i] < a[i-d]) { //当该元素小于有序序列的末元素时,进行插入排序
int s = a[i]; //标记该元素
for(int j = i-d;j >= 0 && s < a[j] ;j -= d) //从有序序列尾元素向前循环,标记元素查找插入位置,并移动其余元素
a[j+d] = a[j];
a[j+d] = s; //插入标记元素
}
}
}
void shell(int a[],int n) {
int b[3] = {
5,3,1}; //增量序列,最后一个元素必须为1
for(int i = 0;i < 3;i++)
function(a,n,b[i]);
}
int main() {
int a[10] = {
5,9,7,8,2,4,3,1,10,6};
shell(a,10);
for(int i = 0;i < 10;i++)
cout<" ";
cout<return 0;
}
堆排序
#include "iostream"
using namespace std;
void function(int a[],int s,int m) {
int i;
int key = a[s];
for(i = 2 * s;i <= m;i *= 2) { //沿值较大的孩子结点向下筛选
if(i < m && a[i] < a[i+1]) //i为值较大的记录的下标
++i;
if(key > a[i]) //key应插入在位置s上
break;
a[s] = a[i];
s = i;
}
a[s] = key; //插入
}
void heap(int a[],int n) {
int i;
for(i = n / 2;i > 0;--i) //把a[1]~a[11]建成大顶堆
function(a,i,n);
for(i = n;i > 1;--i) {
int s = a[1]; //将堆顶记录和当前未经排序子序列a[1]~a[i]中最后一个记录进行交换
a[1] = a[i];
a[i] = s;
function(a,1,i-1); //将a[1]~a[i-1]重新调整为大顶堆
}
}
int main() {
int a[11] = {
0,2,5,6,7,9,1,3,10,4,8};//为了配合二叉树性质,左子树结点序号为父结点序号的两倍,故a[0]没有任何意义,待排序序列为a[1]~a[11]
heap(a,10);
for(int i = 1;i < 11;i++)
cout<" ";
cout<return 0;
}
归并排序
#include "iostream"
using namespace std;
void function(int a[], int l, int m, int r) {
int n1 = m-l+1;
int n2 = r-m;
int *L = new int[n1]; //定义动态数组,长度为传入数组左部
int *R = new int[n2]; //定义动态数组,长度为传入数组右部
int i,j,k;
for(i = 0;i < n1;i++) //赋值左数组
L[i] = a[l+i];
for(j = 0;j < n2;j++) //赋值右数组
R[j] = a[m+j+1];
for(i = 0,j = 0,k = l;i < n1 && j < n2 && k <= r;k++) { //比较左数组和右数组元素大小,由小到大赋值给a
if(L[i] < R[j])
a[k] = L[i++];
else
a[k] = R[j++];
}
if(i < n1) { //若左数组有剩余,则依次写到a数组尾部
for(;k <= r;k++)
a[k] = L[i++];
}
if(j < n2) { //若右数组有剩余,则依次写到a数组尾部
for(;k <= r;k++)
a[k] = R[j++];
}
delete []L; //清除内存
delete []R;
}
void merge(int a[], int l, int r) {
if (l < r) {
int m = (l+r)/2;
merge(a, l, m); //递归数组左部
merge(a, m+1, r); //递归数组右部
function(a, l, m, r); //归并排序
}
}
void main() {
int a[10] = {
5,6,7,8,1,3,4,2,9,10};
merge(a,0,9);
for(int i = 0;i < 10;i++)
cout<" ";
cout<
终。