所有的排序都以升序爲例。考慮複雜度,考慮穩定性的情況。以及在原基礎上步步的優化。
冒泡排序:
算法:從頭開始比較每一對相鄰元素,如果第一個元素比第二個元素大,就交換他們的位置。
舉例:
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] << "_";
}
}
總結:冒泡排序是最簡單的排序方式,後面會陸續更新更多的其他的排序算法。