代码改变世界

随笔分类 -  算法---排序

“基数排序”之数组中缺失的数字

2013-11-07 10:38 by youxin, 566 阅读, 收藏, 编辑
摘要: 首先看看题目要求:给定一个无序的整数数组,怎么找到第一个大于0,并且不在此数组的整数。比如[1,2,0]返回3,[3,4,-1,1]返回2,[1, 5, 3, 4, 2]返回6,[100, 3, 2, 1, 6,8, 5]返回4。要求使用O(1)空间和O(n)时间。这道题目初看没有太好的思路,但是借鉴下《白话经典算法系列之十 一道有趣的GOOGLE面试题》这篇文章,我们不发现使用“基数排序”正好可以用来解决这道题目。以{1, 3, 6, -100, 2}为例来简介这种解法:从第一个数字开始,由于a[0]=1,所以不用处理了。第二个数字为3,因此放到第3个位置(下标为2),交换a[1]和a[2] 阅读全文

一个数组中只有0,1,2三种元素,要求对这样的数组进行排序

2013-11-06 17:24 by youxin, 3517 阅读, 收藏, 编辑
摘要: 题目:一个数组中只有0,1,2三种元素,要求对这样的数组进行排序。1.思路:1.1思路1: 第一眼看到这样的题目,会举得非常简单,只需要两次遍历数组就可以完成了。第一次遍历,扫描数组中的元素,每次遇到0则count0++,遇到1则count1++,遇到2则count2++,这样一趟下来就能够统计出... 阅读全文

已知数组长度为100,且基本有序,里面有仅有两个数字位置不对,但具体是那两个数字不知道,数字不重复

2013-11-06 17:19 by youxin, 431 阅读, 收藏, 编辑
摘要: 已知数组长度为100,且基本有序,里面有仅有两个数字位置不对,但具体是那两个数字不知道,数字不重复例如[1993 4 5 6 7 8 9 10 11 …… 88 89 90 91 92 93 94 95 96 97 982100 ]要求从小到大排序void sort(int *array, int len){ int i; int pos = 0; int tmp; for (i = 0; i array[i+1]) { pos = i; break; } } i += 2; ... 阅读全文

桶排序和鸽巢排序

2013-11-06 15:56 by youxin, 1224 阅读, 收藏, 编辑
摘要: 桶排序 (Bucket sort)或所谓的箱排序,是一个排序算法,工作的原理是将数组分到有限数量的桶子里。每个桶子再个别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排序)。桶排序是鸽巢排序的一种归纳结果。当要被排序的数组内的数值是均匀分配的时候,桶排序使用线性时间(Θ(n))。但桶排序并不是比较排序,他不受到 O(n log n) 下限的影响。桶排序以下列程序进行:设置一个定量的数组当作空桶子。寻访串行,并且把项目一个一个放到对应的桶子去。对每个不是空的桶子进行排序。从不是空的桶子里把项目再放回原来的串行中。function bucket-sort(array, n) is 阅读全文

计数排序

2013-11-06 15:29 by youxin, 334 阅读, 收藏, 编辑
摘要: 计数排序是一个非基于比较的排序算法,该算法于1954年由 Harold H. Seward 提出。它的优势在于在对一定范围内的整数排序时,它的复杂度为Ο(n+k)(其中k是整数的范围),快于任何比较排序算法计数排序假设n个输入元素都是位于[0, k]之间的整数。基本思想为对于每一个输入元素x,确定出小于x的元素个数,然后直接将x放置在最终数组的位置上。#include #include void counting_sort(int A[], int B[], int length, int max);int main(){ int num, i; printf("Input the. 阅读全文

转:冒泡排序的三种实现

2013-11-01 11:19 by youxin, 301 阅读, 收藏, 编辑
摘要: 冒泡排序是非常容易理解和实现,,以从小到大排序举例:设数组长度为N。1.比较相邻的前后二个数据,如果前面数据大于后面的数据,就将二个数据交换。2.这样对数组的第0个数据到N-1个数据进行一次遍历后,最大的一个数据就“沉”到数组第N-1个位置。3.N=N-1,如果N不为0就重复前面二步,否则排序完成。按照定义很容易写出代码://冒泡排序1void BubbleSort1(int a[], int n){ int i, j; for (i = 0; i a[j]) Swap(a[j - 1], a[j]);}下面对其进... 阅读全文

top k 算法

2013-10-12 00:02 by youxin, 1485 阅读, 收藏, 编辑
摘要: 对于一个非有序的数组A[p..r],求数组中第k小的元素。 如何考虑排序(部分排序)就不用说了。。o(nlgn),当然如果在实际情况中要一直取值,当然要排序后,一次搞定,以后都是O(1)我们这里提供了取一次最K小的一个o(n)的解法,用了快速排序的一种思想,关键在于划分只一个部分,我们知道快速排序选 阅读全文

奇偶排序

2013-09-30 21:30 by youxin, 774 阅读, 收藏, 编辑
摘要: 这个算法一般见得比较少,其核心思想非常简单,在数组中重复两趟扫描。第一趟扫描选择所有的数据项对,a[j]和a[j+1],j是奇数(j=1, 3, 5……)。如果它们的关键字的值次序颠倒,就交换它们。第二趟扫描对所有的偶数数据项进行同样的操作(j=2, 4,6……)。重复进行这样两趟的排序直到数组全部有序。和冒泡排序法一样,奇偶排序的时间复杂度为O(N^2)。以一个实例来说明下:待排数组[6 2 4 1 5 9]第一次比较奇数列,奇数列与它的邻居偶数列比较,如6和2比,4和1比,5和9比[6 24 15 9]交换后变成[2 61 45 9]第二次比较偶数列,即6和1比,5和5比[26 14 59 阅读全文

基数排序

2013-09-01 20:48 by youxin, 1831 阅读, 收藏, 编辑
摘要: 基数排序(英语:Radix sort)是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。由于整数也可以表达字符串(比如名字或日期)和特定格式的浮点数,所以基数排序也不是只能使用于整数。基数排序的发明可以追溯到1887年赫尔曼·何乐礼在打孔卡片制表机(Tabulation Machine)上的贡献[1]。它是这样实现的:将所有待比较数值(正整数)统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列。基数排序的方式可以采用LSD(Least signif 阅读全文

百度面试题:把数组排成最小的数

2013-09-01 03:30 by youxin, 1829 阅读, 收藏, 编辑
摘要: 问题描述:输入一个正整数数组,将它们连接起来排成一个数,输出能排出的所有数字中最小的一个。例如输入数组{32, 321},则输出这两个能排成的最小数字32132。请给出解决问题的算法,并证明该算法。很显然,数前面的越小越好。 思路:先将整数数组转为字符串数组,然后字符串数组进行排序,最后依次输出字符串数组即可。这里注意的是字符串的比较函数需要重新定义,不是比较a和b,而是比较ab与 ba。如果ab ba,则a > b;如果ab = ba,则a = b。比较函数的定义是本解决方案的关键。这道题其实就是希望我们能找到一个排序规则,根据这个规则排出来的数组能排成一个最小的数字。证明:为什么这样 阅读全文

二分检索(查找)的各种变种

2013-08-29 16:35 by youxin, 1169 阅读, 收藏, 编辑
摘要: 其实,二分法真的不那么简单,尤其是二分法的各个变种。 最最简单的二分法,就是从一个排好序的数组之查找一个key值。 如下面的程序:int search(int *arr, int n, int key){ int left = 0, right = n-1; while(left key) right = mid - 1; else left = mid + 1; } return -1;}这个程序,相信只要是一个合格的程序员应该都会写。 稍微注意一点, 每次移动left和right指针的时候,需要在mid的基础上+1或者-1, 防止出现死循环, 程序也就... 阅读全文

排序算法稳定性

2013-08-29 16:01 by youxin, 1005 阅读, 收藏, 编辑
摘要: 假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,ri=rj,且ri在rj之前,而在排序后的序列中,ri仍在rj之前,则称这种排序算法是稳定的;否则称为不稳定的。编辑本段判断方法对于不稳定的排序算法,只要举出一个实例,即可说明它的不稳定性;而对于稳定的排序算法,必须对算法进行分析从而得到稳定的特性。需要注意的是,排序算法是否为稳定的是由具体算法决定的,不稳定的算法在某种条件下可以变为稳定的算法,而稳定的算法在某种条件下也可以变为不稳定的算法。例如,对于如下起泡排序算法,原本是稳定的排序算法,如果将记录交换的条件改成r[j]>= 阅读全文

冒泡排序和直接选择排序详解

2013-08-21 15:17 by youxin, 893 阅读, 收藏, 编辑
摘要: 假设 一个大小为n的数组,元素为a[0],a[1],.........a[n-1]。要排成单调递增。常用的就是冒泡排序和直接选择排序。冒泡排序基本思想: 首先要进行n-1轮冒泡,每次冒泡时把2个元素交换,把最大的放在底部,等冒泡完成了,最后的一个是最大的。void bubbleSort (int a[],int n){ for(int i=0;ia[j+1]) { int tmp=a[j];a[j]=a[j+1];a[j+1]=tmp; } } }}输入:59 8 5 1 4输出:我在:n-1轮循... 阅读全文

梳排序(Comb sort)

2013-08-19 19:46 by youxin, 914 阅读, 收藏, 编辑
摘要: CombSort,梳排序或者梳子排序,就像梳子那样有间隔地比较两个数,很形象,O(n*logn)时间复杂度,O(1)空间复杂度,属于不稳定的排序算法。算法的思想是使逆序的元素尽可能快地移动到最终的位置,而不是像冒泡排序那样每次交换只移动一个位置。http://blog.csdn.net/yui/article/details/5957264http://baike.baidu.com/view/4560283.htm 阅读全文

地精排序(Gnome Sort) 算法

2013-08-19 19:41 by youxin, 2356 阅读, 收藏, 编辑
摘要: gnome应该是最简单排序的排序算法吧!GnomeSort,这是该算法的作者命名的,O(n*n)时间复杂度,O(1)空间复杂度,属于稳定的排序算法。算法的思想是每趟循环找到第一个逆序的元素,把它和在它前面的已排序的元素逐个进行比较、交换,有点像插入排序。void gnomeSort(int a[],int len){ int i=1; while(i<len) { if(a[i-1]<=a[i]) { i++; } else { int tmp=a[i-1];a[... 阅读全文

堆和堆排序(堆实现优先级队列)

2012-07-26 20:50 by youxin, 658 阅读, 收藏, 编辑
摘要: 堆是一种特殊类型的二叉树,它具有2个性质:1.每个节点的值大于等于其每个子节点的值2该树完全平衡,最后一层的叶子都处于最左侧的位置。n个元素称为对,当且仅当它的关键字序列k1,k2,.....kn满足ki#includeusing namespace std;//元素上移操作/*数组h[]及被上移的元素下标i输出,维持堆的性质的数组h[]*/templatevoid sift_up(T h[],int i){ if(i!=1) { while(i!=1) { if(h[i]>h[i/2]) { ... 阅读全文

基于递归的插入排序

2012-03-09 12:54 by youxin, 3438 阅读, 收藏, 编辑
摘要: 插入排序类似玩扑克牌,每次把抽到的牌插入到已排好序的牌中,使之大小有序。直接插入排序(Insertion Sort)的基本思想是:每次将一个待排序的记录,按其关键字大小插入到前面已经排好序的子序列中的适当位置,直到全部记录插入完成为止。设数组为a[0…n-1]。1. 初始时,a[0]自成1个有序区,... 阅读全文