算法核心:通过连续的比较相邻的两个元素,使得最大(小)的元素移动到比较方向结束的一端;第一趟比较n-1次,最后一趟比较1次。这样,经过n-1趟比较,到底完全排序的目的。
比较次数:有上述分析可知,为n*(n-1)/2次。
交换次数:在原始序列与目标完全逆序的情况下,需要交换n*(n-1)/2次。
实现关键:比较开始的一端,下标为定值;结束的一端,下表是关于趟数相关的变化量。这是因为,在结束端一侧的元素已经排好序,无需在比较。只要遵循这一规律,实现冒泡排序并不困难,下面是4种网上常见,而且区别很小的实现:
#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;
template <class T>
class Sort
{
public:
Sort(int mSize)
{
MAXSIZE = mSize;
arr = new T[MAXSIZE];
size = 0;
srand((unsigned)time(NULL));
}
~Sort()
{
delete []arr;
}
bool IsFull()
{
return size == MAXSIZE;
}
void Shuffle();
void Add(T element);
void Display();
void BubbleSort1();
void BubbleSort2();
void BubbleSort3();
void BubbleSort4();
private:
T* arr;
int size;
int MAXSIZE;
void Swap(T& a, T& b)
{
T t = a;
a = b;
b = t;
}
};
template <class T>
void Sort<T>::Shuffle()
{
for (int i = 0; i < size; i++)
{
Swap(arr[i], arr[rand() % size]);
}
}
template <class T>
void Sort<T>::Add(T element)
{
if (IsFull())
{
cout << "Array is full!" << endl;
return;
}
arr[size ++] = element;
}
template <class T>
void Sort<T>::Display()
{
cout << "The elements are:" << endl;
for (int i = 0; i < size; i++)
{
cout << arr[i];
if (i < size -1)
{
cout << " ";
}
}
cout << endl;
}
template <class T>
void Sort<T>::BubbleSort1()
{
for (int i = 0; i < size; i++)
{
for (int j = 1; j < size - i; j++)
{
if (arr[j - 1] < arr[j])
{
Swap(arr[j - 1], arr[j]);
}
}
}
}
template <class T>
void Sort<T>::BubbleSort2()
{
for (int i = 1; i < size; i++)
{
for (int j = 1; j <= size - i; j++)
{
if (arr[j - 1] < arr[j])
{
Swap(arr[j - 1], arr[j]);
}
}
}
}
template <class T>
void Sort<T>::BubbleSort3()
{
for (int i = 0; i < size; i++)
{
for (int j = size - 1; j > i; j--)
{
if (arr[j - 1] < arr[j])
{
Swap(arr[j - 1], arr[j]);
}
}
}
}
template <class T>
void Sort<T>::BubbleSort4()
{
for (int i = 1; i < size; i++)
{
for (int j = size - 1; j >= i ; j--)
{
if (arr[j - 1] < arr[j])
{
Swap(arr[j - 1], arr[j]);
}
}
}
}
int main()
{
Sort<int> s(20);
for (int i = 0; i < 20; i++)
{
s.Add(i);
}
s.Shuffle();
s.Display();
s.BubbleSort1();
s.Display();
cout << endl;
s.Shuffle();
s.Display();
s.BubbleSort2();
s.Display();
cout << endl;
s.Shuffle();
s.Display();
s.BubbleSort3();
s.Display();
cout << endl;
s.Shuffle();
s.Display();
s.BubbleSort4();
s.Display();
cout << endl;
system("pause");
}
可以看出,其实第一层循环是n次还是n-1次并不重要。只要保证第二层循环是:
1. 以常理开始,以变量结束
2. 循环变量的边界值,根据交换判断条件,覆盖到边界元素
3. 循环变量的最小值与最大值之和为n-1就可以了