排序算法总结

偶然有空想到,对各种不同的排序算法进行一下总结。比较常用的排序算法有十种。

1.冒泡排序
思路:比较相邻的元素。如果第一个比第二个大,就交换它们两个;对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大的数;针对所有的元素重复以上的步骤,除了最后一个;重复以上的步骤,直到排序完成。
代码:

void bubbleSort(int arr[]) 
{
    int len = arr.length();
    for (int i = 0; i < len - 1; i++) 
    {
        for (int j = 0; j < len - 1 - i; j++) 
        {
            if (arr[j] > arr[j+1]) 
            {        
                int temp = arr[j+1];       
                arr[j+1] = arr[j];
                arr[j] = temp;
            }
        }
    }
}

2.选择排序
思路:初始状态:无序区为R[1…n],有序区为空;第i次排序开始时,当前有序区和无序区分别为R[1…i-1]和R(i…n)。该趟排序从当前无序区中-选出关键字最小的记录 R[k],将它与无序区的第1个记录R交换,使R[1…i]和R[i+1…n)分别变为记录个数增加1个的新有序区和记录个数减少1个的新无序区;n-1次排序结束之后,数组就有序化了。
代码:

void selectionSort( int arr[]) 
{
    int len = arr.length();
    int min;
    for (int i = 0; i < len - 1; i++) 
    {
        min = i;
        for (int j = i + 1; j < len; j++) 
        {
            if (arr[j] < arr[min]) 
            {    
                min = j;      
            }
        }
        int temp = arr[i];
        arr[i] = arr[min];
        arr[min] = temp;
    }
} 

3.插入排序
思路:从第一个元素开始,将此元素认为已经被排序;取下一个元素,在已经排序的元素序列中从后向前扫描;如果该元素(已排序)大于新元素,将该元素移到下一位置;重复上一步骤,直到找到已排序的元素小于或者等于新元素的位置;将新元素插入到该位置后;重复之前的步骤。
代码:

void insertionSort(int arr[]) 
{
    int len = arr.length();
    int pre, cur;
    for (int i = 1; i < len; i++) 
    {
        pre = i - 1;
        cur = arr[i];
        while (pre >= 0 && arr[pre] > cur) 
        {
            arr[pre + 1] = arr[pre];
            pre--;
        }
        arr[pre + 1] = cur;
    }
}

4.希尔排序
思路:是插入排序的改进;将待排序数组按照步长进行分组,然后将每组的元素利用直接插入排序的方法进行排序;通常最初采用数组的一半作为步长;每次将步长折半减小,循环上述操作;当步长为1时,利用直接插入,完成排序。
代码:

void shellSort(int arr[]) 
{
    int i, j, gap, len = arr.length();
    gap = len/2;
    while (gap >= 1)
    {
        for (i = gap + 1; i <= len; i++)
        {
            arr[0] = arr[i];   
            j = i - gap; 
            while((j > 0)&&(arr[0] < arr[j]))
            {
                arr[j + d]= arr[j];
                j = j - gap;
            }
            arr[j + d] = arr[0];
        }
        gap = gap/2;
}

5.归并排序
思路:采用分治法的思想,分为三步;分解:将n个元素分成个含n/2个元素的子序列;解决:用合并排序法对两个子序列递归的排序;合并:合并两个已排序的子序列已得到排序结果。
代码:

void mergesort(int arr[], int reg[], int start, int end) 
{
    if (start >= end)
        return;
    int len = end - start, mid = (len >> 1) + start;
    int start1 = start, end1 = mid;
    int start2 = mid + 1, end2 = end;
    mergesort(arr, reg, start1, end1);
    mergesort(arr, reg, start2, end2);
    int k = start;
    while (start1 <= end1 && start2 <= end2)
        reg[k++] = arr[start1] < arr[start2] ? arr[start1++] : arr[start2++];
    while (start1 <= end1)
        reg[k++] = arr[start1++];
    while (start2 <= end2)
        reg[k++] = arr[start2++];
    for (k = start; k <= end; k++)
        arr[k] = reg[k];
}

6.快速排序
思路:快速排序使用分治法来把一个串分为两个子串;从数列中挑出一个元素,称为 “基准”;重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置;递归地把小于基准值元素的子数列和大于基准值元素的子数列排序。
代码:

void quickSort(int arr[], int left, int right) {
	if (left > right) {
		return;
	}
	int i = left;
	int j = right;
	int base = arr[left];
	while(i != j) {
		while(arr[j] >= base && i<j) {
			j--;
		}

		while(arr[i] <= base && i<j) {
			i++;
		}		
		if(i<j) {
			int tmp = arr[i];
			arr[i] = arr[j];
			arr[j] = tmp;
		}
	}
	arr[left] = arr[i];
	arr[i] = base;
	quickSort(arr, left, i-1);
	quickSort(arr, i+1, right);
}

7.堆排序
思路:使用堆这一数据结构进行排序;将初始待排序关键字序列(R1,R2….Rn)构建成大顶堆,此堆为初始的无序区;将堆顶元素R[1]与最后一个元素R[n]交换,此时得到新的无序区(R1,R2,……Rn-1)和新的有序区(Rn),且满足R[1,2…n-1]<=R[n];由于交换后新的堆顶R[1]可能违反堆的性质,因此需要对当前无序区(R1,R2,……Rn-1)调整为新堆,然后再次将R[1]与无序区最后一个元素交换,得到新的无序区(R1,R2….Rn-2)和新的有序区(Rn-1,Rn)。不断重复此过程直到有序区的元素个数为n-1,则整个排序过程完成。
代码:

void heapSort(int arr[], int n) 
{
	Build_Heap(arr, n);
	for (int i = n - 1; i >= 0; i--)        
	{
		swap(arr[0], arr[i]);
		Heapify(arr, i, 0);
	}
}

void Heapify(int tree[], int n, int m) 
{
	if (m >= n) return;
	int c1 = 2 * m + 1;
	int c2 = 2 * m + 2;
	int max = m; 
	if (c1<n && tree[c1] > tree[max])  
		max = c1; 
	if (c2<n && tree[c2] > tree[max]) 
		max = c2;
	if (max != m) {                          
		swap(tree[max], tree[m]);
		Heapify(tree, n, max);
	}
		
}

void Build_Heap(int arr[], int n)  
{
	int last_node = n - 1;  
	int last_heapify_node = (n-1)/2;
	for (int i = last_heapify_node; i >= 0; i--)
	{
		Heapify(arr, n, i);
	}
}

8.计数排序
思路:建立一个新数组C;找出待排序的数组中最大和最小的元素;统计数组中每个值为i的元素出现的次数,存入数组C的第i项;对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加);反向填充目标数组:将每个元素i放在新数组的第C(i)项,每放一个元素就将C(i)减去1。
代码:

void countingSort(int arr[], int max) 
{
    int c[max + 1];
        sorted = 0;
        len = arr.length();
        cen = max + 1;
 
    for (int i = 0; i < len; i++) 
    {
        if (!c[arr[i]]) 
        {
            c[arr[i]] = 0;
        }
        c[arr[i]]++;
    }
 
    for (int j = 0; j < cen; j++) 
    {
        while(c[j] > 0) 
        {
            arr[sorted++] = j;
            c[j]--;
        }
    }
}

9.桶排序
思路:桶排序是计数排序的改进;定义一个映射函数来决定数据放入的桶及桶的数量;设置一个定量的数组当作空桶;遍历输入数据,并且把数据一个一个放到对应的桶里去;对每个不是空的桶进行排序;从不是空的桶里把排好序的数据拼接起来。
代码:

void bucketSort(int arr[] , int max)
{
    int len = arr.length();
    int tmparr[max + 1];
    for(int i = 0; i <= max; i++) 
        tmparr[i] = 0;
    
    for(int i = 0; i < len; i++) 
        tmparr[ arr[i] ]++;
    
    for(int i = 0; i < max; i ++)
    {
    int j=0;
        while( tmparr[i] != 0) 
        {
            arr[j] = i;
            j++;
            tmparr[i]--;
        }
    }
}

10.基数排序
思路:取得数组中的最大数,并取得位数;arr为原始数组,从最低位开始取每个位组成radix数组;对radix进行计数排序(利用计数排序适用于小范围数的特点);
代码:

void radixSort(int arr[], int len)	
{
    	int d=1;
    	int p=10;
    	for(int i=0;i<len;i++)
    	{	
		while(arr[i]>=p)
        	{
            		p=p*10;
            		d++;
        	}
    	}
    	int temp[len];
    	int count[10];
    	int radix=1;
    	for(int i=1;i<=d;i++)  
    	{
		for(int j=0;j<10;j++)	
            		count[j]=0; 
        	for(int j=0;j<n;j++)
        	{
            		int k=(arr[j]/radix)%10;  
            		count[k]++; 
        	}
        	for(int j=1;j<10;j++)
            		count[j]=count[j-1]+count[j]; 
        	for(int j=n-1;j>=0;j--)
        	{
            		k=(arr[j]/radix)%10;
            		temp[count[k]-1]=arr[j];
            		count[k]--;
        	}
        	for(int j=0;j<n;j++) 
            		arr[j]=temp[j];
        	radix=radix*10;
    	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值