算法合集(自寫暫存)

記錄我的碼農之路~~~
算法爲C++實現。
共包含冒泡排序選擇排序插入排序希爾排序堆排序桶排序快速排序以及歸併排序… …
注:算法是初學自己捋着思路寫的,有不足之處還請大家指正一起優化~~~


#include <iostream>
#include <vector>
#include <string>
#include <cstdlib>
#include <time.h>
#include <stack>
using namespace std;

class Sort {
   
   
public:
	/*************************************************************/
	template<class T>//冒泡排序
	void BubbleSort(T* vec, int n) {
   
   
		int flag = 0;//標記法判斷是否發生 交換
		for (int i = n; i > 1; i--)
		{
   
   //一共i個數進行排序
			for (int j = 0; j < i - 1; j++)
			{
   
   
				if (vec[j] > vec[j + 1])
				{
   
   
					Swap<T>(vec[j], vec[j + 1]);
					flag = 1;  //發生交換纔將flag置1
				}
			}
			if (flag == 0) //一整趟下來沒發生交換,說明無需繼續排序,跳出循環
				break;
		}
	}
	/*************************************************************/
	template<class T>//選擇排序
	void SeleteSort(T* vec, int n)
	{
   
   
		for (int i = n; i > 1; i--)//i表示進行選擇排序的數量
		{
   
   
			int indexMax = 0;
			for (int j = 1; j < i; j++)
			{
   
   
				if (vec[j] > vec[indexMax])
				{
   
   
					indexMax = j; //尋找最大值下標
				}
			}
			if (indexMax != i - 1)//如果最大值不是當前的“最後”一個元素就交換位置
				Swap(vec[indexMax], vec[i - 1]);
		}
	}
	/*************************************************************/
	template<class T>//直接插入排序
	void InsertSort(T* vec, int n)
	{
   
   
		for (int i = 1; i < n; i++)
		{
   
   //有序與無序的分界線
			int j = i - 1;
			T tmp = vec[i];
			for (; j >= 0 && tmp < vec[j]; j--)//找第一個比它小的數
			{
   
   
				//移動過程中完成數據遷移
				vec[j + 1] = vec[j];
			}
			vec[j + 1] = tmp;
		}
	}
	/*************************************************************/
	template<class T>//希爾插入排序
	void ShellSort(T* vec, int n)
	{
   
   
		for (int gap = n / 2; gap >= 1; gap /= 2)
		{
   
   
			for (int i = 0; i < gap; i++)
				groupSort(vec, n / gap, i, gap);
		}
	}
	template<class T>//n代表進行插入排序元素的個數,start爲排序首地址,gap爲間隙
	void groupSort(T* vec, int n, int start, int gap)//傳入數組、起始下標、希爾間隙進行插入排序
	{
   
   
		int i, j;
		for (i = start + gap; i < n * gap; i += gap)
		{
   
   
			T tmp = vec[i];//用變量tmp記錄需要插入的元素
			for (j = i - gap; tmp < vec[j] && j >= 0; j -= gap)
				vec[j + gap] = vec[j];
			vec[j + gap] = tmp;
		}
	}
	/*************************************************************/
	template<class T>//堆排序(堆調整)
	void adjustHeap(T* vec, int curindex, int maxindex)
	{
   
   
		int father = curindex;
		int child = 2 * father + 1;//左孩子節點
		while (child <= maxindex)
		{
   
   
			if (child + 1 <= maxindex && vec[child + 1] > vec[child])//說明有右孩子
				child++;//使用右孩子下標(與父節點比較)
			if (vec[child] > vec[father])//若孩子節點大於父節點,則交換
			{
   
   
				Swap(vec[child], vec[father]);
				father = child;  //交換後檢測子節點的位置是否是最大堆
				child = 2 * father + 1;
			}
			else
				break;//無交換,跳出循環
		}
	}
	template<typename T>//堆排序
	void HeapSort(T* vec, int maxindex)
	{
   
   
		for (int i = (maxindex - 1) / 2; i >= 0; i--)//初始化最大堆結構
			adjustHeap(vec, i, maxindex);
		for (int i = maxindex; i > 0;)
		{
   
   
			Swap(vec[0], vec[i]);//交換首尾元素
			i--;
			for (int j = (i - 1) / 2; j >= 0; j--)//調整堆結構爲最大堆
				adjustHeap(vec, j, i);//重新對堆進行排序
		}
	}
	/*************************************************************/
	template<class T>//桶排序
	void BuckerSort(T* vec, int n)
	{
   
   
		T max = vec[0];
		for (int i = 1; i < n; i++)
			if (vec[i] > max)
				max = vec[i];
		T* bucket = new T[max + 1]();
		for (int i = 0; i < n; i++)
			bucket[vec[i]]++;
		int start = 0;
		for (T i = 0; i < max + 1; i++)
		{
   
   
			while (bucket[i]--) {
   
   
				vec[start++] = i;
			}
		}

	}
	/*************************************************************/
	template<typename T>//荷蘭國旗法快速排序
	pair<int, int > HL_NtionalFlag(T* vec, int start, int end)
	{
   
   
		int i = start - 1, j = end + 1, index = start;
		T flag = vec[index];
		while (index < j)
		{
   
   
			if (vec[index] == flag)
				index++;
			else if (vec[index] < flag) {
   
   
				Swap(vec[index++], vec[++i]);
			}
			else {
   
   
				Swap(vec[index], vec[--j]);
			}
		}
		return make_pair(i, j);
	}
	template <typename T>
	void RecurQuickSort(T* vec, int start, int end)//遞歸法赫拉國旗快排
	{
   
   
		if (start >= end)
			return;
		pair<int, int> p = HL_NtionalFlag(vec, start, end);
		RecurQuickSort(vec, start, p.first);//左半部分
		RecurQuickSort(vec, p.second, end);//右半部分
	}
	template<class T>
	void Non_recurQuick(T* vec, int start, int end)//start/end均爲數字下標
	{
   
   
		stack<pair<int, int>> stk;//定義一個pair類型的棧來存儲每次進行荷蘭國旗排序的下標值
		stk.push(make_pair(start, end));

		while (!stk.empty())
		{
   
   
			pair<int, int> p = stk.top();//得到上一次排序分界線的兩個位置
			stk.pop();//用完將棧區變量彈出
			pair<int, int> part = HL_NtionalFlag(vec, p.first, p.second);
			if (part.first > p.first)//表示這一次左半部分快排有改變
				stk.push(make_pair(p.first, part.first));//上次排序的i值是開始,排序完的i是結束的位置
			if (part.second < p.second)
				stk.push(make_pair(part.second, p.second));//上次的j是結束的位置,排序完是開始id位置
		}
	}
	/*************************************************************/
	template<class T>//歸併整合
	void Merge(T* vec, int l,int mid, int r)
	{
   
   	
		T* help = new T[r - l + 1];//堆區申請空間
		int index = 0,i = l,j = mid + 1;
		while (i <= mid && j <= r)//兩部分數組分別比較
		{
   
   
			if (vec[i] <= vec[j])
				help[index++] = vec[i++];
			else
				help[index++] = vec[j++];
		}
		while (i <= mid)//將兩部分中還沒放入help數組中元素逐一放進去
		{
   
   
			help[index++] = vec[i++];
		}
		while (j <= r)
		{
   
   
			help[index++] = vec[j++];
		}
		//將元素從help數組重新放入原地
		index = l;//記錄原數組最小下標
		for (i = 0; i < r - l + 1; i++)
			vec[index++] = help[i];
		delete[] help;
	}
	template<typename T>//歸併排序
	void MergeSort(T* vec, int l,int r)
	{
   
   
		int mid = (l + r) / 2;
		if (l >= r)//將數組不斷分裂,到單塊數組長度爲 1 時停止,跳出遞歸
		{
   
   
			return;
		}
		
		MergeSort(vec, l, mid); //遞歸調用
		MergeSort(vec, mid + 1, r);
		//分裂後進行逐層排序組合
		Merge(vec, l, mid, r);
	}
	/*************************************************************/
	template<class T>//打亂數組
	void Interupt(T* p, int n)//隨機打亂數組
	{
   
   
		srand(time(0));
		for (int i = 0; i < 100000; i++)//產生模擬時間差
			for (int j = 0; j < 5000; j++);
		for (int i = 0; i < n; i++)
		{
   
   
			int j = rand() % n;
			Swap<T>(p[i], p[j]);
		}
	}
	/*************************************************************/
	template<class T>//打印數組
	void PrintVec(T* vec, int n)
	{
   
   
		for (int i = 0; i < n; i++)
			cout << vec[i] << "    ";
		cout << endl;
	}
	/************************************************************/
	template<class T>//交換元素
	void Swap(T& a, T& b)
	{
   
   
		T t = a;
		a = b;
		b = t;
	}
};

int main() {
   
   
	Sort s;
	int a[] = {
   
   2,1,3,5,4,6,8,7};
	int n = sizeof(a)/sizeof(int);
	cout << "原數組:" << endl;
	s.PrintVec(a, n);
	cout << endl << "堆排序:" << endl;;
	s.HeapSort(a, n - 1);
	s.PrintVec(a, n);
	cout << endl << "打亂後數組:" << endl;;
	s.Interupt(a, n);
	s.PrintVec(a, n);
	cout << endl << "桶排序:" << endl;;
	s.BuckerSort(a, n);
	s.PrintVec(a, n);
	cout << endl << "打亂後數組:" << endl;;
	s.Interupt(a, n);
	s.PrintVec(a, n);
	cout << endl << "冒泡排序:" << endl;;
	s.BubbleSort(a, n);
	s.PrintVec(a, n);
	cout << endl << "打亂後數組:" << endl;;
	s.Interupt(a, n);
	s.PrintVec(a, n);
	cout << endl << "插入排序:" << endl;;
	s.InsertSort(a, n);
	s.PrintVec(a, n);
	cout << endl << "打亂後數組:" << endl;;
	s.Interupt(a, n);
	s.PrintVec(a, n);
	cout << endl << "選擇排序:" << endl;;
	s.SeleteSort(a, n);
	s.PrintVec(a, n);
	cout << endl << "打亂後數組:" << endl;;
	s.Interupt(a, n);
	s.PrintVec(a, n);
	cout << endl << "希爾排序:" << endl;;
	s.ShellSort(a, n);
	s.PrintVec(a, n);
	cout << endl << "打亂後數組:" << endl;
	s.Interupt(a, n);
	s.PrintVec(a, n);
	cout << endl << "快速排序(遞歸):" << endl;
	s.RecurQuickSort(a, 0, n - 1);
	s.PrintVec(a, n);
	cout << endl << "打亂後數組:" << endl;
	s.Interupt(a, n);
	s.PrintVec(a, n);
	cout << endl << "快速排序(非遞歸):" << endl;
	s.Non_recurQuick(a, 0, n - 1);
	s.PrintVec(a, n);
	cout << endl << "打亂後數組:" << endl;
	s.Interupt(a, n);
	s.PrintVec(a, n);
	cout << endl << "歸併排序:" << endl;
	s.MergeSort(a, 0, n - 1);
	s.PrintVec(a, n);
	return 0;
}

效果圖:
P1
P2

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