常用的内部排序算法
一、 实验目的
1.掌握常见的内部排序算法的思想及其适用条件。
2.掌握常见的内部排序算法的程序实现。
二、 实验内容及要求
输入一组关键字序列分别实现下列排序:
(1) 实现简单选择排序、直接插入排序和冒泡排序。
(2) 实现希尔排序算法。
(3) 实现快速排序算法。
(4) 实现堆排序算法。
(5) * 快速排序的非递归算法。
(6) * 实现折半插入排序。
(7) 在主函数中设计一个简单的菜单,分别测试上述算法。
(8) * 综合训练:采用几组不同数据测试各个排序算法的性能(比较次数和移动次数)。
SortsAlgorithm.h
#ifndef DACM_ZSN_SORTSALGORITHM_H
#define DACM_ZSN_SORTSALGORITHM_H
#define MAXSIZE 100 /*参加排序元素的最大个数*/
typedef int KeyType;
typedef int InfoType;
typedef struct {
KeyType key;
InfoType otherinfo; // 其他字段
}RedType;
typedef struct
{
RedType r[MAXSIZE+1];
int length; /*参加排序元素的实际个数*/
}SqList;
void Swap(KeyType &key1,KeyType &key2);
void SL_print(SqList SL);
void DataInput(SqList &SL);
void DataInput1(SqList &L,int *arr);
void DataInput2(SqList &SL);
void SelectSort(SqList &L);
void InsertSort(SqList &L);
void MidInsertSort(SqList &L);
void ShellInsert(SqList &L,int dk);
void ShellSort(SqList &L,int dk[],int t);
void Swap(KeyType &a,KeyType &b);
void BubbleSort(SqList &L);
int Partition2(SqList &L, int left, int right);
void QSort(SqList &L,int low,int high);
void QuickSort(SqList &L);
//void HeapAdjust(SqList &L,int s,int m);
//void CreatHeap(SqList &L);
void HeapSort(SqList &L);
void menu();
void q_sort_stack(SqList &L, int n);
int partition(SqList &L, int left, int right);
//void quicksort2(vector<Comparable> &vec,int low,int high)
#endif //DACM_ZSN_SORTSALGORITHM_H
SortsAlgorithm.cpp
#include "SortsAlgorithm.h"
#include<iostream>
#include<vector>
#include<stack>
#include<cstdlib>
#include<algorithm>
#include <time.h>
using namespace std;
void SL_print(SqList SL) {
for (int i = 0; i < SL.length; i++) {
printf("%3d", SL.r[i]);
}
printf("\n");
}
void DataInput2(SqList &SL) {
printf("请输入需要排序的数据:\n");
int A[100], j = 0;
while (1) {
scanf("%d", A + j);
if (A[j] == -1)
break;
j++;
}
int i = 0;
SL.length = j;
// SL_Init(SL,j);
while (i < SL.length) {
SL.r[i].key = A[i];
i++;
}
}
void DataInput(SqList &SL) {
printf("请输入需要排序的数据:\n");
int A[10] = {9, 8, 5, 76, 13, 27, 9, 32, 2, 50};
int i = 0;
SL.length = 10;
while (i < SL.length) {
SL.r[i].key = A[i];
i++;
}
}
void DataInput1(SqList &L,int *array){
L.length=10;
for (int i = 0; i < L.length; ++i) {
L.r[i].key=*(array+i);
}
}
//简单选择排序
void SelectSort(SqList &L) {
int min = 0;
int n = L.length;
for (int i = 0; i < n - 1; ++i) {
min = i;
for (int j = i + 1; j < n; ++j) {
if (L.r[j].key < L.r[min].key) {
min = j;
}
}
if (i != min) {
Swap(L.r[i].key, L.r[min].key);
}
}
}
//插入排序,从小到大排序,升序
void InsertSort(SqList &L) {
int i, j;
//24 66 94 2 15 74 28 51 22 18 2
for (i = 2; i <= L.length; i++) {
if (L.r[i].key < L.r[i - 1].key) {
L.r[0] = L.r[i];//放到暂存位置
L.r[i] = L.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 + 1] = L.r[0];
}
}
}
//折半查找 插入排序
void MidInsertSort(SqList &L) {
int i, j, low, high, mid;
for (i = 2; i <= L.length; i++) {
L.r[0] = L.r[i];
low = 1;
high = i - 1;
while (low <= high)//先通过二分查找找到待插入位置
{
mid = (low + high) / 2;
if (L.r[mid].key > L.r[0].key)
high = mid - 1;
else
low = mid + 1;
}
for (j = i - 1; j >= high + 1; --j)
L.r[j + 1] = L.r[j];
L.r[high + 1] = L.r[0];
}
}
//希尔排序
void ShellInsert(SqList &L, int dk) {
int j;
for (int i = dk + 1; i < L.length; ++i) {
if (L.r[i].key < L.r[i - dk].key) {
L.r[0] = L.r[i];
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];
}
}
}
void ShellSort(SqList &L, int dk[], int t) {
//按增量序列dt【0.。t-1】对顺序表L做t趟希尔排序
for (int i = 0; i < t; ++i) {
ShellInsert(L, dk[i]);
}
}
//冒泡排序
void Swap(KeyType &a, KeyType &b) {
KeyType tmp;
tmp = a;
a = b;
b = tmp;
}
void BubbleSort(SqList &L) {
int i, j;
int flag = 1;
int m = L.length;
for (i = 0; i < m - 1; i++)//i最多访问到8
{
flag = 0;
for (j = m - 1; j > i; j--)//把最小值就放在最前面
{
if (L.r[j - 1].key > L.r[j].key) {
Swap(L.r[j - 1].key, L.r[j].key);
flag = 1;
}
}
}
}
//书上快排
int Partition2(SqList &L, int low, int high) {
int pivotkey;
L.r[0] = L.r[low];
pivotkey = L.r[low].key;
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];
}
L.r[low] = L.r[0];
return low;
}
void QSort(SqList &L, int low, int high) {
int pivotloc;
if (low < high) {
pivotloc = Partition2(L, low, high);
QSort(L, low, pivotloc - 1);
QSort(L, pivotloc + 1, high);
}
}
void QuickSort(SqList &L) {
QSort(L, 1, L.length);
}
//递归实现
//快速排序
int Partition(SqList &L, int left, int right) {
int k, i;//k记录要放入比分割值小的数据的位置
for (i = left, k = left; i < right; i++) {
if (L.r[i].key < L.r[right].key) {
Swap(L.r[k].key, L.r[i].key);
k++;
}
}
Swap(L.r[k].key, L.r[right].key);
return k;
}
void QuickSort(SqList &L, int low, int high) {
if (low < high) {
int pivotpos = Partition(L, low, high);//分割点左边的元素都比分割点要小,右边的比分割点大
QuickSort(L, low, pivotpos - 1);
QuickSort(L, pivotpos + 1, high);
}
}
//快速排序非递归
int partition(SqList &L, int left, int right)
{
int pivot = L.r[left].key;
while (left < right)
{
while (left < right && L.r[right].key >= pivot)
right--;
L.r[left] = L.r[right];
while (left < right && L.r[left].key <= pivot)
left++;
L.r[right] = L.r[left];
}
L.r[left].key = pivot;
return left;
}
void q_sort_stack(SqList &L, int n)
{
int left = 0;
int right = n - 1;
stack<int> s;
s.push(left);
s.push(right);
while(!s.empty())
{
right = s.top();
s.pop();
left = s.top();
s.pop();
int index = partition(L, left, right);
if (index - 1 > left)
{
s.push(left);
s.push(index - 1);
}
if (index + 1 < right)
{
s.push(index + 1);
s.push(right);
}
}
}
//堆排序
//void HeapAdjust(SqList &L,int s,int m){
// RedType rc=L.r[s];
// int j;
// for(j=2*s;j<=m;j*=2){
// if (j<m&&L.r[j].key<L.r[j+1].key)
// ++j;
// if (rc.key>=L.r[j].key)
// break;
// }
// L.r[s]=rc;
//}
//void CreatHeap(SqList &L){
// int n=L.length;
// int i;
// for (i = n/2; i > 0; --i) {
// HeapAdjust(L,i,n);
// }
//}
//void HeapSort(SqList &L){
// CreatHeap(L);
// RedType x;
// int i;
// for (i = L.length; i>1;--i) {
// x=L.r[1];
// L.r[1]=L.r[i];
// L.r[i]=x;
// HeapAdjust(L,1,i-1);
// }
//}
void AdjustDown(SqList &L, int k, int len) {
int dad = k;
int son = 2 * dad + 1; //左孩子下标
while (son <= len) {
if (son + 1 <= len && L.r[son].key < L.r[son + 1].key)//看下有没有右孩子,比较左右孩子选大的
{
son++;
}
if (L.r[son].key > L.r[dad].key)//比较孩子和父亲
{
Swap(L.r[son].key, L.r[dad].key);
dad = son;
son = 2 * dad + 1;
} else {
break;
}
}
}
void HeapSort(SqList &L) {
int i;
int len = L.length;
//建立大顶堆
for (i = len / 2; i >= 0; i--) {
AdjustDown(L, i, len);
}
Swap(L.r[0].key, L.r[len].key);//交换顶部和数组最后一个元素
for (i = len - 1; i > 0; i--) {
AdjustDown(L, 0, i);//剩下元素调整为大根堆
Swap(L.r[0].key, L.r[i].key);
}
}
void menu() {
printf("-------------------------------------\n");
printf("\t选择\n");
printf("1.简单选择排序\n");
printf("2.直接插入排序\n");
printf("3.冒泡排序\n");
printf("4.希尔排序\n");
printf("5.快速排序\n");
printf("6.堆排序\n");
printf("7.快速排序的非递归\n");
printf("8.折半插入排序\n");
printf("9.多组随机数测试\n");
printf("0.退出\n");
printf("-------------------------------------\n");
}
int main() {
while (1) {
SqList L;
// printf("\n未排序数据为:\n");
// DataInput(L);///////////
// int a1,i;
// srand((int)time(NULL));
// int A[11]={49,38,65,97,76,13,27,1,32,2,5};
// for (i = 0; i < 11; ++i) {
// a1=rand();
// int p=a1%(100-1+i)+1;
// L.r[i].key=p;
// L.r[i].key=A[i];
// }
// L.length=i+1;
// L.length;
DataInput(L);
// DataInput2(L);
SL_print(L);
int dk[] = {1, 3, 5, 7, 9, 11, 13};
menu();
int choice = 0;
scanf("%d", &choice);
switch (choice) {
case 1:
SelectSort(L);
SL_print(L);
break;
case 2://第一个无了
// L.length-=1;
InsertSort(L);
SL_print(L);
break;
case 3:
BubbleSort(L);
SL_print(L);
break;
case 4:
ShellSort(L, dk, 2);
SL_print(L);
break;
case 5://第一个无了
QuickSort(L);
// QuickSort(L,1,L.length-1);
SL_print(L);
break;
case 6://有问题
HeapSort(L);
SL_print(L);
break;
case 7://有问题
//快速排序非递归
q_sort_stack(L,L.length-1);
SL_print(L);
break;
case 8://有问题
MidInsertSort(L);
SL_print(L);
break;
case 9:
//其他多组数据测试
int a,i,j;
int arr[8][10];
SqList SL[8];
srand((int) time(NULL));
printf("待测试数据\n");
for (i = 0; i < 8; ++i) {
for (j = 0; j < 10; ++j) {
a = rand();
int p = a % (100 - 1 + j) + 1;
arr[i][j] = p;
}
DataInput1(SL[i],arr[i]);
SL_print(SL[i]);
}
printf("开始测试\n");
SelectSort(SL[0]);
SL_print(SL[0]);
InsertSort(SL[1]);
SL_print(SL[1]);
MidInsertSort(SL[2]);
SL_print(SL[2]);
// ShellSort(SL[3]);
BubbleSort(SL[3]);
SL_print(SL[3]);
QuickSort(SL[4]);
SL_print(SL[4]);
HeapSort(SL[5]);
SL_print(SL[5]);
q_sort_stack(SL[6],SL[6].length);
SL_print(SL[6]);
break;
case 0:
return 0;
}
}
}
生命依靠吸收负熵,避免了趋向平衡的衰退

浙公网安备 33010602011771号