• 排序算法:快排,插入,希尔,归并,堆,选择,冒泡



    #include <iostream>
    using namespace std;
    
    //划分函数:将数组划分为大于和小于某元素的两部分
    template <typename T>
    int partition_job(T *array, int left, int right)
    {
    	int index = left;
    	int pivot = array[index];
    	swap(array[index],array[right]);
    	for(int i = left; i< right; i++)
    	{
    		if(array[i] > pivot)
    		{
    			swap(array[index++], array[i]);
    		}//降序
    	}
    	swap(array[right], array[index]);
    	return index;
    }
    
    
    //快速排序:分治法+挖空填空
    //快速排序的平均时间复杂度为:O(nlog(n)),每次划分数组整体比较n次,分成两半。
    template <typename T>
    void qsort_job(T *array, int left, int right)
    {
    	if(left >= right)
    		return ;
    	int index = partition_job(array, left, right);
    	qsort_job(array, left, index - 1);//做部分
    	qsort_job(array, index + 1, right);
    }
    
    
    //插入排序
    //平均时间复杂度:O(n2);最好O(n):已排好序;最差O(n2):完全逆序。
    /*
    原理:
    初始:首个元素自成一个有序(已排)序列,其余的记录为无序(待排)序列。
    循环:从第二个记录开始,按照记录的大小依次将当前处理的记录插入到其之前的有序序列中。
    终止:直至最后一个记录插入到有序序列中为止。
    */
    template <typename T>
    void insertsort_job(T *data, int size)
    {
    	for(int i = 1; i < size; i++)
    	{
    		T key = data[i];
    		int j(i-1);
    		for(; j >= 0 && data[j] > key; j--) //降序
    			data[j+1] = data[j];
    		data[j+1] = key;
    	}
    }
    
    //希尔排序:有间隔的插入排序,间隔逐渐减小,最后间隔为1
    //不稳定的,
    template <typename T>
    void shellsort_job(T *data, size_t size)
    {
    	for(int gap = size/2; gap > 0; gap /= 2)
    	{
    		for(int i = gap; i < size; ++i)
    		{
    			T key = data[i];
    			int j = 0;
    			for(j = i - gap; j >= 0 && data[j] > key; j -= gap) //降序
    				data[j+gap] = data[j];
    			data[j+gap] = key;
    		}
    	}
    }
    
    //归并排序
    //时间复杂度:O(nlog(n)),取n次堆顶元素,并维护n次堆,每次维护时间为O(log(n))
    /*
    初始化:将整个序列建立成一个堆。
    循环:堆顶元素(最值)与最后一个元素互换,堆的最后一个元素即为最大(以大顶堆为例)记录,完成一次排序
    	接着将前N-1个元素(即不包括最大记录)进行大顶堆维护,再将堆顶元素与最后一个元素互换,得到次大值。
    	重复以上步骤,直至堆中只剩一个记录,排序结束。
    */
    template <typename T>
    void Merge(T *array, int low, int mid, int high)
    {
    	int i, j, k;
    	T *temp = (T *)malloc((high - low + 1) * sizeof(T));
    	i = low, j = mid + 1, k = 0;
    	while(i <= mid && j <= high)	//合并已排好序的前后两半数组元素,以mid为中点分割。
    	{
    		if(array[i] < array[j])	//升序
    			temp[k++] = array[i++];
    		else
    			temp[k++] = array[j++];
    	}
    	while(i <= mid)				//若前一半中还有未处理完的元素
    		temp[k++] = array[i++];
    	while(j <= high)			//若后一半中还有未处理完的元素
    		temp[k++] = array[j++];
    	for(i = low, j = 0; i <= high; ++i)	//将排好序的元素从临时数组temp输入到array中,并释放temp;
    		array[i] = temp[j++];
    	free(temp);
    }
    
    template <typename T>
    void Mergesort(T *array, int low, int high)
    {
    	int mid;
    	if(low < high)
    	{
    		mid = (low + high) >> 1;
    		//递归:二分分解,直至单元素
    		Mergesort(array, low, mid);
    		Mergesort(array, mid + 1, high);
    		//合并:每次合并都是合并两个排好序的子数组
    		Merge(array, low, mid, high);
    	}
    }
    
    //堆排序
    
    //对堆进行调整,使下标从s到m的无序序列成为一个大顶堆
    //堆的维护/保持
    //一次堆维护的时间复杂度为O(lg(n))
    template <typename T>
    void HeapAjust(T *array, int s, int m)
    {
    	int j, temp = array[s];
    	//节点s的左子树的下标为:2s+1,右子树下标:2s+2.其实下标为0;
    	for(j = 2*s; j <= m; j *=2)
    	{
    		//选出左右孩子中较大者与父节点比较
    		if(j < m && array[j] < array[j+1])
    			++j;
    		if(temp >= array[j])	//若父节点大于等于左右孩子,则满足大顶堆的定义,跳出循环
    			break;
    		array[s] = array[j];	//否则用较大的节点替换父节点
    		s = j;					//记录下替换父节点的节点下标
    	}
    	array[s] = temp;
    }
    
    //堆的排序(排序过程不断的维护堆)
    //http://blog.csdn.net/sdlwlxf/article/details/24645557
    template <typename T>
    void Heapsort(T *array, int len)
    {
    	int i;
    	// 建堆,堆的叶子节点下标为len/2~len-1,
    	//初始化:第一轮循环之前:初始化时只有叶子节点,也是最大堆的根。
    	//保持:每次添加一个新节点都对堆进行维护保持。维护时间为O(lg(n))
    	//终止:当i=0时,每个都是最大堆的跟。一个堆建立了。
    	//建堆的时间复杂度为O(n)而不是O(nlg(n)),详见算法导论 P78.
    	for(i = len / 2 - 1; i >= 0; --i)
    		HeapAjust(array, i, len - 1);
    	//每次将堆顶的元素(数组中最大的元素)与最后元素互换,最大元素就排在最后了。
    	//由于换过来的元素不一定满足大顶堆,需要维护一次大顶堆,再转到步骤一,直至循环结束。
    	//排序结束,升序。
    	for(i = len - 1; i > 0; --i)
    	{
    		swap(array[0], array[i]);
    		HeapAjust(array, 0, i-1);
    	}
    }
    
    //直接选择排序
    //时间复杂度为O(n2),与序列的初始状态无关。
    //不稳定:例子:2 2 1
    /*
    简单选择排序的基本思想:第i趟简单选择排序是指通过n-i次关键字的比较,
    从n-i+1个记录中选出关键字最小的记录,并和第i个记录进行交换。共需进行i-1趟比较,直到所有记录排序完成为止。
    例如:进行第i趟选择时,从当前候选记录中选出关键字最小的k号记录,并和第i个记录进行交换。
    */
    template <typename T>
    void SelectSort(T *array, int len)
    {
    	int i = 0, j = 0, k = 0;
    	for(i = 0; i < len - 1; ++i)
    	{
    		k = i;
    		for(j = i+1; j < len; ++j)	//从后面选择一个最小的元素
    		{
    			if(array[j] < array[k])
    				k = j;
    		}
    		if(k != i)		//与第i个元素交换
    			swap(array[i], array[k]);
    	}
    }
    
    //冒泡排序,下面这并不是真正的冒泡。
    template <typename T>
    void BubbleSort(T *array, int len)
    {
    	int i = 0, j = 0;
    	for(i = 0; i < len - 1; ++i)
    	{
    		for(j = i + 1; j < len; ++j)
    		{
    			if(array[j] < array[i])
    				swap(array[i], array[j]);
    		}
    	}
    }
    
    
    template <typename T>
    void BubbleSort2(T *array, int len)
    {
    	int i = 0, j = 0;
    	for(i = 0; i < len - 1; ++i)
    	{
    		for(j = len - 1; j > i; --j)
    		{
    			if(array[j] < array[j-1])	//将最小值像水中气泡冒上去。
    				swap(array[j], array[j-1]);
    		}
    	}
    }
    
    
    int main()
    {
    	int num;
    	int arr[200];
    	int count=0;
    
    #if 0
    	while(cin>>num)
    	{
    		arr[count++]=num;
    	}
    	qsort_job(arr, 0, count-1);
    	for(int i = 0; i < count; i++)
    	{
    		cout << arr[i] << " ";
    	}
    	cout << endl;
    #endif
    
    	while(cin>>num)
    	{
    		arr[count++]=num;
    	}
    	SelectSort(arr,count);
    	for(int i = 0; i < count; i++)
    	{
    		cout << arr[i] << " ";
    	}
    	cout << endl;
    
    	system("pause");
    
    	return 0;
    }
    
    
    /*
    参考
    http://blog.csdn.net/hackbuteer1/article/details/6568913
    */


  • 相关阅读:
    web应用/http协议/web框架
    算法-排序-1.冒泡排序/2.选择排序/3.插入排序
    算法-基础和查找-1.汉诺塔/2.顺序查找/3.二分查找/4.顺序查找和二分查找的比较
    前端开发
    前端开发
    前端开发
    前端开发
    数据库
    LeetCode : Add Binary
    LeetCode : Length of Last Word
  • 原文地址:https://www.cnblogs.com/cnsec/p/3789812.html
Copyright © 2020-2023  润新知