所有的排序都以升序为例。考虑复杂度,考虑稳定性的情况。以及在原基础上步步的优化。
冒泡排序:
算法:从头开始比较每一对相邻元素,如果第一个元素比第二个元素大,就交换他们的位置。
举例:
void BubbleSort::sort(int array[], int len)
{
if (array == NULL || len < 2)
{
return;
}
this->m_array = array;
this->m_len = len;
for(int end = this->m_len - 1; end > 0; end--)
{
for(int begin = 1; begin <= end; begin++)
{
if(this->cmp(begin,begin-1) < 0)
{
this->swap(begin, begin - 1);
}
}
}
for (int i = 0; i < this->m_len; i++)
{
cout << this->m_array[i] << "_";
}
}
冒泡排序的优化1:
首先得知道为什么要进行优化,前一种的算法出现了什么文艺? 优化就说明前一种的冒泡排序的算法有点“小问题”,首先声明:不是程序出错的问题,而是效率的问题。好的,我们下面举个例子,说明一下。
算法:假设每一轮比较开始,我们都认为数组是有序的,bool flags = true.如果进行了一次交换位置,说明这一轮不是有序的,将flags = false.这样就避免了数组本身是有序的,还“傻傻的”义无反顾的比较下去。
优化方式1:
void BubbleSort1::sort(int array[], int len)
{
if (array == NULL || len == 1)
{
return;
}
this->m_array = array;
this->m_len = len;
for (int end = this->m_len - 1; end > 0; end--)
{
bool flags = true;//假设每次否是排好序的
for (int begin = 1; begin <= end; begin++)
{
if(cmp(begin,begin-1) < 0)
{
this->swap(begin, begin - 1);
//如果有交换 代表没有排好序
flags = false;
}
}
if (flags == true)
{
break;
}
}
for (int i = 0; i < this->m_len; i++)
{
cout << this->m_array[i] << "_";
}
}
,冒泡排序的优化2:
进行过一次的优化之后,我们在进一步的优化思考,在大多数的情况下,数组往往不是直接有序的,而是局部有序的(如下图)。我们需要做的是记录最后一次交换的位置,这样后面的元素就已经排好序,这样可以减少比较的次数,达到优化的目的。
优化方式2:
void BubbleSort2::sort(int array[], int len)
{
if (array == NULL || len == 1)
{
return;
}
this->m_array = array;
this->m_len = len;
for (int end = this->m_len - 1; end > 0; end--)
{
int sortedIndex = 1;
for (int begin = 1; begin <= end; begin++)
{
if(this->cmp(begin,begin - 1) < 0)
{
this->swap(begin, begin - 1);
//最后一次的比较位置
sortedIndex = begin;
}
}
//改变end的位置。最后一次比较的位置之后的元素全不已经有序了
end = sortedIndex;
}
for (int i = 0; i < this->m_len; i++)
{
cout << this->m_array[i] << "_";
}
}
总结:冒泡排序是最简单的排序方式,后面会陆续更新更多的其他的排序算法。