您的位置:首页 > 其它

常用排序算法总结

2015-12-14 19:44 232 查看
1.直接插入排序

直接插入排序是一种最为简单的排序方法。

直接插入排序的基本思想:第i趟排序将序列中的第i+1个元素k[i+1]插入到一个已经按值有序的子序列(k[1],k[2],...k[i])中的合适的位置,使得插入后的序列依然按值有序。

直接插入排序(straight insertion sort)的做法是:每次从无序表中取出第一个元素,把它插入到有序表的合适位置,使有序表仍然有序。第一趟比较前两个数,然后把第二个数按大小插入到有序表中;
第二趟把第三个数据与前两个数从后向前扫描,把第三个数按大小插入到有序表中;依次进行下去,进行了(n-1)趟扫描以后就完成了整个排序过程。

代码如下:

#include<stdio.h>
void insertsort(int a[],int n)
{
	int i,j;
	for(i=2;i<=n;i++)
  {
	a[0]=a[i];
	j=i-1;
	while(j>0&&a[0]>a[j])
	{
	a[j+1]=a[j--];
	a[j+1]=a[0];	
	} 
  }
}
int main()
{   
    int i;
    int a[11]={-1,2,4,6,7,18,3,48,21,1,0};          //a[0]作为哨兵,用来存储每次待插入的元素,节省系统空间
    printf("排序前的数组:\n");
    for(i=1;i<=10;i++)
    printf("%d ",a[i]);
    printf("\n");
    insertsort(a,10);
    printf("直接插入排序后的数组:\n");
    for(i=1;i<=10;i++)
    printf("%d ",a[i]); 
	
}



2.选择排序

选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。

#include<stdio.h>
void select_sort(int a[],int n)
{
	int i,j,m,temp;
	for(i=0;i<n-1;i++)
	{
		for(j=i+1;j<n;j++)
		{
			if(a[j]>a[i])
			{
				temp=a[i];
				a[i]=a[j];
				a[j]=temp;
			}
		}
		 
	}
}
int main()
{
    int i;
    int a[10]={2,4,6,7,18,3,48,21,1,0};
    printf("排序前的数组:\n");
    for(i=0;i<10;i++)
    printf("%d ",a[i]);
    printf("\n");
    select_sort(a,10);
    printf("选择排序后的数组:\n");
    for(i=0;i<10;i++)
    printf("%d ",a[i]); 	
}




3.冒泡排序:

冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法

原理:

1.比较相邻的元素。如果第一个比第二个小,就交换他们两个。

2.对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最小的数。

3.针对所有的元素重复以上的步骤,除了最后一个。

4.持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

#include<stdio.h>
 void bubble_sort(int a[],int n)
{
    int i,j,temp;
    for (j=0;j<n-1;j++)
        for (i=0;i<n-1-j;i++)
        {
            if(a[i]<a[i+1])
            {
                temp=a[i];
                a[i]=a[i+1];
                a[i+1]=temp;
            }
        }
}
int main()
{
    int i;
    int a[10]={2,4,6,7,18,3,48,21,1,0};
    printf("排序前的数组:\n");
    for(i=0;i<10;i++)
    printf("%d ",a[i]);
    printf("\n");
    bubble_sort(a,10);
    printf("冒泡排序后的数组:\n");
    for(i=0;i<10;i++)
    printf("%d ",a[i]); 	
}




4.希尔排序

希尔排序(Shell Sort)是插入排序的一种。也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。该方法因DL.Shell于1959年提出而得名。

希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。

基本思想:
先取一个小于n的整数d1作为第一个增量,把文件的全部记录分组。所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量




=1(




<




…<d2<d1),即所有记录放在同一组中进行直接插入排序为止。

该方法实质上是一种分组插入方法

比较相隔较远距离(称为增量)的数,使得数移动时能跨过多个元素,则进行一次比[2] 较就可能消除多个元素交换。D.L.shell于1959年在以他名字命名的排序算法中实现了这一思想。算法先将要排序的一组数按某个增量d分成若干组,每组中记录的下标相差d.对每组中全部元素进行排序,然后再用一个较小的增量对它进行,在每组中再进行排序。当增量减到1时,整个要排序的数被分成一组,排序完成。

一般的初次取序列的一半为增量,以后每次减半,直到增量为1。

#include<stdio.h>
 void shell_sort(int a[],int n)
 {
 	int i,j,temp,gap=n;
 	while(gap>0)
 	{
        for (i=0;i<n-gap;i++)        //子序列采用冒泡排序
        {
            if(a[i]<a[i+gap])
            {
                temp=a[i];
                a[i]=a[i+gap];
                a[i+gap]=temp;
            }
        }
	 gap--;	                //增量减小	
	 }
	
 }
 int main()
{
    int i;
    int a[10]={2,4,6,7,18,3,48,21,1,0};
    printf("排序前的数组:\n");
    for(i=0;i<10;i++)
    printf("%d ",a[i]);
    printf("\n");
    shell_sort(a,10);
    printf("希尔排序后的数组:\n");
    for(i=0;i<10;i++)
    printf("%d ",a[i]); 	
}



5.快速排序

快速排序(Quicksort)是对冒泡排序的一种改进。快速排序由C. A. R. Hoare在1962年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列

设要排序的数组是A[0]……A[N-1],首先任意选取一个数据(通常选用数组的第一个数)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序。值得注意的是,快速排序不是一种稳定的排序算法,也就是说,多个相同的值的相对位置也许会在算法结束时产生变动。

一趟快速排序的算法是:

1)设置两个变量i、j,排序开始的时候:i=0,j=N-1;

2)以第一个数组元素作为关键数据,赋值给key,即key=A[0];

3)从j开始向前搜索,即由后开始向前搜索(j--),找到第一个小于key的值A[j],将A[j]和A[i]互换;

4)从i开始向后搜索,即由前开始向后搜索(i++),找到第一个大于key的A[i],将A[i]和A[j]互换;

5)重复第3、4步,直到i=j; (3,4步中,没找到符合条件的值,即3中A[j]不小于key,4中A[i]不大于key的时候改变j、i的值,使得j=j-1,i=i+1,直至找到为止。找到符合条件的值,进行交换的时候i, j指针位置不变。另外,i==j这一过程一定正好是i+或j-完成的时候,此时令循环结束)。

#include<stdio.h>
#include<stdlib.h>
void swap(int &m,int &n)                             //序列中元素交换
{
int temp;
temp=m;
m = n;
n=temp;

}
void quick_sort(int a[],int m,int n)                
{
	int i,j;
	if(m<n)
	{
		i=m;
		j=n+1;
		while(1)
		{
			do i++;
			while(!(a[m]>=a[i]||i==n));         //重复i++操作
			do j--;
			while(!(a[m]<=a[j]||j==m));          //重复j--操作
	
		if(i<j)
		swap(a[i],a[j]);                            //交换a[i]和a[j]位置
		else
		break;
		}
	
	
	swap(a[m],a[j]);
	quick_sort(a,m,j-1);
	quick_sort(a,j+1,n);
	}
}
 int main()
{
    int i;
    int a[10]={2,4,6,7,18,3,48,21,1,0};
    printf("排序前的数组:\n");
    for(i=0;i<10;i++)
    printf("%d ",a[i]);
    printf("\n");
    quick_sort(a,0,9);
    printf("快速排序后的数组:\n");
    for(i=0;i<10;i++)
    printf("%d ",a[i]); 	
}





6.堆排序
堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构,并同时满足堆性质:即子结点的键值或索引总是小于(或者大于)它的父节点。

#include<stdio.h>
void adjust(int a[],int i,int n)
{
	int j;
	int temp;
	temp=a[i];
	j=2*i;
	while(j<n)
	{
	if(j<n&&a[j]>a[j+1])
	{
	j++;	                     //j为i的左右孩子中较小孩子的序号
	}
	if(temp<=a[j])               
	{
		break;              //temp为最小的孩子,不需要元素的交换
	}
	a[j/2]=a[j];
	j=2*j;
	}
	a[j/2]=temp;
}
void heap_sort(int a[],int n)               
{
	int i;
	int temp;
	for(i=n/2;i>=1;i--)                                //将原序列初始化为一个小顶堆
	{
		adjust(a,i,n);
	}
	for(i=n-1;i>=1;i--)                               //调整序列元素
	{
		temp=a[i+1];
		a[i+1]=a[1];
		a[1]=temp;
		adjust(a,1,i);
	}
}
int main()
{
    int i;
    int a[11]={-11,5,2,12,6,9,0,3,6,15,20};
    printf("排序前的数组:\n");
    for(i=1;i<=10;i++)
    printf("%d ",a[i]);
    printf("\n");
    heap_sort(a,10);
    printf("堆排序后的数组:\n");
    for(i=1;i<=10;i++)
    printf("%d ",a[i]); 	
}



堆排序这里只列出了简单代码,随后会详细介绍。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: