插入排序、冒泡排序、选择排序、快速排序
1.插入排序
插入排序,其实就像打牌一样,每一次从未添加数列中(牌堆)里面选取最近的一个关键字(数),将这个数插入到已添加数列(手牌)中。然后,因为插入的时候是需要进行对这些数进行平移的,所以,我们在平移的时候需要将这一个需要插入的数存放在我们的0号下标位置,这样的话就可以对插入位置的右边部份进行平移操作。(当然,如果已经是比它的前一个数要大的话,那就不需要再进一步比较了)直到所有未添加数列(牌库)中的数都插入到相应的位置(手牌)中,这样的话就完成了排序操作
//插入排序
void InsertSort(int a[17]) {
int times = 0;//移动次数
int find = 0; //比较次数
int m = 0;
cout << "输出插入排序过程:" << endl;
for (int i = 2; i < 17; i++) {
if (a[i] < a[i - 1]) {
find++;
a[0] = a[i];//将a[i]记录在a[0]中
a[i] = a[i - 1];
for (int j = i - 2; a[0] < a[j]; j--) {
times++;
a[j + 1] = a[j];
a[j] = a[0]; //书本上有问题
}
}
cout << "第" << ++m << "次排序"; Read(a);
}
cout << "移动的次数为:" << find << endl;
cout << "比较的次数为:" << times << endl;
}
2.冒泡排序
冒泡排序就像是他的名字一样,在我们进行升序排序的时候,其实就是将比较大的数往后面放的一个过程。具体做法就是在每一趟的交换的时候,每一次都比较相邻的两个数,然后将比较大的数交换到后面,这样的话每一趟都可以的到大于等于1个已近是排好顺序的逆序数列。但是,由于算法的不一样,其实也有可能即使是已经得到了已经排好序的序列,但是还是会继续进行比较。
这时候就可以做一个哨兵来记录当前进行交换的最后一个元素的下标,这样的话下一次排序的时候就会从哨兵对应的下标那里开始。
//冒泡排序
void Bubble(int a[17]) {
int times = 0; //次数
int find = 0; //比较次数
cout << "输出冒泡排序过程:" << endl;
for (int i = 1; i < 17; i++) {
for (int j = 1; j < 17 - i ; j++) {
int temp;
times++;
if (a[j] > a[j + 1]) {
find++;
temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
cout << "第" << i << "次排序"; Read(a);
}
cout << "移动的次数为:" <<find<<endl;
cout << "比较的次数为:" << times << endl;
}
3.快速排序
其实快速排序跟冒泡排序相似,都是要消除逆序。但是,冒泡排序在一趟排序中,每一次排序最多只能够交换相邻的两个数,而快速排序却能够交换两个不相邻的数,从而消除多个逆序。
在进行快速排序的时候通常会选取当前数组中的第一个元素当做枢轴(或支点),将其设置为一个关键字,然后将所有大于这个数都放到右边,将所有小于这个数都放在左边。这样的话每一次下来都会分成很两个子表,然后重复上面的做法,直到所有的子表都只剩下一个元素的时候,排序完成。
做法就是:利用动态规划的思想,可以将这个大的问题转换成一个个小的问题。也就是可以利用递归的方法实现了。
//快速排序
int loc; //记录位置
int times1 = 0; //比较次数
int find1 = 0; //移动次数
int m1 = 1;
int Partition(int a[17], int low, int hight) {
m1++;
cout << "第" << m1-1 << "次排序"; Read(a);
//寻找当前序列中需要交换的下标
a[0] = a[low]; //作为关键词进行存储
int key = a[low];
while (low < hight) {
while (low < hight && a[hight] >= key) { hight--; times1++; }
a[low] = a[hight]; find1++; //将比Key小的记录移到低端
while (low < hight && a[low] <= key) { low++; times1++; }
a[hight] = a[low]; find1++;//将比Key大的数移到高端
}
a[low] = a[0];
return low;
}
void QSort(int a[17], int low, int hight) {
//调用当前初值;low = 1;hight = 16
if (low < hight) { //结束条件为当low==hight
loc = Partition(a, low, hight);
QSort(a, low, loc - 1); //往左移
QSort(a, loc + 1, hight); //往右移
}
}
void QuickSort(int a[17]) {
QSort(a, 1, 16); //这里高位输入的是实际长度
cout << "移动的次数为:" << find1 << endl;
cout << "比较的次数为:" << times1 << endl;
}
总代码:
#include<iostream>
#include<ctime>
using namespace std;
/*以下所有的排序用的都是升序*/
//构造一个随机函数
void RandomNum(int a[17]) {
srand((unsigned)time(NULL));
for(int i=1;i<=16;i++)
a[i] = rand() % 89+10;
}
//读出
void Read(int a[17]) {
for (int i = 1; i < 17; i++) {
cout << a[i] << " ";
}
cout << endl;
}
//插入排序
void InsertSort(int a[17]) {
int times = 0;//移动次数
int find = 0; //比较次数
int m = 0;
cout << "输出插入排序过程:" << endl;
for (int i = 2; i < 17; i++) {
if (a[i] < a[i - 1]) {
find++;
a[0] = a[i];//将a[i]记录在a[0]中
a[i] = a[i - 1];
for (int j = i - 2; a[0] < a[j]; j--) {
times++;
a[j + 1] = a[j];
a[j] = a[0]; //书本上有问题
}
}
cout << "第" << ++m << "次排序"; Read(a);
}
cout << "移动的次数为:" << find << endl;
cout << "比较的次数为:" << times << endl;
}
//冒泡排序
void Bubble(int a[17]) {
int times = 0; //次数
int find = 0; //比较次数
cout << "输出冒泡排序过程:" << endl;
for (int i = 1; i < 17; i++) {
for (int j = 1; j < 17 - i ; j++) {
int temp;
times++;
if (a[j] > a[j + 1]) {
find++;
temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
cout << "第" << i << "次排序"; Read(a);
}
cout << "移动的次数为:" <<find<<endl;
cout << "比较的次数为:" << times << endl;
}
//选择排序
void SelectSorct(int a[17]) {
int times = 0; //比较次数
int find = 0; //移动次数
int k = 0;
cout << "输出选择排序过程:" << endl;
for (int i = 1; i < 16; i++) {
k = i;
for (int j = i + 1; j <= 16; j++) {
if (times++,a[j] < a[k]) { k = j; }
if (k != i) {
int temp;
temp = a[i];
a[i] = a[k];
a[k] = temp;
find++;
}
}
cout << "第" << i << "次排序"; Read(a);
}
cout << "移动的次数为:" << find << endl;
cout << "比较的次数为:" << times << endl;
}
//快速排序
int loc; //记录位置
int times1 = 0; //比较次数
int find1 = 0; //移动次数
int m1 = 1;
int Partition(int a[17], int low, int hight) {
m1++;
cout << "第" << m1-1 << "次排序"; Read(a);
//寻找当前序列中需要交换的下标
a[0] = a[low]; //作为关键词进行存储
int key = a[low];
while (low < hight) {
while (low < hight && a[hight] >= key) { hight--; times1++; }
a[low] = a[hight]; find1++; //将比Key小的记录移到低端
while (low < hight && a[low] <= key) { low++; times1++; }
a[hight] = a[low]; find1++;//将比Key大的数移到高端
}
a[low] = a[0];
return low;
}
void QSort(int a[17], int low, int hight) {
//调用当前初值;low = 1;hight = 16
if (low < hight) { //结束条件为当low==hight
loc = Partition(a, low, hight);
QSort(a, low, loc - 1); //往左移
QSort(a, loc + 1, hight); //往右移
}
}
void QuickSort(int a[17]) {
QSort(a, 1, 16); //这里高位输入的是实际长度
cout << "移动的次数为:" << find1 << endl;
cout << "比较的次数为:" << times1 << endl;
}
int main() {
int a[17];
a[0] = { -1 };
int b[17]; //创建另外一个做存放
RandomNum(a);
cout << "---输出随机生成的数---" << endl;
Read(a);
//插入排序
memcpy(b, a, sizeof(int) * 17);
InsertSort(b);
cout << "---输出插入排序后的顺序---" << endl;
Read(b);
//冒泡排序
memcpy(b, a,sizeof(int)*17); //复制函数
Bubble(b);
cout << "---输出冒泡排序后的顺序---" << endl;
Read(b);
//选择排序
memcpy(b, a, sizeof(int) * 17);
SelectSorct(b);
cout << "---输出选择排序后的排序---" << endl;
Read(b);
//快速排序
memcpy(b, a, sizeof(int) * 17);
QuickSort(b);
cout << "---输出快速排序的排序---" << endl;
Read(b);
}