前言
記錄使用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的數也是有序的。