数据结构 排序

 定义一个排序类。要求如下:

(1)该类包含至少3种排序算法;

(2)其中一种排序算法为改进的快速排序,且最坏情况下的

算法复杂度为O(nlogn); (3)其中一种排序算法为堆排序

 

一:实验思路:

排序类五种算法,分别是堆排序,快速排序,选择排序,冒泡排序,直接插入排序

  1. 直接插入排序法

基本思路:

1.从第一个元素开始,该元素可以认为已被排序;

2.取出下一个元素,在已经排序的元素序列中从后向前扫描;

3.如果该元素(已排序)大于新元素,将该元素移到下一个位置;

4.重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;

5.将新元素插入到该位置后,重复步骤2-5。

          2.冒泡排序法

基本思路:

1.比较相邻的元素。如果第一个比第二个大,就交换他们两个。

2.对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。

3.持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

 

          3.堆排序

基本思路:

1.初始化数组,创建大顶堆。大顶堆的创建从下往上比较,不能直接用无序数组从根节点比较,否则有的不符合大顶堆的定义。

2.交换根节点和倒数第一个数据,现在倒数第一个数据就是最大的。

3、重新建立大顶堆。

4、重复2、3的步骤,直到只剩根节点。

要实现从小到大的排序,就要建立大顶堆,即父节点比子节点都要大。

          4.选择排序

基本思路:

每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。

 

         5.快速排序

基本思路:

首先在待排序序列中选一个轴值(即比较的基准),通过一趟排序将待排序记录分割成独立的两部分,前一部分记录的关键码均小于或等于轴值,后一部分记录的关键码均大于或等于轴值,然后分别对这两部分重复上述方法,直到整个序列有序为止。

  1. 首先在序列中选择基准值,然后将除了基准值以外的进行划分。
  2. 即分为三部分

【比基准值小的数】 【基准值】 【比基准值大的数】

     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;

}

 

}

 

运行结果:

4071f6e9e36f4b339ff143c592d4b8c1.png

 bc1794f201d04573b1dad7fdb24de955.png

 c60c85c246a547be8c55d5346d0a9990.png

 66789bb648f2440aa9ce0a320c6fd50c.png

 9e91235e33f94463b8bd556244566174.png

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值