排序最全总结

http://www.docin.com/p-614435589.html
http://www.docin.com/p-300941887.html
http://www.cnblogs.com/alexworks/articles/1847080.html
排序法	最差时间分析	平均时间复杂度	稳定度	空间复杂度
冒泡排序	O(n2)	O(n2)	稳定	O(1)
快速排序	O(n2)	O(n*log2n)	不稳定	O(log2n)~O(n)递归
选择排序	O(n2)	O(n2)	不稳定	O(1)
二叉树排序	O(n2)	O(n*log2n)	不一定	O(n)
插入排序	O(n2)	O(n2)	稳定	O(1)
折半插入排序	O(n2)	O(n2)	稳定	O(1)
希尔排序	O	O	不稳定	O(1)
堆排序	O(n*log2n)	O(n*log2n)	不稳定	O(1)
归并排序	O(n*log2n)	O(n*log2n)	稳定	O(n)//递归
基数排序	O(n)	O(n)	稳定	O(n)
桶排序	O(n)	O(n)	稳定	O(n)
				
				
				
				
插入排序
原理:将数组分为无序区和有序区两个区,然后不断将无序区的第一个元素按大小顺序插入到有序区中去,最终将所有无序区元素都移动到有序区完成排序。
直接插入:
void InsertSort(int *a,int n)
{
	int j;
    int temp;
   for (int i=1;i<n;i++)
   {
        temp=a[i];
		j=i;
		while (j>0&&a[j-1]>temp)
		{
			a[j]=a[j-1];
			j--;//查找与移动同时进行
		}
		a[j]=temp;
   }
}
折半插入:
void BinaryInsertSort(int *a,int n)
{
	int temp,low,mid,high;
	for (int i=1;i<n;i++)
	{
       temp=a[i];
	   low=0;
	   high=i-1;
	   while (high>=low)//用对半查找
	   {
             mid=(high+low)/2;
			 if (temp<a[mid])
			 {
				high=mid-1;
			 } 
			 else
			 {
				  low=mid+1;
			 }
	   }
	   for (int j=i;j>low;j--)//移动
	   {
		   a[j]=a[j-1];
	   }
      a[low]=temp;//放在这个位置
	}
}
希尔排序(插入):
先取一个整数k,把全部记录分成k个组,所有距离是k的看成一个组插入排序,然后
k=k/2;
void shellsort(int *a,int n)
{
    int k=n/2;
	while (k>=1)
	{
        for (int i=0;i<k;i++)//第i组,共有k组
        {
			for (int j=k+i;j<n;j+=k)//组内移动,每次k个单位
			{
				int temp=a[j];//记录要插入的值
				int m=j;//记录该位置
                while ((m-k)>=0&&temp<a[m-k])
                {
					a[m]=a[m-k];
					m=m-k;
                }
				a[m]=temp;
			}
        }
		k=k/2;
	}
}
//冒泡排序
void BubbleSort(int *a,int n)
{
      for (int i=0;i<n;i++)//控制比较次数
      {
		  for (int j=1;j<n-i;j++)//从1开始
		  {
			  if (a[j-1]>a[j])
			  {
				  int temp=a[j-1];
				  a[j-1]=a[j];
				  a[j]=temp;
			  }
		  }
      }
}
改进版http://blog.csdn.net/morewindows/article/details/6657829
void BubbleSort(int *a,int n)
{
      Int k=n;
		  for (int j=1;j<k;j++)//从1开始
		  {
			  if (a[j-1]>a[j])
			  {
				  int temp=a[j-1];
				  a[j-1]=a[j];
				  a[j]=temp;
			  }
		  }
     K--;
}
1.	//冒泡排序3  
2.	void BubbleSort3(int a[], int n)  
3.	{  
4.	    int j, k;  
5.	    int flag;  
6.	      
7.	    flag = n;  
8.	    while (flag > 0)  
9.	    {  
10.	        k = flag;  
11.	        flag = 0;  
12.	        for (j = 1; j < k; j++)  
13.	            if (a[j - 1] > a[j])  
14.	            {  
15.	                Swap(a[j - 1], a[j]);  
16.	                flag = j;  
17.	            }  
18.	    }  
19.	} 
20.	
选择排序
  选择排序是给每个位置选择当前元素最小的,比如给第一个位置选择最小的,在剩余元素里面给第二个元素选择第二小的,依次类推,直到第n-1个元素,第n个元素不用选择了,因为只剩下它一个最大的元素了。那么,在一趟选择,如果当前元素比一个元素小,而该小的元素又出现在一个和当前元素相等的元素后面,那么交换后稳定性就被破坏了。比较拗口,举个例子,序列5 8 5 2 9, 我们知道第一遍选择第1个元素5会和2交换,那么原序列中2个5的相对前后顺序就被破坏了,所以选择排序不是一个稳定的排序算法。
void SelectSort(int *a,int n)
{
    for (int i=0;i<n;i++)
    {
		int minnum=a[i];//初始记为最小值
		int minposition=i;
		for (int j=i+1;j<n;j++)//寻找后面的最小值
		{
               if (a[j]<minnum)
               {
				   minnum=a[j];
				   minposition=j;
               }
		}
     swap(a[minposition],a[i]);//当前位置与后面的最小值交换
    }
}
快速排序
http://blog.csdn.net/morewindows/article/details/6684558
分析:数据结构p186.重要
当源文件有序时复杂度是o(n2).此时冒泡排序最好,无序时快速排序是最好的方法。
void QuickSort(int *a,int l,int r)
{
	if (r<=l)
	{
		return;
	}
	int i=l;
	int j=r;
	int x=a[i];//a[l]即a[i]就是第一个坑 
    //挖坑填数
	while (j>i)
	{
		 // 从右向左找小于x的数来填a[i]  
		while (a[j]>=x&&j>i)
		{
			j--;
		}
		if (j>i)
		{
			a[i]=a[j];//a[j]填到a[i]中,a[j]就形成了一个新的坑  
			i++;
		}
		// 从左向右找大于或等于x的数来填a[j]  
		while (a[i]<x&&j>i)
		{
			i++;
		}
		if (j>i)
		{
			a[j]=a[i];//将a[i]填到a[j]中,a[i]就形成了一个新的坑  
			j--;
		}
	}
	//退出时,i等于j。将x填到这个坑中。
	a[i]=x;
	//分治法
	QuickSort(a,l,i-1);
    QuickSort(a,i+1,r);
}
//桶式排序   http://blog.csdn.net/hyhyl1990/article/details/7610279
#define N 10            //N表示要排序数组的数字个数
#define M 89        //M表示要排序元素中的最大值(元素值从0到M)
void bucketSort(int  arr[],int n) //缺点:浪费了一大块内存
{
	int  Times[M+1]={0};//每个数对应一个桶,该数组存放每个桶的数字个数。初始为0
	int  TempArr[N];
	for (int i=0;i<n;i++)//统计各数字出现的次数
	{
		Times[arr[i]]++;
	}
	//重新组织存放出现次数的数组 ,Times[i]-1是第i个桶的右边界索引 ,	
	for (int i=1;i<M+1;i++)
	{
		Times[i]+=Times[i-1];
	}
	//相同的数字位于同一个桶内,按照先后进入桶内的顺序根据该桶索引依次减小存放进该桶。
	for (int i=n-1;i>=0;i--)//为了排序稳定性,从后面开始
	{
		TempArr[--Times[arr[i]]]=arr[i];
	}
	for (int i=0;i<n;i++)
	{
		arr[i]=TempArr[i];
	}
}
//基式排序,原理同上,但是没有存在浪费内存的问题,按个位数排,然后再按十位数排。。。类似于扑克牌排序
void radixSort(int arr[],int n,int cou)   //n表示数组内元素个数,cou表示位数
{  
	int radix=10;//十进制,共有10个数
	int* tempArr=new int[n];	//开辟一个临时数组
	int Times[10]={0};	//存放进制内各数出现的次数
	int rad=1;				//动态变化的基数
	int Temp;
	for (int i=0;i<cou;i++)//先从个位数开始,从低位到高位,依次进行判定 
	{
		//一轮判定开始时,需要对times数组重置为0
		for(int j=0;j<radix;j++)
		{
			Times[j]=0;
		}
            for (int j=0;j<n;j++)
            {
				Temp=(arr[j]/rad)%10;// //需要得到正在判定的这一位上的值 
                 Times[Temp]++;
            }
			//对times数组进行重置 
           for (int j=1;j<10;j++)
           {
			   Times[j]+=Times[j-1];
           }
		    //对原数组内的元素进行收集,放在临时数组中。(从后面开始) 
		   for (int j=n-1;j>=0;j--)//为了排序稳定性,从后面开始
		   {
			   Temp=(arr[j]/rad)%10;// //需要得到正在判定的这一位上的值 
               tempArr[--Times[Temp]]=arr[j];
		   }
		    //把临时数组tempArr内的元素复制到arr数组中  
		   for (int j=0;j<n;j++)
		   {
			   arr[j]=tempArr[j];
		   }
		    rad*=radix; //该趟循环结束,rad=rad*radix 
	}
}
堆与堆排序
http://blog.csdn.net/morewindows/article/details/6709644
//  从i节点开始调整,n为节点总数 从0开始计算 i节点的子节点为 2*i+1, 2*i+2
void MinHeapFixdown(int a[], int i, int n)
{
	int j, temp;

	temp = a[i];
	j = 2 * i + 1;
	while (j < n)
	{
		if (j + 1 < n && a[j + 1] < a[j]) //在左右孩子中找最小的
			j++;

		if (a[j] >= temp)
			break;

		a[i] = a[j];     //把较小的子结点往上移动,替换它的父结点
		i = j;
		j = 2 * i + 1;
	}
	a[i] = temp;
}
//由数组建立最小堆
void MakeMinHeap(int a[], int n)
{
	for (int i = n / 2 - 1; i >= 0; i--)
		MinHeapFixdown(a, i, n);
}
void Swap(int &a,int &b)
{ 
    int temp=a;
	a=b;
	b=temp;
}
//堆排序
void Minheapsort(int a[], int n)
{
    MakeMinHeap(a,n);//由数组建立二叉堆
	for (int i = n - 1; i >= 1; i--)
	{
		Swap(a[i], a[0]);
		MinHeapFixdown(a, 0, i);
	}
}
归并排序
http://blog.csdn.net/morewindows/article/details/6678165
//将有二个有序数列a[first...mid]和a[mid...last]合并。
void mergearray(int a[], int first, int mid, int last, int temp[])
{
	int i=first;
	int n=mid;
	int j=mid+1;
	int m=last;
	int k=0;
	while (i<=n&&j<=m)
	{
		//比较二个数列的第一个数,谁小就先取谁,取了后就在对应数列中删除这个数
		if (a[i]<a[j])
		{
			temp[k++]=a[i++];
		} 
		else
		{
			temp[k++]=a[j++];
		}
	}
	//有数列为空,那直接将另一个数列的数据依次取出即可
	while (i<=n)
	{
		temp[k++]=a[i++];
	}
	while (j<=m)
	{
		temp[k++]=a[j++];
	}
   for (i=0;i<k;i++)
   {
	   a[first+i]=temp[i];
   }
}
void mergesort(int a[], int first, int last, int temp[])  
{  
	if (first < last)  
	{  
		int mid = (first + last) / 2;  
		mergesort(a, first, mid, temp);    //左边有序  
		mergesort(a, mid + 1, last, temp); //右边有序  
		mergearray(a, first, mid, last, temp); //再将二个有序数列合并  
	}  
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值