一、實驗目的
(1)掌握各種排序算法的基本思想;
(2)掌握各種排序算法的實現方法。
二、實驗內容
對一組數據進行排序,可選擇直接插入排序、折半插入排序、希爾排序、冒泡排序、快速排序、簡單選擇排序、堆排序和2-路歸併排序算法實現。
要求:設計菜單,根據菜單提示進行操作。
三、算法代碼
#include <iostream>
#include <iomanip>
#include <stdlib.h>
#include <time.h>
#include <cmath>
using namespace std;
#define MAXSIZE 10
typedef int KeyType;
typedef int InfoType;
typedef struct {
KeyType key;
InfoType otherinfo;
} RedType;
typedef struct {
RedType r[MAXSIZE + 1];
int length;
} SqList;
//打印
void print(SqList &t) {
for (int i = 1; i <= t.length; i++) {
if ((i - 1) % 10 == 0)
cout << endl;
cout <<" "<< t.r[i].key;
}
cout << endl;
}
//產生隨機數
void producerandom(SqList &t) {
srand(time(NULL));
for (int i = 1; i <= MAXSIZE; i++)
t.r[i].key = rand() % 100;
t.length = MAXSIZE;
print(t);
}
//直接插入排序
void InsertSort(SqList &t) {
for (int i = 2; i <= t.length; i++) {
if (t.r[i].key < t.r[i - 1].key) {
int j;
t.r[0] = t.r[i];
t.r[i] = t.r[i - 1];
for (j = i - 2; t.r[j].key > t.r[0].key; j--) {
t.r[j + 1] = t.r[j];
}
t.r[j + 1] = t.r[0];
}
}
}
//折半插入排序
void BInsertSort(SqList &t) {
for (int i = 2; i <= t.length; i++) {
int low, high, m;
t.r[0] = t.r[i];
low = 1;
high = i - 1;
while (low <= high) {
m = (low + high) / 2;
if (t.r[0].key < t.r[m].key)
high = m - 1;
else
low = m + 1;
}
for (int j = i; j > high + 1; j--) {
t.r[j] = t.r[j - 1];
}
t.r[high + 1] = t.r[0];
}
}
//希爾排序
void ShellInsert(SqList &t, int dk) {
for (int i = dk + 1; i <= t.length; i++) {
if (t.r[i].key < t.r[i - dk].key) {
int j;
t.r[0] = t.r[i];
t.r[i] = t.r[i - dk];
for (j = i - 2 * dk; j > 0 && (t.r[j].key > t.r[0].key); j = j - dk)
t.r[j + dk] = t.r[j];
t.r[j + dk] = t.r[0];
}
}
}
void ShellSort(SqList &t) {
int temp = t.length, i, j;
int *const dt = (int *)malloc(sizeof(int) * t.length);
for (i = 0; temp != 0; i++) {
//增量序列參考某文章,對於length<10000時的較高效率
temp = temp / 3;
dt[i] = temp + 1;
}
for (int j = 0; j <= i - 1; j++)
ShellInsert(t, dt[j]);
}
//冒泡排序
void BubbleSort(SqList &t) {
int m, j, flag = 1;
m = t.length - 1;
while (m > 0 && flag) {
flag = 0;
for (j = 1; j <= m; j++) {
if (t.r[j].key > t.r[j + 1].key) {
flag = 1;
t.r[0] = t.r[j];
t.r[j] = t.r[j + 1];
t.r[j + 1] = t.r[0];
}
}
m--;
}
}
//快速排序
void QuickSort(SqList &t, int low, int high) {
if (low < high) {
int left = low, right = high;
t.r[0] = t.r[low];
while (low < high) {
while (low < high && t.r[high].key >= t.r[0].key)
high--;
t.r[low] = t.r[high];
while (low < high && t.r[low].key <= t.r[0].key)
low++;
t.r[high] = t.r[low];
}
t.r[low] = t.r[0];
QuickSort(t, left, low - 1);
QuickSort(t, low + 1, right);
}
}
//簡單選擇排序
void SelectSort(SqList &t) {
int min;
for (int i = 1; i < t.length; i++) {
min = i;
for (int j = i + 1; j <= t.length; j++) {
if (t.r[j].key < t.r[min].key)
min = j;
}
if (min != i) {
t.r[0] = t.r[min];
t.r[min] = t.r[i];
t.r[i] = t.r[0];
}
}
}
//篩選堆
void HeapAdjust(SqList &t, int s, int m) {
t.r[0] = t.r[s];
for (int i = 2 * s; i <= m; i *= 2) {
if (i < m && t.r[i].key < t.r[i + 1].key)
i++;
if (t.r[0].key >= t.r[i].key)
break;
t.r[s] = t.r[i];
s = i;
}
t.r[s] = t.r[0];
}
//創建堆
void CreateHeap(SqList &t) {
int n = t.length;
for (int i = n / 2; i >= 1; i--) {
HeapAdjust(t, i, n);
}
}
//堆排序
void HeapSort(SqList &t) {
CreateHeap(t);
for (int i = t.length; i >= 2; i--) {
t.r[0] = t.r[1];
t.r[1] = t.r[i];
t.r[i] = t.r[0];
HeapAdjust(t, 1, i - 1);
}
}
//歸併
void Merge(SqList &t, RedType *&S, int low, int high) {
int i = low, k = low, mid = (low + high) / 2;
int j = mid + 1;
while (i <= mid && j <= high) {
if (t.r[i].key <= t.r[j].key)
S[k++] = t.r[i++];
else
S[k++] = t.r[j++];
}
while (i <= mid)
S[k++] = t.r[i++];
while (j <= high)
S[k++] = t.r[j++];
for (int m = low; m <= high; m++)
t.r[m] = S[m];
}
//歸併排序
void MergeSort(SqList &t, RedType *&S, int low, int high) {
if (low >= high) {
S[low] = t.r[low];
} else {
int mid = (low + high) / 2;
MergeSort(t, S, low, mid);
MergeSort(t, S, mid + 1, high);
Merge(t, S, low, high);
}
}
void menu() {
cout << endl;
cout << " ----排序操作---- " << endl;
cout << "************************" << endl;
cout << "* 1---產生隨機數 *" << endl;
cout << "* 2---直接插入排序 *" << endl;
cout << "* 3---折半插入排序 *" << endl;
cout << "* 4---希爾排序 *" << endl;
cout << "* 5---冒泡排序 *" << endl;
cout << "* 6---快速排序 *" << endl;
cout << "* 7---簡單選擇排序 *" << endl;
cout << "* 8---堆排序 *" << endl;
cout << "* 9---歸併排序 *" << endl;
cout << "* 0---退出 *" << endl;
cout << "************************" << endl;
cout << "請選擇菜單(0-9):";
}
int List() {
int n = -1, flag = 0;
SqList T, R;
RedType *S = (RedType *)malloc(sizeof(RedType) * T.length + 1);
while (n != 0) {
menu();
cin >> n;
switch (n) {
case 1:
cout << "產生隨機數如下" ;
producerandom(T);
flag = 1;
break;
case 2:
if (flag) {
cout << "直接插入排序" ;
R = T;
InsertSort(R);
print(R);
} else {
cout << "請先產生隨機數" << endl;
}
break;
case 3:
if (flag) {
cout << "折半插入排序" ;
R = T;
BInsertSort(R);
print(R);
} else {
cout << "請先產生隨機數" << endl;
}
break;
case 4:
if (flag) {
cout << "希爾排序" ;
R = T;
ShellSort(R);
print(R);
} else {
cout << "請先產生隨機數" << endl;
}
break;
case 5:
if (flag) {
cout << "冒泡排序";
R = T;
BubbleSort(R);
print(R);
} else {
cout << "請先產生隨機數" << endl;
}
break;
case 6:
if (flag) {
cout << "快速排序";
R = T;
QuickSort(R, 1, R.length);
print(R);
} else {
cout << "請先產生隨機數" << endl;
}
break;
case 7:
if (flag) {
cout << "簡單選擇排序" ;
R = T;
SelectSort(R);
print(R);
} else {
cout << "請先產生隨機數" << endl;
}
break;
case 8:
if (flag) {
cout << "堆排序" ;
R = T;
HeapSort(R);
print(R);
} else {
cout << "請先產生隨機數" << endl;
}
break;
case 9:
if (flag) {
cout << "歸併排序" ;
R = T;
MergeSort(R, S, 1, R.length);
print(R);
} else {
cout << "請先產生隨機數" << endl;
}
break;
case 0:
cout << "退出成功" << endl;
break;
default:
cout << "輸入數字錯誤,請重新輸入" << endl;
break;
}
}
return 0;
}
int main() {
List();
return 0;
}
作者文壇寫於2020年6月6日