七大排序总结(附源代码)

本文实现了冒泡排序,直接插入排序,直接选择排序,快速排序,堆排序,归并排序,希尔排序其中排序算法,并指出他们的时间复杂度以及稳定性情况。

#include<stdio.h>
void swap(int* a, int* b)
{
	int temp;
	temp = *a;
	*a = *b;
	*b = temp;
}
/*
//冒泡排序:每次都将最大值放到要排的序列末尾
//时间复杂度为O(n^2)
//属于稳定算法
3,1,8,2,5,7,9,4,6
132578469
123574689
123546789
123456789
123456789
123456789
123456789
123456789
123456789
void bubbleSort(int* arr, int length)
{
	int i, j;
	for(int i=0; i<length; i++)
		for(int j=1; j<length-i;j++)
		{
			if(arr[j]<arr[j-1])
				swap(&arr[j],&arr[j-1]);
		}
}
//改进的冒泡排序:设置一个标志,如果这一趟发生了交换,则为true,否则为false。
//明显如果有一趟没有发生交换,说明排序已经完成。
void bubbleSort(int* arr, int length)
{
	int i;
	bool flag = true;
	while(flag)
	{
		flag = false;
		for(int i=1; i<length; i++)
		{
			if(arr[i]<arr[i-1])
				swap(&arr[i],&arr[i-1]);
			flag=true;
		}
		length--;
	}
}
*/


/*
//直接插入排序:选取第一个数字作为初始有序数列,
//将后面的无序数列依次插入有序数列的合适位置
//最坏时间复杂度为O(n^2)
//属于稳定算法
3,1,8,2,5,7,9,4,6
138257946
138257946
123857946
123587946
123578946
123457896
123456789
123456789
void insertSort(int* arr, int length)
{
	int i,j;
	for(i=1; i<length;i++)
	{
		if(arr[i]<arr[i-1])
		{
			int temp = arr[i];	//在序列中找到第一个比前一个数字大的数字的索引
			for(j = i-1;j>=0 && arr[j]>temp;j--) //找到放temp的正确位置,且不越界
			{
				arr[j+1] = arr[j];//将前面比temp大的数字后移
			}
			arr[j+1] = temp;	//在正确位置放置temp
		}	
	}	
}
*/

/*
//希尔排序:先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组。
//所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;
//然后,取第二个增量d2<d1重复上述的分组和排序,
//直至所取的增量dt=1(dt<dt-l<…<d2<d1),即所有记录放在同一组中进行直接插入排序为止。
//希尔排序的时间复杂度与增量序列的选取有关,采用希尔增量时间复杂度为O(n^2)
//采用Hibbard增量时间复杂度为O(n^3/2);希尔排序相对于前面两种有较大改进
//属于不稳定算法
void shellSort(int* arr, int length)
{
	int i,j,d,temp;
	for(d = length/2; d>0; d=d/2)	//采用希尔增量
	{
		for(i=d;i<length;i=i+d)		//分组插入排序
		{
			if(arr[i]<arr[i-d])
			{
				temp = arr[i];
				for(j=i-d;j>=0&&arr[j]>temp;j=j-d)
				{
					arr[j+d] = arr[j];
				}
				arr[j+d] = temp;
			}
		}
	}
}
*/
/*
//直接选择排序:直接选择排序和直接插入排序类似,都将数列分为
//有序区和无序区,所不同的是直接选择排序是将无序区中最小的数
//直接放在有序区的末尾。
//它的时间复杂度是O(n^2)
//不稳定算法
3,1,8,2,5,7,4,6
13825746
12835746
12385746
12348756
12345876
12345687
12345678
void selectSort(int* arr, int length)
{
	int i,j;
	for(i = 0;i<length-1;i++)
	{
		for(j=i+1;j<length;j++)
		{
			if(arr[j]<arr[i])
				swap(&arr[i],&arr[j]);
		}
	}
}
*/
/*
//归并排序:将数列分成两组,如果两组子数列有序,就可以方便地将它们进行排序。
//如果它们无序,则再将它们各自拆分成两组子数列,依次类推。
//它的最好,最坏和平均时间复杂度都为O(n*logn),空间复杂度为O(n)
//属于稳定排序算法
3,1,8,2,5,7,9,4,6
138257946
138257946
123584679
123456789
void merge(int* arr,int* temp_arr,int first,int last,int mid)
{
	int arrIndex1 = first;
	int arrIndex2 = mid+1;
	int index = first;
	while(arrIndex1<=mid && arrIndex2<=last)
	{
		if(arr[arrIndex1]<=arr[arrIndex2])
			temp_arr[index++] = arr[arrIndex1++];
		else
			temp_arr[index++] = arr[arrIndex2++];
	}
	while(arrIndex1<=mid)
		temp_arr[index++] = arr[arrIndex1++];
	while(arrIndex2<=last)
		temp_arr[index++] = arr[arrIndex2++];
	for(int i=0;i<index;i++)	//必须将数组赋值放在这里,否则会导致排好的数列又复原
		arr[i] = temp_arr[i];
}
void merge_sort(int* arr,int* temp_arr,int first,int last)
{
	if(first<last)
	{
		int mid = (first+last)/2;	//递归的拆分
		merge_sort(arr,temp_arr,first,mid);
		merge_sort(arr,temp_arr,mid+1,last);
		merge(arr,temp_arr,first,last,mid);	//合并子数列
	}
}
void mergeSort(int* arr, int length)
{
	if(arr == NULL || length <=0)
		return;
	int* temp_arr=new int[length];	//辅助数列
	merge_sort(arr,temp_arr,0,length-1);
	delete[] temp_arr;
}
*/
/*
//快速排序:通过一趟排序将要排序的数据分割成独立的两部分,
//其中一部分的所有数据都比另外一部分的所有数据都要小,
//然后再按此方法对这两部分数据分别进行快速排序,
//整个排序过程可以递归进行,以此达到整个数据变成有序序列。
//最坏情况O(n*n),平均为O(nlogn);在同为O(nlogn)中,效率最高
//不稳定算法
3,1,8,2,5,7,9,4,6(基准选最后一个)
312546879
312456879
123456789
int partition(int* arr, int start,int end)
{
	int standard = arr[end];
	int small = start-1;
	for(int i=start; i<end; ++i)
	{
		if(arr[i]<standard)
		{
			++small;
			if(i!=small)
			{
				swap(&arr[i],&arr[small]);
			}
		}
	}
	++small;
	swap(&arr[small],&arr[end]);
	return small;
}
void quickSort(int* arr, int start,int end)
{
	if(arr == NULL)
		return;
	if(start<end)
	{
		int index = partition(arr,start,end);
		quickSort(arr,start,index-1);
		quickSort(arr,index+1,end);
	}
}
*/
/*
//堆排序:堆排序利用了大根堆(或小根堆)堆顶记录的关键字最大(或最小)这一特征,
//使得在当前无序区中选取最大(或最小)关键字的记录变得简单。
//时间复杂度:O(N*logN)
//属于不稳定算法
void heapAdjust(int* arr,int length,int i)
{
	int nChild;
	int parent;
	for(parent=arr[i]; 2*i+1<length; i=nChild)
	{	
		nChild = 2*i+1;
		//找出子节点中较大值,并确保不越界
		if(nChild<length-1 && arr[nChild]<arr[nChild+1])
			++nChild;
		//如果找到的子节点大于父节点,将子节点往上移动
		if(arr[nChild]>parent)
		{
			arr[i] = arr[nChild];
			arr[nChild] = parent;
		}
		else
			break;
	}
}
void heapSort(int* arr, int length)
{
	// 调整序列的前半部分元素,调整完之后第一个元素是序列的最大的元素
    //length/2-1是第一个非叶节点
	for(int i=(length-1)/2; i>=0; --i)
		heapAdjust(arr,length,i);

	// 从最后一个元素开始对序列进行调整,不断的缩小调整的范围直到第一个元素
	for(int i=length-1; i>0; --i)
	{
		swap(&arr[0],&arr[i]);		//确保最后的元素最大
		heapAdjust(arr,i,0);	//保证整棵树符合二叉堆性质
	}
}
*/
void test1()
{
	const int length = 9;
	int arr[] = {3,1,8,2,5,7,9,4,6};
	//bubbleSort(arr,length);
	//insertSort(arr,length);
	//shellSort(arr,length);
	//selectSort(arr,length);
	//mergeSort(arr,length);
	//quickSort(arr,0,length-1);
	//heapSort(arr,length);
	for(int i =0;i<length;i++)
		printf("%d\t",arr[i]);
}
int main()
{
	test1();
	return 0;
}

== 参考 http://my.csdn.net/mmc_maodun

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值