冒泡排序、插入排序、選擇排序的C++實現

前言

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章