您的位置:首页 > 理论基础 > 数据结构算法

c++实现数据结构中的各种排序方法:直接插入、选择,归并、冒泡、快速、堆排序、shell排序

2016-12-19 18:09 816 查看
#include "iostream"
using namespace std;
/*(1) 直接插入排序 (2)(Bonus) 希尔排序(增量为5,2,1) (3) 起泡排序

(4) 快速排序 (5) 直接选择排序 (6)(Bonus) 堆排序 (7)(Bonus)二路归并排序

*/

void swap(int &a, int &b)
{
int c = a;
a = b;
b = c;
}

//冒泡排序的思想:从最后一位开始和前一位比较,如果小于就交换,一直进行下去,每一次都会找到一个最小值,总共要进行n-1步
void sort_Bubble(int a[], int len)
{
for (int i = 0; i < len - 1; i++)     //进行n-1步
{
for (int j = len - 1; j>i; j--)    //从最后一个开始,前i个已经是有序的了,所以不需要在比较了,j>i
{
if (a[j] < a[j - 1])
swap(a[j], a[j - 1]);           //交换
}

}
}

//直接插入的思想:将紧挨着前面已经排好序的数和前一个比较,如果大于前面一个就不用执行,如果小于前面一个数就要一直和前面的数进行比较,直到找到要插入的位置
void sort_insert(int a[], int len)
{
int i, j;
for (i = 1; i < len; i++)   //先假设第一个数已经是有序的了,所以从第二个数开始比较
{
if (a[i] < a[i - 1])    //如果前面一个数小就执行下面的步骤(从小到大排序)
{
int temp = a[i];     //首先将这个数储存起来,以免后面移动会丢失
for (j = i - 1; j >= 0 && a[j]>temp; j--)    //从i-1位开始移动,边移动边判断前面是否还有数比temp大,找到合适的位置插入,结束的标志是j<0||temp>=a[j],就不需要移动了直接插入在j+1的位置
a[j + 1] = a[j];    //后移
a[j + 1] = temp;   //将temp插入
}
}
}

//选择排序的思想:先假设一个最小值,然后向后比较,如果面有更小的就交换,同时最小值变成这个数再次比较直到一个循环结束,因为最后一个数不用比较,所以要进行n-1步
void sort_select(int a[], int len)
{
for (int i = 0; i < len- 1; i++)
{
int min = a[i];     //假设最小值
for (int j = i + 1; j < len; j++)
{
if (min>a[j])
{
min = a[j];      //改变最小值
swap(a[i], a[j]);  //交换数
}

}

}
}

//这是选择排序的第二种方法:直接用下标来选择
void sort_select_1(int a[], int len)
{
for (int i = 0; i < len - 1; i++)
{
int min = i;   //假设最小值的下标为min
for (int j = i + 1; j<len; j++)
{
if (a[min] > a[j])
min = j;    //记录下标
swap(a[min], a[i]);   //交换数据
}
}
}

//shell排序:通过增量的方法将一个数组的数据分成若干组,然后在每一个分组中执行直接插入排序,然后减少增量gap,直到增量gap等于1的时候
//增量的定义是下标之差,起始是0,然后对应的是下标为0+gap的是一组,继续向后寻找,直到完结(gap<n);
/*
void sort_shell(int a[], int n)
{
int i, j, gap,k;
for (gap = n / 2; gap > 0; gap /= 2)    //定义增量gap,起始的增量为n/2,然后减少两倍
{
for (i = 0; i < gap; i++)           //对每一个分组进行排序,0-gap表示每一组中的第一个数的下标,这也是分的组数(gap)
{
for (j = i + gap; j < n; j = j + gap)   //插入排序的思想就是假设第一个已经是有序的,所以就从一组的第二个数开始排序(i+gap)
{
if (a[j] < a[j - gap])    //因为一组中的数据的下标都是相差gap,所以下标为0-gap之间的数都是每一组中的第一个数(没有排序之前)
{                         //下面就是执行直接插入排序
int temp = a[j];      //将带插入的数据存储
for (k = j - gap; k >= 0 && temp < a[k]; k = k - gap)   //每一个数据的下标都是相差gap,所以k=k-gap
{
a[k + gap] = a[k];
}
a[k + gap] = temp;           //插入

}
}
}
}

}
*/

//这是对shell排序的每一个分组的排序
void group_shell(int a[], int n,int gap)
{
int j, k;
for (int i = 0; i < gap; i++)
{
for (j = i + gap; j < n; j += gap)
{
if (a[j] < a[j - gap])
{
int temp = a[j];
for (k = j - gap; k >= 0 && temp < a[k]; k = k-gap)
{
a[k+ gap] = a[k];
}
a[k+ gap] = temp;
}
}
}

}
//这是调用对数组排序
void sort_shell(int a[], int n)
{
/*
for (int gap = n / 2; gap >0; gap = gap / 2)
{
group_shell(a, n, gap);

}
*/

group_shell(a, n, 5);
group_shell(a, n, 3);
group_shell(a, n, 2);
group_shell(a, n, 1);
}

int main()
{
int a[5] = { 22, 33, 4, 11, 77 };
//  sort_Bubble(a, 4);

//  sort_insert(a, 4);

//sort_select_1(a, 4);
sort_shell(a, 5);

for (int i = 0; i < 5; i++)
{
cout << a[i] << "  ";
}

return 0;

}


//等待后面还会陆续更新新的排序方式,这里只是更新了几种,希望大家一起学习
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息