前言
记录使用C++实现冒泡排序、插入排序和选择排序。三种排序的时间复杂度都是O(N^2)
代码
主要有4个文件,分别是BubbleSort.h,InsertSort.h,SelectSort.h 以及main.cpp
首先是BubbleSort:
#include<cassert>
#ifndef _BUBBLE_SORT_H
#define _BUBBLE_SORT_H
template<typename T>
class BubbleSortAlgo
{
public:
BubbleSortAlgo(int size, int growBy = 1) :
m_array(NULL), m_maxSize(0),
m_growSize(0), m_numElements(0)
{
if (size)
{
m_maxSize = size;
m_array = new T[m_maxSize];
memset(m_array, 0, sizeof(T)* m_maxSize);
m_growSize = ((growBy > 0) ? growBy : 0);
}
}
~BubbleSortAlgo()
{
if (m_array != NULL)
{
delete[] m_array;
m_array = NULL;
}
}
void push(T val)
{
assert(m_array != NULL);
if (m_numElements >= m_maxSize)
{
Expand();
}
m_array[m_numElements] = val;
m_numElements++;
}
void pop()
{
if (m_numElements > 0)
m_numElements--;
}
void remove(int index)
{
assert(m_array != NULL);
if (index >= m_maxSize)
{
return;
}
for (int k = index; k < m_maxSize - 1; k++)
m_array[k] = m_array[k + 1];
m_maxSize--;
if (m_numElements >= m_maxSize)
m_numElements = m_maxSize - 1;
}
T& operator[](int index)
{
assert(m_array != NULL && index <= m_numElements);
return m_array[index];
}
int search(T val)
{
assert(m_array != NULL);
for (int i = 0; i < m_numElements; i++)
{
if (m_array[i] == val)
return i;
}
return -1;
}
void BubbleSort()
{
assert(m_array != NULL);
for (int k = m_numElements - 1; k > 0; k--)
{
for (int i = 0; i < k; i++)
{
if (m_array[i] > m_array[i + 1])
{
T temp = m_array[i];
m_array[i] = m_array[i + 1];
m_array[i + 1] = temp;
}
}
}
}
void clear() { m_numElements = 0; }
int GetSize() { return m_numElements; }
int GetMaxSize() { return m_maxSize; }
int GetGrowSize() { return m_growSize; }
void SetGrowSize(int val)
{
assert(val >= 0);
m_growSize = val;
}
private:
bool Expand()
{
if (m_growSize <= 0)
return false;
T *temp = new T[m_maxSize + m_growSize];
assert(temp != NULL);
memcpy(temp, m_array, sizeof(T)* m_maxSize);
delete[] m_array;
m_array = temp;
m_maxSize += m_growSize;
return true;
}
private:
T *m_array;
int m_maxSize;
int m_growSize;
int m_numElements;
};
#endif
然后是InsertSort.h
#ifndef _INSERT_SORT_H
#define _INSERT_SORT_H
template<typename T>
class InsertSortAlgo{
public:
InsertSortAlgo(int size, int growBy = 1) :
m_array(NULL), m_maxSize(0),
m_growSize(0), m_numElements(0)
{
if (size)
{
m_maxSize = size;
m_array = new T[m_maxSize];
memset(m_array, 0, sizeof(T)* m_maxSize);
m_growSize = ((growBy > 0) ? growBy : 0);
}
}
~InsertSortAlgo()
{
if (m_array != NULL)
{
delete[] m_array;
m_array = NULL;
}
}
void push(T val)
{
assert(m_array != NULL);
if (m_numElements >= m_maxSize)
{
Expand();
}
m_array[m_numElements] = val;
m_numElements++;
}
void pop()
{
if (m_numElements > 0)
m_numElements--;
}
void remove(int index)
{
assert(m_array != NULL);
if (index >= m_maxSize)
{
return;
}
for (int k = index; k < m_maxSize - 1; k++)
m_array[k] = m_array[k + 1];
m_maxSize--;
if (m_numElements >= m_maxSize)
m_numElements = m_maxSize - 1;
}
T& operator[](int index)
{
assert(m_array != NULL && index <= m_numElements);
return m_array[index];
}
int search(T val)
{
assert(m_array != NULL);
for (int i = 0; i < m_numElements; i++)
{
if (m_array[i] == val)
return i;
}
return -1;
}
void insertSort(){
assert(m_array != NULL);
for (int i = 0; i < m_numElements - 1; i++){
//you don't have to consider about the situation when the i+1 one is bigger, because the 0 to i is sorted so just skip it
if (m_array[i + 1]<m_array[i]){//the i+1 one is less than i
for (int j = i + 1; j > 0; j--){
if (m_array[j] < m_array[j - 1]){
T temp = m_array[j];
m_array[j] = m_array[j - 1];
m_array[j - 1] = temp;
}
else break;
}
}
}
}
void clear() { m_numElements = 0; }
int GetSize() { return m_numElements; }
int GetMaxSize() { return m_maxSize; }
int GetGrowSize() { return m_growSize; }
void SetGrowSize(int val)
{
assert(val >= 0);
m_growSize = val;
}
private:
bool Expand()
{
if (m_growSize <= 0)
return false;
T *temp = new T[m_maxSize + m_growSize];
assert(temp != NULL);
memcpy(temp, m_array, sizeof(T)* m_maxSize);
delete[] m_array;
m_array = temp;
m_maxSize += m_growSize;
return true;
}
private:
T *m_array;
int m_maxSize;
int m_growSize;
int m_numElements;
};
#endif
然后是SelectSort.h
#include<cassert>
#ifndef _SELECT_SORT_H
#define _SELECT_SORT_H
template<typename T>
class SelectSortAlgo
{
public:
SelectSortAlgo(int size, int growBy = 1) :
m_array(NULL), m_maxSize(0),
m_growSize(0), m_numElements(0)
{
if (size)
{
m_maxSize = size;
m_array = new T[m_maxSize];
memset(m_array, 0, sizeof(T)* m_maxSize);
m_growSize = ((growBy > 0) ? growBy : 0);
}
}
~SelectSortAlgo()
{
if (m_array != NULL)
{
delete[] m_array;
m_array = NULL;
}
}
void push(T val)
{
assert(m_array != NULL);
if (m_numElements >= m_maxSize)
{
Expand();
}
m_array[m_numElements] = val;
m_numElements++;
}
void pop()
{
if (m_numElements > 0)
m_numElements--;
}
void remove(int index)
{
assert(m_array != NULL);
if (index >= m_maxSize)
{
return;
}
for (int k = index; k < m_maxSize - 1; k++)
m_array[k] = m_array[k + 1];
m_maxSize--;
if (m_numElements >= m_maxSize)
m_numElements = m_maxSize - 1;
}
T& operator[](int index)
{
assert(m_array != NULL && index <= m_numElements);
return m_array[index];
}
int search(T val)
{
assert(m_array != NULL);
for (int i = 0; i < m_numElements; i++)
{
if (m_array[i] == val)
return i;
}
return -1;
}
void SelectSort()
{
assert(m_array != NULL);
int min;
for (int i = 0; i < m_numElements; i++){
min = i;//begin from the element whose index is i
for (int j = i; j < m_numElements; j++){
if (m_array[j] < m_array[min]) min = j;//find the smallest one whose index is j
}
if (min != i){
T temp = m_array[min];
m_array[min] = m_array[i];
m_array[i] = temp;
}
}
}
void clear() { m_numElements = 0; }
int GetSize() { return m_numElements; }
int GetMaxSize() { return m_maxSize; }
int GetGrowSize() { return m_growSize; }
void SetGrowSize(int val)
{
assert(val >= 0);
m_growSize = val;
}
private:
bool Expand()
{
if (m_growSize <= 0)
return false;
T *temp = new T[m_maxSize + m_growSize];
assert(temp != NULL);
memcpy(temp, m_array, sizeof(T)* m_maxSize);
delete[] m_array;
m_array = temp;
m_maxSize += m_growSize;
return true;
}
private:
T *m_array;
int m_maxSize;
int m_growSize;
int m_numElements;
};
#endif
最后是main.cpp
#include<iostream>
#include"conio.h"
#include"BubbleSort.h"
#include"InsertSort.h"
#include"SelectSort.h"
using namespace std;
int main(int args, char *arg[])
{
cout << "Bubble Sort Algorithm" << endl;
cout << "**********************" << endl << endl;
BubbleSortAlgo<int> array(5);
array.push(80);
array.push(64);
array.push(99);
array.push(76);
array.push(5);
cout << "Before sort:";
for (int i = 0; i < 5; i++)
{
cout << " " << array[i];
}
cout << endl;
array.BubbleSort();
cout << "After sort:";
for (int i = 0; i < 5; i++)
{
cout << " " << array[i];
}
cout << endl << endl;
_getch();
cout << "Insert Sort Algorithm" << endl;
cout << "**********************" << endl << endl;
InsertSortAlgo<int> array2(6);
array2.push(80);
array2.push(64);
array2.push(99);
array2.push(76);
array2.push(5);
array2.push(76);
cout << "Before sort:";
for (int i = 0; i < 6; i++)
{
cout << " " << array2[i];
}
cout << endl;
array2.insertSort();
cout << "After sort:";
for (int i = 0; i < 6; i++)
{
cout << " " << array2[i];
}
cout << endl << endl;
_getch();
cout << "Select Sort Algorithm" << endl;
cout << "**********************" << endl << endl;
SelectSortAlgo<int> array3(6);
array3.push(80);
array3.push(64);
array3.push(99);
array3.push(76);
array3.push(5);
array3.push(76);
cout << "Before sort:";
for (int i = 0; i < 6; i++)
{
cout << " " << array3[i];
}
cout << endl;
array3.SelectSort();
cout << "After sort:";
for (int i = 0; i < 6; i++)
{
cout << " " << array3[i];
}
cout << endl << endl;
return 0;
}
注意点
三个比较基础的算法,简要说明思路。
冒泡:
void BubbleSort()
{
assert(m_array != NULL);
for (int k = m_numElements - 1; k > 0; k--)
{
for (int i = 0; i < k; i++)
{
if (m_array[i] > m_array[i + 1])
{
T temp = m_array[i];
m_array[i] = m_array[i + 1];
m_array[i + 1] = temp;
}
}
}
}
形象点说,就是从第0个数开始,依次把最大、次大、第三大……的数移动到最后。就像冒泡泡一样,让大数一个接一个排到最后。
选择排序
void SelectSort()
{
assert(m_array != NULL);
int min;
for (int i = 0; i < m_numElements; i++){
min = i;//begin from the element whose index is i
for (int j = i; j < m_numElements; j++){
if (m_array[j] < m_array[min]) min = j;//find the smallest one whose index is j
}
if (min != i){
T temp = m_array[min];
m_array[min] = m_array[i];
m_array[i] = temp;
}
}
}
每次都选出当前序列最小的一个,然后把它置于队首,令序列-1 。
很直观。
插入排序
void insertSort(){
assert(m_array != NULL);
for (int i = 0; i < m_numElements - 1; i++){
//you don't have to consider about the situation when the i+1 one is bigger, because the 0 to i is sorted so just skip it
if (m_array[i + 1]<m_array[i]){//the i+1 one is less than i
for (int j = i + 1; j > 0; j--){
if (m_array[j] < m_array[j - 1]){
T temp = m_array[j];
m_array[j] = m_array[j - 1];
m_array[j - 1] = temp;
}
else break;
}
}
}
}
从左至右,如果发现后一个数(i+1)比前一个数(i)小,那么将该数往前移动,一直移动到它前面的数比它小为止。也就是一个有序数列中,它自己该待的地方。不用考虑后一个(i+1)数比前一个数(i)大的情况,因为后前i个数一定是有序的,所以加上i+1的数也是有序的。