前言
重新温习数据结构与算法,对一些常用的算法进行代码实现。一、冒泡排序
1. 代码实现
#include<bits/stdc++.h>
using namespace std;
#define maxSize 100
typedef struct
{
int Elem[maxSize]; //存储元素
int length; //元素数组长度
}SqList;
void sortMP(SqList &ql)
{
int i,j; //两层循环的标志位
bool flag = false; //改进冒泡排序(减少冒泡次数)的标记位
for(i=0;i<ql.length-1&&flag==false;i++) //冒泡轮次=数组长度-1,且在flag为false的时候进行冒泡
{
flag = true; //默认进行一个轮次冒泡的时候,将flag置为true
for(j=0;j<ql.length-i;j++) //一个轮次冒泡的具体交换遍历
{
if(ql.Elem[j]>ql.Elem[j+1]) //如果相邻两个元素是逆序
{
flag = false; //这个轮次发生了交换,将标记位flag置为false
int x; //两个位置元素进行交换
x = ql.Elem[j+1];
ql.Elem[j+1] = ql.Elem[j];
ql.Elem[j] = x;
}
}
cout<<i<<": "; //打印每一轮次冒泡后的结果,便于观察
for(int k=0;k<ql.length;k++)
{
cout<<ql.Elem[k]<<" ";
}
cout<<endl;
}
}
int main()
{
SqList QL;
QL.length = 8;
for(int i=0;i<QL.length;++i)
{
cin>>QL.Elem[i];
}
cout<<"插入前元素:";
for(int i=0;i<QL.length;++i)
{
cout<<QL.Elem[i]<<" ";
}
cout<<endl;
sortMP(QL);
cout<<endl;
cout<<"插入后元素:";
for(int i=0;i<QL.length;++i)
{
cout<<QL.Elem[i]<<" ";
}
//cout<<"ok!"<<endl;
return 0;
}
2. 运行结果
1.测试排序结果
2.测试flag的效果
当要排序的数组是升序的时候,仅冒泡一个轮次。
二、快速排序
1.代码实现
#include<bits/stdc++.h>
using namespace std;
#define maxSize 100
typedef struct
{
int Elem[maxSize]; //存储元素
int length; //元素数组长度
}SqList;
int findCenter(SqList &ql,int low,int high)
{
ql.Elem[0] = ql.Elem[low]; //以第一个元素作为中心点坐标
while(low<high) //双指针法
{
while(low<high&&ql.Elem[high]>=ql.Elem[0]) high--; //从数组的最后面开始遍历,找到第一个小于中心点的元素
ql.Elem[low] = ql.Elem[high]; //将该元素交换到low的位置,即将小于中心元素数组放在数组的左边
while(low<high&&ql.Elem[low]<ql.Elem[0]) low++; //从数组的最前面开始遍历,找到第一个大于中心点的元素
ql.Elem[high] = ql.Elem[low]; //将该元素交换到high的位置,即将大于中心元素数组放在数组的右边
}
//while循环结束时,数组已经划分成为左右两个子数组
ql.Elem[low] = ql.Elem[0];//然后把哨兵保存的元素赋值给剩余的中间位置
return low; //同时返回中心坐标,此处返回low和high效果一样。因为上面while循环结束的条件一定是:low=high
}
void sortKP(SqList &ql,int low,int high)
{
if(low<high) //数组元素长度大于1才有排序的意义
{
int mid = findCenter(ql,low,high); //快速排序的核心算法,即找中心点位置
sortKP(ql,low,mid-1); //递归思想,对小于中心点的子数组进行同样的排序
sortKP(ql,mid+1,high); //再对大于中心点的子数组进行同样的排序方法
}
}
int main()
{
SqList QL;
QL.length = 8;
for(int i=1;i<=QL.length;++i)
{
cin>>QL.Elem[i];
}
cout<<"插入前元素:";
for(int i=1;i<=QL.length;++i)
{
cout<<QL.Elem[i]<<" ";
}
cout<<endl;
sortKP(QL,1,QL.length);
cout<<endl;
cout<<"插入后元素:";
for(int i=1;i<=QL.length;++i)
{
cout<<QL.Elem[i]<<" ";
}
//cout<<"ok!"<<endl;
return 0;
}
2.运行结果
总结
- 冒泡排序中,为了提高效率不浪费资源,设置flag是为了及时发现排序结果已经完成。
- 快速排序以空间换时间,是比较快速的排序方法。但是它最坏的情况其实就是没有改进的冒泡排序。
- 快速排序的时候,用数组下标为0的位置作为哨兵,以保存每个子数组的中心坐标元素。