Sort

9 篇文章 0 订阅
#include<iostream>
#include<vector>
#include<map>

using namespace std;

//交换函数
void swap(vector<int>& v, int a, int b)
{
	int temp = v[a];
	v[a] = v[b];
	v[b] = temp;
}

//1.冒泡排序
//思想:从左往右遍历,比较相邻两个元素的大小,将大的一个放在后面,每遍历一趟,可找到一个最大值放置在最后,经过n - 1趟遍历即可。
//性能:时间复杂度为O(n2),空间复杂度O(1),元素比较次数与初始状态无关,性能略低于插入排序。
void Bubble_Sort(vector<int>& v)
{
	int flag = 0;
	int len = v.size();
	for (int i = 0; i < len - 1; i++)
	{
		flag = 0;
		for (int j = 0; j < len - i - 1; j++)
		{
			if (v[j]>v[j + 1])
			{
				swap(v, j, j + 1);
				flag = 1;
			}
		}
		if (!flag)
		{
			break;
		}
	}
	return ;
}

//2.选择排序
//思想:遍历数组,每次遍历都在未排序的部分找到最小元素的下标,在此次遍历结束后将最小元素交换到遍历开始的位置。
//性能:时间复杂度为O(n2),空间复杂度O(1),算法比较次数与初始序列状态无关,性能在所有排序算法中最差。
void Violence_Sort(vector<int>& v)
{
	int len = v.size();

	for (int i = 0; i < len - 1; i++)
	{
		int min = i;
		for (int j = i + 1; j < len; j++)
		{
			if (v[j] < v[min])
			{
				min = j;
			}
		}
		if (min != i)
		{
			swap(v, i, min);
		}
	}
	return ;
}

//3.插入排序
//思想:将当前元素与它前面已排好序的元素依次进行比较,最后放置在合适的位置
//      初始时可从第二个元素开始,认为第一个元素已排好序。
//性能:算法时间复杂度为O(n2),空间复杂度O(1),在序列规模较小时,性能比较好,且元素比较次数与初始序列杂乱程度相关
//      最优复杂度为O(n)。
void Insert_Sort(vector<int>& v)
{
	int len = v.size();
	for (int i = 1; i < len; i++)
	{
		int key = v[i];
		int j = i - 1;
		while (j >= 0 && v[j] > key)
		{
			v[j + 1] = v[j];
			j--;
		}
		v[j + 1] = key;
	}
	return ;
}

//希尔排序
//思想:利用插入排序的思想,考虑到插入排序在序列基本有序且数量较少时性能较高,
//因此先对序列进行逻辑上的分组然后插入排序,如:设定初始增量为x,则0,0 + x,0 + x + x ...为一组,
//1,1 + x,1 + x + x ...为第二组,共有x组,分别进行排序。那个随后减少增量,增加分组,直到增量为1。
//性能:算法时间复杂度为O(n1.3) - O(n2),性能取决于增量序列。
void Shell_Sort(vector<int>& v)
{
	int len = v.size();
	int flag = len / 2;
	for (flag; flag > 0; flag /= 2)
	{
		for (int i = flag; i < len; i++)
		{
			int key = v[i];
			int j = i - flag;
			while (j >= 0 && v[j] > key)
			{
				v[j + flag] = v[j];
				j -= flag;
			}
			v[j + flag] = key;
		}
	}
	return ;
}
//快速排序
//思想:与归并排序类似,也使用分治思想,选择一个元素值(一般选择最后一个元素),将比它小的放在左边部分,
//比它大的放在右边,然后对两部分分别进行上述操作知道递归结束,关键步骤在于元素的分类,且只占用O(1)的额外存储空间。
//性能:时间复杂度为O(nlgn),与归并排序不同,该算法占用常数级额外存储,在大规模序列排序应用中性能较好。
//快速排序-前后交换法
int PartSort1(vector<int>&v, int left, int right)
{
	int begin = left;
	int end = right - 1;
	int key = v[end];
	while (begin < end)
	{
		//begin从前往后找,找比基准值大的元素
		while (begin < end&&v[begin] <= key)
		{
			begin++;
		}
		//end从后往前找,找比基准值小的元素
		while (begin < end&&v[end] >= key)
		{
			end--;
		}
		if (begin < end)
		{
			swap(v, begin, end);
		}
	}
	if (begin != right - 1)
	{
		swap(v, begin, right - 1);
	}
	return begin; //新div
}

//快速排序-挖坑法
int PartSort2(vector<int>&v, int left, int right)
{
	int begin = left;
	int end = right - 1;
	int key = v[begin];

	while (begin < end)
	{
		while (begin < end&&v[end] >= key)
		{
			end--;
		}
		if (begin < end)
		{
			v[begin] = v[end];
			begin++;
		}

		while (begin < end&&v[begin] <= key)
		{
			begin++;
		}
		if (begin < end)
		{
			v[end] = v[begin];
			end--;
		}
	}
	v[begin] = key;

	return begin;
}

//快速排序-前后指针法
int PartSort3(vector<int>&v, int left, int right)
{
	int cur = 0;
	int prev = cur - 1;
	int key=v[right-1];
	while (cur < right)
	{
		if (v[cur] < key&&++prev != cur)
		{
			swap(v, prev, cur);
		}
		cur++;
	}
	swap(v, ++prev, right - 1);
	return prev;
}

void Quick_Sort(vector<int>& v,int left,int right)
{
	//左闭右开
	if (left >= right) return;
	int div = PartSort3(v, left, right);
	Quick_Sort(v, left, div);
	Quick_Sort(v, div + 1, right);
}

//归并排序
//思想:使用分治思想,将原始序列分为两部分分别排序,然后合并,重点在于合并过程。
//性能:时间复杂度为O(nlgn),不过合并过程会使用额外的存储空间,占用内存。
void MergeData(vector<int>&v, int left, int mid, int right, vector<int>&temp)
{
	int begin1 = left, end1 = mid;
	int begin2 = mid, end2 = right;
	int index = left;

	while (begin1 < end1&&begin2 < end2)
	{
		if (v[begin1] <= v[begin2])
		{
			temp[index++] = v[begin1++];
		}
		else
			temp[index++] = v[begin2++];
	}
	while (begin1<end1) temp[index++] = v[begin1++];
	while (begin2<end2) temp[index++] = v[begin2++];
}

void _MergeSort(vector<int>&v, int left, int right, vector<int>&temp)
{
	if (right - left > 1)
	{
		int mid = left + ((right - left)>>1);
		_MergeSort(v, left, mid, temp);
		_MergeSort(v, mid, right, temp);
		MergeData(v, left, mid, right, temp);
		for (int i = 0; i < (right-left); i++)
		{
			v[left + i] = temp[left + i];
		}
	}
}

void MergeSort(vector<int>& v)
{
	int len = v.size();
	vector<int>temp(len);
	_MergeSort(v, 0, len, temp);
}

//堆排序
//思想:使用堆数据结构进行排序,堆是一种用数组存储的二叉树,根据父节点和子节点的大小关系分为最大堆和最小堆,这里使用最大堆进行排序。
//性能:时间复杂度为O(nlgn),在实际使用中,堆排序的排序性能通常逊与快速排序
void AdjustDown(vector<int>& v,int len,int parent)
{
	//int len = v.size();
	int child = parent * 2 + 1;
	while (child < len)
	{
		if (child + 1 < len&&v[child + 1] < v[child])
		{
			child++;
		}
		if (v[child] < v[parent])
		{
			swap(v, child, parent);
			parent = child;
			child = parent * 2 + 1;
		}
		else
			return;
	}
}
void HeapSort(vector<int>&v)
{
	int len = v.size();
	for (int root = (len - 2) >> 1; root >= 0; root--)
	{
		AdjustDown(v, len,root);
	}
	int end = len - 1;
	while (end)
	{
		swap(v, 0, end);
		AdjustDown(v,end, 0);
		end--;
	}
}
//只能和0进行交换
void my_swap(vector<int>&v, int num)
{
	int len = v.size();
	int index;
	for (int i = 0; i < len; i++)
	{
		if (v[i] == 0) index = i;
	}
	swap(v, index, num);
}
void Sort1(vector<int>& v)
{
	int len = v.size();
	int num;
	for (int i = 0; i < len; i++)
	{
		if (v[i] == i) continue;
		num = i;
		my_swap(v, i);
		for (int j = 0; j < len; j++)
		{
			if (v[j]==num) 
				swap(v,num, j);
		}
	}
}
void Printf(const vector<int> v)
{
	for (auto ch : v)
	{
		cout << ch << " ";
	}
	cout << endl;
}

void Test1()
{
	vector<int> v{ 1, 4, 8, 5, 3, 9, 0, 2, 7, 6 };
	//Bubble_Sort(v);   //冒泡排序
	//Violence_Sort(v); //选择排序
	//Insert_Sort(v);   //插入排序
	//Shell_Sort(v);    //希尔排序
	//Quick_Sort(v, 0, v.size()); //快速排序
	//MergeSort(v); //归并排序
	//HeapSort(v); //堆排序
	//Sort1(v);     //0排序
	Printf(v);
}

int main()
{
	Test1();
	system("pause");
	return 0;
}






//bool matchNames(string alias, string names)
//{
//	int len = alias.size();
//	map < string, char > m;
//	int left = 0;
//	for (int i = 0; i < len - 1; i++)
//	{
//		int right = names.find(" ", left);
//		string temp = names.substr(left, right - left);
//		left = right + 1;
//		if (m.find(temp) == m.end())
//		{
//			m[temp] = alias[i];
//		}
//		else
//		{
//			if (m[temp] != alias[i])
//			{
//				return 0;
//			}
//		}
//	}
//	string temp = names.substr(left);
//	if (m.find(temp) == m.end())
//	{
//		m[temp] = alias[len - 1];
//	}
//	else
//	{
//		if (m[temp] != alias[len - 1])
//		{
//			return 0;
//		}
//	}
//	return 1;
//}
//int main()
//{
//	//Test1();
//	string s1 = "abbac";
//	string s2 = "sd1 sd2 sd2 sd1 sd3";
//	if (matchNames(s1, s2)) 
//		cout << 1 << endl;
//	else cout << 2 << endl;
//	system("pause");
//	return 0;
//}




//int main(void)
//{
//	int nTest = 1234;
//	printf("%s,%5.3s,%2d\n","Hithink","Hithink",nTest);
//	system("pause");
//	return 0;
//}

//int num(int n)
//{
//	if (n / 10 == 0) return n;
//	int count = 0;
//	while (n)
//	{
//		count += n % 10;
//		n /= 10;
//	}
//	return num(count);
//}
//int main()
//{
//	cout << num(38) << endl;
//	system("pause");
//	return 0;
//}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值