//以下算法不足
//1.效率有点低,做不到 就差一个就排好序的情况下一步即可,而这里始终都是n-1次排序
#include <iostream>
using namespace std;
#define MAXSIZE 20 //顺序表的最大长度
typedef struct {
int key;
char *otherinfo;
} ElemType;
//顺序表的存储结构
typedef struct {
ElemType *r; //存储空间的基地址
int length; //顺序表长度
} SqList; //顺序表类型
void show(SqList L) {
int i;
for (i = 1; i <= L.length; i++)
cout << L.r[i].key << " ";
cout << endl;
}
//折半插入
void BInsertSort(SqList &L) {
int m, low, high, j, i;
for ( i = 2; i <= L.length; i++) {
L.r[0] = L.r[i];
low = 1;
high = i - 1;
while (low <= high) {
m = low + high / 2;
if (L.r[0].key < L.r[m].key) {
high = m - 1;
} else {
low = m + 1;
}
}
//找到位置high为i的前一个位置,因此i要插入到high+1位置,high+1后面的要后移
for (j = i - 1; j >= high; --j) {
L.r[j + 1] = L.r[j];
}
L.r[high + 1] = L.r[0];
printf("第%d次排序情况:", i - 1);
show(L);
printf("\n");
}
//将r[0]即原r[i],插入到正确位置
} //for
//直接插入
void InsertSort(SqList &L) {
//对顺序表L做直接插入排序
int i, j;
for (i = 2; i <= L.length; ++i) {
if (L.r[i].key < L.r[i - 1].key) {
//"<",需将r[i]插入有序子表
L.r[0] = L.r[i]; //将待插入的记录暂存到监视哨中
L.r[i] = L.r[i - 1]; //r[i-1]后移
for (j = i - 2; L.r[0].key <= L.r[j].key; --j) //从后向前寻找插入位置
L.r[j + 1] = L.r[j]; //记录逐个后移,直到找到插入位置
L.r[j ] = L.r[0]; //将r[0]即原r[i],插入到正确位置
}
printf("第%d次排序情况:", i - 1);
show(L);
printf("\n");
} //if
} //InsertSort
void Create_Sq(SqList &L) {
int i, n;
cout << "请输入数据个数,不超过" << MAXSIZE << "个。" << endl;
cin >> n; //输入个数
cout << "请输入待排序的数据:\n";
while (n > MAXSIZE) {
cout << "个数超过上限,不能超过" << MAXSIZE << ",请重新输入" << endl;
cin >> n;
}
for (i = 1; i <= n; i++) {
cin >> L.r[i].key;
L.length++;
}
}
//希尔核心算法
void ShellInsert(SqList &L, int dk) {
//对顺序表L做一趟增量是dk的希尔插入排序
int i, j;
for (i = dk + 1; i <= L.length; ++i)
if (L.r[i].key < L.r[i - dk].key) {
//需将L.r[i]插入有序增量子表
L.r[0] = L.r[i]; //暂存在L.r[0]
for (j = i - dk; j > 0 && L.r[0].key < L.r[j].key; j -= dk)
L.r[j + dk] = L.r[j]; //记录后移,直到找到插入位置
L.r[j + dk] = L.r[0]; //将r[0]即原r[i],插入到正确位置
} //for
show(L);
printf("\n");
}
//希尔趟数
void ShellSort(SqList &L, int dt[ ], int t) {
//按增量序列dt[0..t-1]对顺序表L作t趟希尔排序
int k;
for (k = 0; k < t; ++k)
//printf("%d\n", k);
ShellInsert(L, dt[k]);//5,3,1 //一趟增量为dt[t]的希尔插入排序
} //ShellSort
//冒泡排序
void BubbleSort(SqList L) {
//对顺序表L做冒泡排序
int m, j, flag, i = 1;
ElemType t;//ElemType
m = L.length - 1;
flag = 1; //flag用来标记某一趟排序是否发生交换
while ((m > 0) && (flag == 1)) {
flag = 0; //flag置为0,如果本趟排序没有发生交换,则不会执行下一趟排序
for (j = 1; j <= m; j++)
if (L.r[j].key > L.r[j + 1].key) {
flag = 1; //flag置为1,表示本趟排序发生了交换
t = L.r[j];
L.r[j] = L.r[j + 1];
L.r[j + 1] = t; //交换前后两个记录
} //if
--m;
printf("第%d次排序情况:", i);
i++;
show(L);
printf("\n");
} //while
} //BubbleSort
//快速排序2
int Partition(SqList &L, int low, int high) {
//对顺序表L中的子表r[low..high]进行一趟排序,返回枢轴位置
int pivotkey;
L.r[0] = L.r[low]; //用子表的第一个记录做枢轴记录
pivotkey = L.r[low].key; //枢轴记录关键字保存在pivotkey中
while (low < high) {
//从表的两端交替地向中间扫描
while (low < high && L.r[high].key >= pivotkey)
--high;
L.r[low] = L.r[high]; //将比枢轴记录小的记录移到低端
while (low < high && L.r[low].key <= pivotkey)
++low;
L.r[high] = L.r[low]; //将比枢轴记录大的记录移到高端
}//while
L.r[low] = L.r[0];
//int i = 1; //枢轴记录到位
printf("排序情况:");
show(L);
printf("\n");
return low; //返回枢轴位置
}//Partition
//快速排序
void QSort(SqList &L, int low, int high) {
//调用前置初值:low=1; high=L.length;
//对顺序表L中的子序列L.r[low..high]做快速排序
int pivotloc;
int i = 1;
if (low < high) {
//长度大于1
pivotloc = Partition(L, low, high); //将L.r[low..high]一分为二,pivotloc是枢轴位置
QSort(L, low, pivotloc - 1); //对左子表递归排序
QSort(L, pivotloc + 1, high); //对右子表递归排序
}
} //QSort
void SelectSort(SqList &L) {
//对顺序表L做简单选择排序
int i, j, k;
ElemType t;
for (i = 1; i < L.length; ++i) {
//在L.r[i..L.length] 中选择关键字最小的记录
k = i;
for (j = i + 1; j <= L.length; ++j)
if (L.r[j].key < L.r[k].key)
k = j; //k指向此趟排序中关键字最小的记录
if (k != i) {
t = L.r[i]; //交换r[i]与r[k]
L.r[i] = L.r[k];
L.r[k] = t;
}
printf("第%d次排序情况:", i);
show(L);
printf("\n");
}
}
//归并三
//用算法8.10 相邻两个有序子序列的归并
void Merge(ElemType R[], ElemType T[], int low, int mid, int high) {
//将有序表R[low..mid]和R[mid+1..high]归并为有序表T[low..high]
int i, j, k;
i = low;
j = mid + 1;
k = low;
while (i <= mid && j <= high) {
//将R中记录由小到大地并入T中
if (R[i].key <= R[j].key)
T[k++] = R[i++];
else
T[k++] = R[j++];
}
while (i <= mid) //将剩余的R[low..mid]复制到T中
T[k++] = R[i++];
while (j <= high) //将剩余的R[j.high]复制到T中
T[k++] = R[j++];
}//Merge
//归并2
void MSort(ElemType R[], ElemType T[], int low, int high) {
//R[low..high]归并排序后放入T[low..high]中
int mid;
ElemType *S = new ElemType[MAXSIZE];
if (low == high)
T[low] = R[low];
else {
mid = (low + high) / 2; //将当前序列一分为二,求出分裂点mid
MSort(R, S, low, mid); //对子序列R[low..mid] 递归归并排序,结果放入S[low..mid]
MSort(R, S, mid + 1, high); //对子序列R[mid+1..high] 递归归并排序,结果放入S[mid+1..high]
Merge(S, T, low, mid, high); //将S[low..mid]和S [mid+1..high]归并到T[low..high]
}//else
}
int main() {
SqList L;
L.r = new ElemType[MAXSIZE + 1];
L.length = 0;
// 输入数据,插入顺序表
printf("1.直接插入排序、2.折半插入排序、3.希尔排序、4.冒泡排序、5.快速排序、6.简单选择排序、7.归并排序\n\n");
printf("请在上方的七个算法中选择一个算法进行排序(输入编号)\n");
int i, t; //增量数组的长度
int *dt = new int[MAXSIZE]; //增量数组
int a = 0;
scanf("%d", &a);
while (1) {
switch (a) {
//注意在这里不能放一个大括号,不然会死循环
case 1:
printf("请先输入要排序的数据\n\n");
Create_Sq(L);
printf("1.直接插入排序\n");
InsertSort(L);
cout << "排序后最终的结果为:" << endl;
show(L);//打印
printf("请在上方的七个算法中选择一个算法进行排序(输入编号)\n");
scanf("%d", &a);
break;
case 2:
printf("请先输入要排序的数据\n\n");
Create_Sq(L);
printf("2.折半排序\n");
BInsertSort(L);
cout << "排序后最终的结果为:" << endl;
show(L);//打印
printf("请在上方的七个算法中选择一个算法进行排序(输入编号)\n");
scanf("%d", &a);
break;
case 3:
printf("请先输入要排序的数据\n\n");
Create_Sq(L);
printf("3.希尔排序\n");
cout << "请输入增量个数:\n";
cin >> t;
//把增量存入数组
for (i = 0; i < t; i++) {
cout << "第" << i + 1 << "个增量:\n";
cin >> dt[i];
}
ShellSort(L, dt, t);//希尔
cout << "排序后最终的结果为:" << endl;
show(L);//打印
printf("请在上方的七个算法中选择一个算法进行排序(输入编号)\n");
scanf("%d", &a);
break;
case 4:
printf("请先输入要排序的数据\n\n");
Create_Sq(L);
printf("4.冒泡排序\n");
BubbleSort(L);//冒泡
cout << "排序后最终的结果为:" << endl;
show(L);//打印
printf("请在上方的七个算法中选择一个算法进行排序(输入编号)\n");
scanf("%d", &a);
break;
case 5:
printf("请先输入要排序的数据\n\n");
Create_Sq(L);
printf("5.快速排序\n");
QSort(L, 1, L.length); //快速排序
cout << "排序后最终的结果为:" << endl;
show(L);//打印
printf("请在上方的七个算法中选择一个算法进行排序(输入编号)\n");
scanf("%d", &a);
break;
case 6:
printf("请先输入要排序的数据\n\n");
Create_Sq(L);
printf("6.简单选择排序\n");
SelectSort(L);//选择排序
cout << "排序后最终的结果为:" << endl;
show(L);//打印
printf("请在上方的七个算法中选择一个算法进行排序(输入编号)\n");
scanf("%d", &a);
break;
case 7:
printf("请先输入要排序的数据\n\n");
Create_Sq(L);
printf("7.简单选择排序\n");
SqList R;
MSort(L.r, L.r, 1, L.length);
cout << "排序后最终的结果为:" << endl;
show(L);//打印
printf("请在上方的七个算法中选择一个算法进行排序(输入编号)\n");
scanf("%d", &a);
break;
}
}
return 0;
}