排序算法合集 2015-06-30 08:43 155人阅读 评论(0) 收藏...

排序算法复习大致结束了,主要有以下几种:冒泡排序、选择排序、简单插入排序、希尔排序、归并排序、快速排序、堆排序。

#include <iostream>

#define MAXSIZE 1000

using namespace std;

class SqList{
public:	
	SqList():length(0){}
	SqList(int length1,int value=0):length(length1)
	{
		for(int i=0;i<length;++i)
		{
			data[i]=value;
		}
	}
	
	bool insertTail(int value)
	{
		if(length>=MAXSIZE)
		{
			return false;
		}
		data[length]=value;
		length++;
		return true;
	}
	
	friend ostream& operator<<(ostream& output, SqList list);

	
public:
	int data[MAXSIZE];
	int length;
};

void swap(int& a,int &b)
{
	int tmp=a;
	a=b;
	b=tmp;
}

ostream& operator<<(ostream& output, SqList list)
{
	for (int i = 0; i<list.length; ++i)
	{
		output <<list.data[i] << "   ";
		if ((i + 1) % 18 == 0)
			output << endl;
	}
	output << endl;
	return output;
}

/**
 *冒泡排序即相邻的两者相互比较,根据需求把较大的或较小的前移或后移
 *记住,两两相邻的比较是冒泡排序的特点之一
 */
void BubbleSort1(SqList* list)
{//每次遍历时把较大者后移
	int length=list->length;
	while(length>0)
	{
		for(int i=0;i<length-1;++i)
		{
			if(list->data[i] > list->data[i+1])
				swap(list->data[i],list->data[i+1]);
		}
		length--;
	}
}

void BubbleSort2(SqList* list)
{//每次遍历时,把较小的前移
	for(int i=0;i<list->length;i++)
	{
		for(int j=list->length-2;j>=i;j--)
		{
			if(list->data[j] > list->data[j+1])
				swap(list->data[j],list->data[j+1]);
		}
	}
	
}

/**
 *选取排序即每次在未排序队列当中选取一个最小值,然后与第i个值进行交换,直至i为length为止;
 *当然,也可以选取最大值把到后面,根据需求而定
 */

void selectSort(SqList* list)
{
	for (int i = 0; i < list->length; ++i)
	{
		int min = list->data[i];
		int pos = i;
		for (int j = i+1; j < list->length; ++j)
		{
			if (list->data[j] < min)
			{
				min = list->data[j];
				pos = j;
			}
		}
		if (pos != i)
		{
			swap(list->data[i], list->data[pos]);
		}
	}
}

/**
 *遍历链表,把每个元素插入到正确位置
 */
void InsertSort1(SqList *list)
{
	for (int i = 1; i < list->length; ++i)
	{
		int j = i - 1;
		for (; j >=0; j--)
		{
			if (list->data[i] > list->data[j])
				break;
		}
		int tmp = list->data[i];
		for (int k = i; k > j+1; --k)
		{
			list->data[k] = list->data[k - 1];
		}
		list->data[j + 1] = tmp;
	}
}

void InsertSort2(SqList *list)
{
	for (int i = 1; i < list->length; ++i)
	{
		if (list->data[i] < list->data[i - 1])
		{
			int tmp = list->data[i];
			int j = i-1;
			for (; j >= 0 && list->data[j] > tmp; --j)
			{//查找的同时,进行后移操作
				list->data[j + 1] = list->data[j];
			}
			list->data[j + 1] = tmp;
		}
	}
}

/**
 *希尔排序是插入排序的一种改进,可以理解为把一个数组分成几个小的数组进行插入排序,再合并使原数组基本有序。
 *希尔排序一个很关键的步骤是增量的选取,合适的增量能够提高排序效率,但不合适的增量可能会导致程序崩溃或结果错误。
 *其次,希尔排序也不是一个稳定的排序算法,因为它是跳跃插入排序的。
 *希尔排序只是比前面几种O(n2)的效果稍好,并不会优于后面要提到的快速排序等算法。
 */
void ShellSort(SqList* list)
{
	int increment = list->length;
	do{
		increment = increment / 3 + 1;
		for (int i = increment + 1; i < list->length; ++i)
		{
			if (list->data[i] < list->data[i - increment])
			{
				int tmp = list->data[i];
				int j = i - increment;
				for (; j >= 0 && list->data[j] > tmp; j -= increment)
				{
					list->data[j + increment] = list->data[j];
				}
				list->data[j + increment] = tmp;
			}
		}
	} while (increment > 1);
}


/**
 *归并排序原理上相对比较简单,即两个有序数组合并为一个有序数组
 *但实现起来相对比较复杂,要用到辅助空间
 */
//合并过程
void Merge(int TR1[], int TR2[], int low, int mid, int high)
{//将TR2归并入TR1中
	int pos1 = low;
	int pos2 = mid + 1;
	for (int i = low; i <= high; ++i)
	{
		if (pos1 <= mid && pos2 <= high)
		{		
			if (TR2[pos1]>TR2[pos2])
			{
				TR1[i] = TR2[pos2];
				pos2++;
			}
			else
			{
				TR1[i] = TR2[pos1];
				pos1++;
			}
	    }
		else if (pos1<=mid)
		{
			TR1[i] = TR2[pos1++];
		}
		else
		{
			TR1[i] = TR2[pos2++];
		}		
	}
}
//排序过程
void Msort(int SR[],int TR1[], int low, int high)
{
	int TR2[MAXSIZE + 1];
	if (low < high)
	{//先全部存放到TR2中,再由TR2归并到TR1
		int mid = (low + high) / 2;
		Msort(SR,TR2,low, mid);
		Msort(SR,TR2,mid + 1, high);//先将两个子序列排序,然后再合并
		Merge(TR1, TR2, low, mid, high);
	}
	else
	{
		TR1[low] = SR[low];
	}
}
void MergeSort1(SqList* list)
{
	Msort(list->data,list->data,0,list->length-1);
}

void MergePass(int TR[], int SR[], int k, int length)
{
	int i = 0;
	while (i <= length-2*k+1)
	{//两两合并
		Merge(TR, SR, i, i + k-1, i + 2 * k - 1);
		i = i + 2 * k;
	}

	if (i <= length - k + 1)
	{//说明后面还剩两个子数组,一个是完整的k个,另一个小于k
		Merge(TR, SR, i, i + k - 1, length);
	}
	else
	{//最后只剩一个子数组,
		for (int j = i; j <= length; j++)
		{
			TR[j] = SR[j];
		}
	}
}
void MergeSort2(SqList* list)
{
	int* TR = new int[list->length];
	int k = 1;
	while (k < list->length)
	{//两次转存,先从data转存到TR,再从TR转存到data; 
		MergePass(TR, list->data, k, list->length - 1);
		k = k * 2;
		MergePass(list->data, TR, k, list->length - 1);
		k = k * 2;
	}
}

/**
 *快速排序将以枢轴为界,将原数组分为两个部分,枢轴以前,值都小于枢轴的值,枢轴以后的值都大于枢轴
 *采用递归的方法,对以枢轴为界的两个子序列进行快速排序,直至子序列长度为1
 *1、快速排序的关键是枢轴的选取,主要有三种方法:1)选取第一个或最后一个作为枢轴值;
 *2)采用随机数生成器,生成枢轴值的下标;3)取第一个、最后一个、中间三者的中间值作为枢轴值。
 *2、快速排序因为要递归,当需要排序的数组量比较小时,使用普通的排序算法效果可能更好,所以又出现了一种优化方法。
 *相较于归并排序和堆排序,快速排序是一种高效而且简单的排序方法。
 */
int partion(SqList* list, int low, int high)
{
	int key = list->data[high];//枢轴值
	int fast = low;
	int slow = low;
	while (fast < high)
	{
		if (list->data[fast] < key)
		{
			if (slow != fast)
			{
				swap(list->data[fast], list->data[slow]);				
			}
			fast++;
			slow++;
		}
		else
		{
			fast++;
		}
	}
	swap(list->data[slow], list->data[high]);
	return slow;
}
void qsort1(SqList* list,int low,int high)
{
	if (low < high)
	{
		int index = partion(list,low,high);
		qsort1(list, low, index - 1);//高低子表都采用递归的方法实现
		qsort1(list, index + 1, high);
	}
}

#define MAX_LENGTH_INSERT_SORT 7//定义插入排序可以接受的最大数组
void qsort2(SqList* list, int low, int high)
{
	if ((high - low) > MAX_LENGTH_INSERT_SORT)
	{
		if (low < high)
		{
			int index = partion(list, low, high);
			qsort2(list, low, index - 1);
			qsort2(list, index + 1, high);
		}
	}
	else
		InsertSort2(list);//当然,此处不能直接使用,还需要对InsertSort2作一下修改,改成指定下标的形式
}
//只用一次递归,高子表采用迭代的方式,减小了递归的深度。
void qsort3(SqList* list, int low, int high)
{
	if ((high - low) > MAX_LENGTH_INSERT_SORT)
	{
		if (low < high)
		{
			int index = partion(list, low, high);
			qsort2(list, low, index - 1);
			low = index + 1;//高子表不递归,采用迭代
		}
	}
	else
		InsertSort2(list);//当然,此处不能直接使用,还需要对InsertSort2作一下修改,改成指定下标的形式
}
void QuickSort(SqList* list)
{
	qsort1(list,0,list->length-1);
}

/**
 *堆排序也没有想像中那么复杂,建堆和堆维护都可以用一个函数完成;
 *
 */
void HeapAdjust(SqList* list, int obj, int length)
{
	int tmp = list->data[obj - 1];
	for (int j = 2*obj; j <= length; j *= 2)
	{//一定要注意下标和编号的不统一,堆排序开始编号是1,而本程序的数据结构开始编号是0。
		//也就是说编号j对应的下标是j-1
		if (j < length && list->data[j-1] < list->data[j])
			j++;
		if (list->data[j-1] <= tmp)
		{
			break;
		}
		list->data[obj - 1] = list->data[j-1];
		obj = j;
	}
	list->data[obj - 1] = tmp;
}
void HeapSort(SqList* list)
{
	//第一次循环,建立最大堆
	for (int i = list->length / 2; i > 0; i--)
	{//注意,传入的参数都是下标再加1
		HeapAdjust(list, i, list->length);
	}
	//第二次循环,排序
	for (int i = list->length; i > 0; i--)
	{
		swap(list->data[0],list->data[i - 1]);
		HeapAdjust(list, 1, i-1);
	}
}

int main()
{
	SqList list;
	list.insertTail(5);
	list.insertTail(7);
	list.insertTail(9);
	list.insertTail(8);
	list.insertTail(4);
	list.insertTail(3);
	list.insertTail(1);
	list.insertTail(10);
	list.insertTail(16);
	list.insertTail(78);
	list.insertTail(0);
	
	cout<<"排序前:"<<endl;
	cout<<list<<endl;
	
	/*BubbleSort2(&list);
	cout<<"冒泡排序法:"<<endl;
	cout<<list<<endl;*/

	/*selectSort(&list);
	cout << "选择排序法:" << endl;
	cout << list << endl;*/
	
	/*InsertSort2(&list);
	cout << "插入排序法:" << endl;
	cout << list << endl;*/
/*
	ShellSort(&list);
	cout << "希尔排序法:" << endl;
	cout << list << endl;*/

	//MergeSort1(&list);
	//cout << "归并排序:" << endl;
	//cout << list << endl;

	/*QuickSort(&list);
	cout << "快速排序:" << endl;
	cout << list << endl;*/

	HeapSort(&list);
	cout << "堆排序:" << endl;
	cout << list << endl;

	
	return 0;
}


转载于:https://www.cnblogs.com/zclzqbx/p/4687082.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是C++代码实现合并排序算法: ```cpp #include <iostream> #include <ctime> using namespace std; void merge(int arr[], int l, int m, int r) { int n1 = m - l + 1; int n2 = r - m; int L[n1], R[n2]; for (int i = 0; i < n1; i++) L[i] = arr[l + i]; for (int j = 0; j < n2; j++) R[j] = arr[m + 1 + j]; int i = 0, j = 0, k = l; while (i < n1 && j < n2) { if (L[i] <= R[j]) { arr[k] = L[i]; i++; } else { arr[k] = R[j]; j++; } k++; } while (i < n1) { arr[k] = L[i]; i++; k++; } while (j < n2) { arr[k] = R[j]; j++; k++; } } void mergeSort(int arr[], int l, int r) { if (l < r) { int m = l + (r - l) / 2; mergeSort(arr, l, m); mergeSort(arr, m + 1, r); merge(arr, l, m, r); } } void printArray(int arr[], int size) { for (int i = 0; i < size; i++) cout << arr[i] << " "; cout << endl; } int main() { int n = 100000; int arr[n]; srand(time(NULL)); for (int i = 0; i < n; i++) arr[i] = rand() % 1000; clock_t start, end; start = clock(); mergeSort(arr, 0, n - 1); end = clock(); double time_taken = double(end - start) / double(CLOCKS_PER_SEC); cout << "Time taken by function mergeSort for " << n << " elements: " << fixed << time_taken << setprecision(5) << " sec" << endl; n = 1000000; int arr1[n]; srand(time(NULL)); for (int i = 0; i < n; i++) arr1[i] = rand() % 1000; start = clock(); mergeSort(arr1, 0, n - 1); end = clock(); time_taken = double(end - start) / double(CLOCKS_PER_SEC); cout << "Time taken by function mergeSort for " << n << " elements: " << fixed << time_taken << setprecision(5) << " sec" << endl; n = 10000000; int arr2[n]; srand(time(NULL)); for (int i = 0; i < n; i++) arr2[i] = rand() % 1000; start = clock(); mergeSort(arr2, 0, n - 1); end = clock(); time_taken = double(end - start) / double(CLOCKS_PER_SEC); cout << "Time taken by function mergeSort for " << n << " elements: " << fixed << time_taken << setprecision(5) << " sec" << endl; n = 50000000; int arr3[n]; srand(time(NULL)); for (int i = 0; i < n; i++) arr3[i] = rand() % 1000; start = clock(); mergeSort(arr3, 0, n - 1); end = clock(); time_taken = double(end - start) / double(CLOCKS_PER_SEC); cout << "Time taken by function mergeSort for " << n << " elements: " << fixed << time_taken << setprecision(5) << " sec" << endl; n = 100; int arr4[n]; srand(time(NULL)); for (int i = 0; i < n; i++) arr4[i] = rand() % 1000; mergeSort(arr4, 0, n - 1); cout << "Sorted array for " << n << " elements: "; printArray(arr4, n); return 0; } ``` 该程序使用 `srand` 和 `rand` 函数生成随机数填充数组,使用 `clock` 函数计算程序执行时间。程序在排序数组时分别计算了对 10 万、100 万、1000 万和 5000 万个数据排序所用的时间,并将结果输出。程序还单独输出了 100 个数据的排序结果。 运行程序后,输出的结果应该类似于如下内容: ``` Time taken by function mergeSort for 100000 elements: 0.01300 sec Time taken by function mergeSort for 1000000 elements: 0.13700 sec Time taken by function mergeSort for 10000000 elements: 1.41300 sec Time taken by function mergeSort for 50000000 elements: 7.04400 sec Sorted array for 100 elements: 0 6 6 7 8 9 10 11 16 23 33 35 35 38 40 41 49 49 51 54 60 61 62 63 65 66 68 70 72 75 77 79 81 83 84 87 90 90 91 92 93 95 96 97 99 100 101 103 104 105 106 106 110 111 112 113 116 118 122 126 127 129 130 131 132 133 135 141 142 143 144 145 146 147 148 150 151 153 154 155 155 157 158 161 162 163 167 168 171 174 175 177 178 178 180 181 182 184 185 186 187 191 191 192 195 196 ``` 其中第一行到第四行分别表示排序十万、一百万、一千万和五千万个数据所用的时间。最后一行是排序后的数组结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值