定义一个排序类。要求如下:
(1)该类包含至少3种排序算法;
(2)其中一种排序算法为改进的快速排序,且最坏情况下的
算法复杂度为O(nlogn); (3)其中一种排序算法为堆排序;
一:实验思路:
排序类五种算法,分别是堆排序,快速排序,选择排序,冒泡排序,直接插入排序
- 直接插入排序法
基本思路:
1.从第一个元素开始,该元素可以认为已被排序;
2.取出下一个元素,在已经排序的元素序列中从后向前扫描;
3.如果该元素(已排序)大于新元素,将该元素移到下一个位置;
4.重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;
5.将新元素插入到该位置后,重复步骤2-5。
2.冒泡排序法
基本思路:
1.比较相邻的元素。如果第一个比第二个大,就交换他们两个。
2.对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。
3.持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
3.堆排序
基本思路:
1.初始化数组,创建大顶堆。大顶堆的创建从下往上比较,不能直接用无序数组从根节点比较,否则有的不符合大顶堆的定义。
2.交换根节点和倒数第一个数据,现在倒数第一个数据就是最大的。
3、重新建立大顶堆。
4、重复2、3的步骤,直到只剩根节点。
要实现从小到大的排序,就要建立大顶堆,即父节点比子节点都要大。
4.选择排序
基本思路:
每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。
5.快速排序
基本思路:
首先在待排序序列中选一个轴值(即比较的基准),通过一趟排序将待排序记录分割成独立的两部分,前一部分记录的关键码均小于或等于轴值,后一部分记录的关键码均大于或等于轴值,然后分别对这两部分重复上述方法,直到整个序列有序为止。
- 首先在序列中选择基准值,然后将除了基准值以外的进行划分。
- 即分为三部分
【比基准值小的数】 【基准值】 【比基准值大的数】
3.对【比基准值小的数】和【比基准值大的数】中的数据进行排序
源代码:/*4. 定义一个排序类。要求如下:
(1)该类包含至少3种排序算法;
(2)其中一种排序算法为改进的快速排序,且最坏情况下的
算法复杂度为O(nlogn); (3)其中一种排序算法为堆排序;*/
#include<iostream>
using namespace std;
void swap(int a[], int i, int j)//交换函数
{
int r = a[i];
a[i] = a[j];
a[j] = r;
}
class LYT
{
public:
void HeapSort(int tree[], int n);//堆排序
void quick(int array[], int low, int high);//快速排序
void select(int a[], int n);//选择排序
void bubbleSort(int w[], int n);//冒泡排序
void insertSort(int a[], int high);//直接插入法排序
private:
void Sift(int k, int last);
int partition(int A[], int low, int high);选取枢轴,分割序列
int length;//数组长度
int* data;
};
void LYT::insertSort(int a[], int high)//直接插入排序法
/*最差时间复杂度:O(n ^ 2)
最优时间复杂度:O(n)
平均时间复杂度:O(n ^ 2)
稳定性:稳定
*/
{
for (int j = 1; j < high; j++)
{
int key = a[j];
int i = j - 1;
while (i >= 0 && a[i] > key)
{
a[i + 1] = a[i];
i--;
}
a[i + 1] = key;
}
}
void LYT::bubbleSort(int w[], int n)//冒泡排序法
/*比较相邻的元素。如果第一个比第二个大,就交换他们两个。
对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
针对所有的元素重复以上的步骤,除了最后一个。
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
最差时间复杂度:O(n^2)
最优时间复杂度:O(n)
平均时间复杂度:O(n ^ 2)
稳定性:稳定*/
{
for (int i = 0; i < n - 1; i++)//外循环为排序趟数,n个数进行n-1趟
{
for (int j = 0; j < n - 1 - i; j++)// 内循环为每趟比较的次数,第i趟比较n-i次
{
if (w[j] > w[j + 1])
{
swap(w[j], w[j + 1]);
}
}
}
for (int i = 0; i < n; i++)
{
cout << w[i] << " ";
}
cout << endl << endl;
}
void LYT::select(int a[], int n)
{
for (int i = 0; i < n - 1; i++) {
for (int j = i + 1; j < n; j++) {
if (a[i] > a[j]) {
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
}
}
}
//快速排序
void LYT::quick(int array[], int low, int high)
{
if (low < high)
{
int k = partition(array, low, high);//获取low的位置
quick(array, low, k);//前
quick(array, k + 1, high);//后
}
}
int LYT::partition(int a[], int low, int high)
{
int mid = low + (high - low) / 2;
if ((a[low] - a[mid]) * (a[high] - a[mid]) < 0)//mid为中位
{
swap(a, low, mid);
}
else if ((a[low] - a[high]) * (a[mid] - a[high]) < 0)//high为中位
{
swap(a, low, high);
}
int key = low;//最前面的中位
while (low < high)//趟排序
{
while (a[high] >= a[key] && low < high)//从后往前,>中位,循环继续,反之跳出
--high;
while (a[low] <= a[key] && low < high)//从前往后,<中位,循环继续,反之跳出
++low;
//此时key,low,high位置元素大小关系:中大小
if (low < high)
swap(a, low, high);
//此时key,low,high位置元素大小关系:中小大
//直到low=high跳出
}
swap(a, low, key);
//此时key,low,high位置元素大小关系:小中大
return low;//返回位置
}
//堆
void LYT::Sift(int k, int last)
{
int i, j, temp;
i = k; j = 2 * i + 1; // i是被筛选结点,j是i的左孩子
while (j <= last) //筛选还没有进行到叶子
{
if (j < last && data[j] < data[j + 1]) j++; // j指向左右孩子的较大者
if (data[i] > data[j])
break; //已经是堆
else
{
swap(data[i], data[j]);
i = j; j = 2 * i + 1; //被筛结点位于原来结点j的位置
}
}
}
void LYT::HeapSort(int tree[], int n)
{
data = new int[n];
for (int i = 0; i < n; i++)
{
data[i] = tree[i];
}
length = n;
int i, temp;
for (i = ceil(length / 2) - 1; i >= 0; i--)//从最后一个分支结点根结点的数组下标
Sift(i, length - 1);
for (i = 1; i < length; i++)
{
temp = data[0]; data[0] = data[length - i]; data[length - i] = temp;//交换最后一位和最高位
Sift(0, length - i - 1); //重建堆
}
for (int i = 0; i < n; i++)
{
tree[i] = data[i];
}
}
void Begin()//主页面
{
cout << "我们的排序方式有: |" << endl;
cout << " 1.堆排序 |" << endl;
cout << " 2.快速排序 |" << endl;
cout << " 3.选择排序 |" << endl;
cout << " 4.冒泡排序 |" << endl;
cout << " 5.直接插入排序 |" << endl;
cout << " 输入0即可退出! |" << endl;
}
int main()
{
int key = 1;
while (1)
{
cout << "_______________________________________\n";
Begin();
cout << "_______________________________________\n";
cout << "请输入您想要的排序方式:" << endl;
cout << "========================================\n";
cin >> key;
if (key == 0)
{
cout << endl;
cout << "已退出" << endl;
break;
}
cout << "请您输入数字个数:";
cout << endl;
int n;
cin >> n;
cout << "您所需要的排序数字是:";
cout << endl;
int* c = new int[n];
for (int i = 0; i < n; i++)
{
cin >> c[i];
}
LYT s;
if (key == 1)
{
cout << "使用堆排序后数组为:";
s.HeapSort(c, n);
}
else if (key == 2)
{
cout << "使用快速排序后数组为:";
s.quick(c, 0, n - 1);
}
else if (key == 3)
{
cout << "使用选择排序后数组为:";
s.select(c, n);
}
else if (key == 4)
{
cout << "使用冒泡排序后数组为:";
s.bubbleSort(c, n);
}
else if (key == 5)
{
cout << "使用直接插入排序后数组为:";
s.insertSort(c, n);
}
for (int i = 0; i < n; i++)
{
cout << c[i] << ' ';
}
cout << endl;
}
}
运行结果: