#include<iostream>
#include<iomanip>
#include<cstdlib>
#include<ctime>
#include<cmath>
using namespace std;
#define MAXSIZE 10000
#define DATA_NUM_PER_LINE 20
#define MAX_DATA 9999
#define MIN_DATA 10
typedef int KeyType;
typedef struct {
KeyType key;
int other_imformation;
}RedType;
typedef struct {
RedType r[MAXSIZE + 1];
int length;
}Sqlist;
void PrintList(Sqlist& L)
{//遍历顺序表
for (int i = 1; i < L.length; i++)
{
cout << setw(6) << setfill(' ') << L.r[i].key << " ";
if (i % DATA_NUM_PER_LINE == 0)
cout << endl; //每DATA_NUM_PER_LINE个数据一换行
}
cout << endl << "PrintList Over" << endl;
return;
}
void InsertSort(Sqlist L)
{//直接插入排序法
clock_t start_t, end_t;
double total_t;
int num = 0, j;
start_t = clock();
for (int i = 2; i < L.length; ++i)
{
if (++num && L.r[i].key < L.r[i - 1].key)
{
L.r[0].key = L.r[i].key;
L.r[i].key = L.r[i - 1].key;
for (j = i - 2; ++num && L.r[0].key < L.r[j].key; --j)
{
L.r[j + 1].key = L.r[j].key;
}
L.r[j + 1].key = L.r[0].key;
}
}
printf("InsertSort:\n");
PrintList(L);
end_t = clock();
total_t = (double)(end_t - start_t) / CLOCKS_PER_SEC;
printf("计算用时%f秒\n", total_t);
cout << "比较次数为:" << num << endl << endl;
return;
}
void BubbleSort(Sqlist L)
{//冒泡排序
clock_t start_t, end_t;
double total_t;
int num = 0; //比较次数
start_t = clock();
for (int i = 1; i < L.length; i++) //共L.length-1次
{
for (int j = 1; j < L.length - i; j++)
{
num++;
if (L.r[j].key > L.r[j + 1].key)
{
swap(L.r[j].key, L.r[j + 1].key);
}
}
}
printf("BubbleSort:\n");
PrintList(L);
end_t = clock();
total_t = (double)(end_t - start_t) / CLOCKS_PER_SEC;
printf("计算用时%f秒\n", total_t);
cout << "比较次数为:" << num << endl << endl;
return;
}
void SelectSort(Sqlist L)
{//选择排序
clock_t start_t, end_t;
double total_t;
start_t = clock();
int i, j, min, num = 0;
for (i = 1; i < L.length - 1; i++)
{
min = i;
for (j = i + 1; j < L.length; j++)
{
if (++num && L.r[min].key > L.r[j].key)
{
min = j;
}
}
if (++num && min != i)
{
swap(L.r[i].key, L.r[min].key);
}
}
end_t = clock();
printf("SelectSort:\n");
PrintList(L);
total_t = (double)(end_t - start_t) / CLOCKS_PER_SEC;
printf("计算用时%f秒\n", total_t);
cout << "比较次数为:" << num << endl << endl;
return;
}
int Patition(Sqlist& L, int low, int high, int& num) //把顺序表一分为二,并且返回枢轴位置
{
int pivotvalue = L.r[low].key; //用第一个数作为枢轴,pivotvalue保存枢轴的值
while (++num && low < high) //当low==high时两边相遇了,结束一趟排序
{
while (++num && low < high && L.r[high].key >= pivotvalue) //先从右往左找比pivotvalue小的数,
high--;
L.r[low].key = L.r[high].key; //找到后放到前边
while (++num && low < high && L.r[low].key <= pivotvalue) //从前往后找比pivotvalue大的数
low++;
L.r[high].key = L.r[low].key; //放到后边
}
L.r[low].key = pivotvalue; //枢轴此时放到low和high相遇的地方
return low; //返回枢轴位置
}
void QuickSort(Sqlist& L, int low, int high, int& num)
{//快速排序
int pivotloc;
if (++num && low < high) //长度大于1
{
pivotloc = Patition(L, low, high, num);
QuickSort(L, low, pivotloc - 1, num);
QuickSort(L, pivotloc + 1, high, num);
}
return;
}
void QuickSort(Sqlist L)
{
clock_t start_t, end_t;
double total_t;
int num = 0;
start_t = clock();
QuickSort(L, 1, L.length - 1, num);
end_t = clock();
printf("QuickSort:\n");
PrintList(L);
total_t = (double)(end_t - start_t) / CLOCKS_PER_SEC;
printf("计算用时%f秒\n", total_t);
cout << "比较次数为:" << num << endl << endl;
return;
}
void ShellInsert(Sqlist& L, int dk, int& num)
{//对顺序表L做一趟希尔插入排序,di为该趟排序的增量
int j;
for (int i = 1 + dk; i < L.length; ++i)// 1+di为第一个子序列的第二个元
if (++num && L.r[i - dk].key > L.r[i].key)
{
L.r[0].key = L.r[i].key;//备份L->r[i](不做监视哨)
for (j = i - dk; ++num && j > 0 && L.r[0].key < L.r[j].key; j -= dk)
{
L.r[j + dk].key = L.r[j].key;
}
L.r[j + dk].key = L.r[0].key;
}
return;
}
void ShellSort(Sqlist L)
{//对顺序表L按增量序列delta[0] ~ dlta[dlta_num-1]做希尔排序
clock_t start_t, end_t;
double total_t;
start_t = clock();
int num = 0, dlta_num = (int)(log(L.length + 1) / log(2));
int* dlta = new int[dlta_num];
for (int i = 0; i < dlta_num; i++) {
dlta[i] = (int)pow(2, dlta_num - i) - 1; //dlta[i]=2^(dlta_num-i)-1
}
for (int i = 0; i < dlta_num; i++)
ShellInsert(L, dlta[i], num);
end_t = clock();
delete[] dlta;
printf("ShellSort:\n");
PrintList(L);
total_t = (double)(end_t - start_t) / CLOCKS_PER_SEC;
printf("计算用时%f秒\n", total_t);
cout << "比较次数为:" << num << endl;
return;
}
void HeadAdjust(RedType* R, int low, int high, int& num)
{
int i = low, j = 2 * i;
RedType tmp = R[i];
while (++num && j <= high)
{
if (++num && j < high && R[j].key < R[j + 1].key)
j++;
if (++num&& tmp.key < R[j].key)
{
R[i] = R[j];
i = j;
j = 2 * i;
}
else break;
}
R[i] = tmp;
return;
}
void HeadSort(Sqlist L)
{//堆排序
clock_t start_t, end_t;
double total_t;
int num = 0, i;
int n = L.length - 1;
start_t = clock();
RedType R = L.r[0];
for (i = n / 2; i > 0; i--)
HeadAdjust(L.r, i, n, num);
for (i = n; i > 1; i--)
{
swap(L.r[1], L.r[i]);
HeadAdjust(L.r, 1, i - 1, num);
}
end_t = clock();
printf("HeadSort:\n");
PrintList(L);
total_t = (double)(end_t - start_t) / CLOCKS_PER_SEC;
printf("计算用时%f秒\n", total_t);
cout << "比较次数为:" << num << endl;
return;
}
int main()
{
Sqlist* P = new Sqlist;
Sqlist& L = *P;
cout << "请输入顺序的长度:" << endl;
cin >> L.length;
L.length++;
if (L.length > MAXSIZE)
{
printf("已满");
return -1;
}
else
{
srand((unsigned)time(NULL));
for (int i = 1; i < L.length; i++)
{
L.r[i].key = (rand() % (MAX_DATA - MIN_DATA) + MIN_DATA);
}
}
PrintList(L);
cout << endl;
InsertSort(L);//直接插入排序
BubbleSort(L);//起泡排序
SelectSort(L);//选择排序
QuickSort(L);//快速排序
ShellSort(L);//希尔排序
HeadSort(L);//堆排序
system("pause");
return 0;
}
华中科技大学数据结构实验——内部排序代码
于 2023-04-05 19:55:40 首次发布