算法合集(自写暂存)

记录我的码农之路~~~
算法为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

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