Chp11: Sorting and Searching
Common Sorting Algo:

Bubble Sort: Runime: O(n2) average and worst case. Memory: O(1).
void BubbleSortArray(){
for(int i=1;i<n;i++)
for(int j=0;i<n-i;j++)
if(a[j]>a[j+1]){//比较交换相邻元素
int temp;
temp=a[j]; a[j]=a[j+1]; a[j+1]=temp;
}
}
Selection Sort: Runtime: O(n2) average and worst case. Memory: O(1).
void SelectSortArray(){
int min_index;
for(int i=0;i<n-1;i++){
min_index=i;
for(int j=i+1;j<n;j++)//每次扫描选择最小项
if(arr[j]<arr[min_index]) min_index=j;
if(min_index!=i){//找到最小项交换,即将这一项移到列表中的正确位置
int temp;
temp=arr[i]; arr[i]=arr[min_index]; arr[min_index]=temp;
}
}
}
Merge Sort: Runtime: O(nlogn) average and worst case. Memory: Depends.
void mergeSort(int[] array, int low,int high){
if(low < high){
int middle = (low + high) / 2;
mergeSort(array, low, middle);
mergeSort(array, middle + 1, high);
merge(array, low, middle, high);
}
}
void merge(int[] array, int low, int middle, int high){
int[] helper = new int[array.length];
for(int i = low; i <= high; i ++)
helper[i] = array[i];
int helperLeft = low;
int helperRight = middle + 1;
int current = low;
while(helperLeft <= middle && helperRight <= high){
if(helper[helperLeft] <= helper[helperRight])
array[current ++] = helper[helperLeft ++];
else
array[current ++] = helper[helperRight ++];
}
int remaining = middle - helperLeft;
for(int i = 0; i <= remaining; i ++)
array[current + i] = helper[helperLeft + i];
}
Quick Sort: Runtime: O(nlogn) average, O(n2) worse case. Memory: O(nlogn).
In quick sort, we pick a random element and partition the array, such that all numbers that are less than the partitioning element come before all elements that are greater than it. The partitioning can be performed efficiently through a series of swaps.
void quickSort(int[] arr, int left, int right){
int index = partition(arr, left, right);
if(left < index - 1) quickSort(arr, left, index - 1);
if(right < index - 1) quickSort(arr, index, right);
}
int partition(int[] arr, int left, int right){
int pivot = arr[(left + right) / 2];
while(left <= right){
while(arr[left] < pivot) left ++;
while(arr[right] > pivot) right --;
if(left <= right){
swap(arr, left, right);
left ++;
right --;
}
}
return left;
}
//pro4 : quick sort
public int adjust_array(int[] input,int low,int high){
//set the pivot to be the first element of the array
int pivot = input[low];
int exchange = 0;
while(low < high){
//from the tail to header,find the item smaller than the pivot
while(input[high] >= pivot && high > low)
high --;
exchange = input[high];
input[high] = input[low];
input[low] = exchange;
//from the header to tail,find the item larger than the pivot
while(input[low] <= pivot && high > low)
low ++;
exchange = input[high];
input[high] = input[low];
input[low] = exchange;
}
//set the mid to be pivot
input[low] = pivot; return low;
} public void quick_sort(int[] input, int low, int high){
//set the low and high pointer
if(low < high){
int mid = adjust_array(input,low,high);
quick_sort(input, 0, mid - 1);
quick_sort(input, mid + 1, high);
}
} public void pro4(){
int[] input = {20,1,2,40,7,90,11};
int low = 0;
int high = input.length - 1;
quick_sort(input,low,high);
for(int i = 0; i < input.length; i ++){
System.out.println(input[i]);
}
}
Radix Sort: Runtime: O(kn).
It is a sorting algo for intergers that takes advantage of the fact that integers have a finite number of bits.
Void RadixSort(Node L[],length,maxradix)
{
Int m,n,k,lsp;
k=1;m=1;
Int temp[10][length-1];
Empty(temp); //清空临时空间
While(k<maxradix) //遍历所有关键字
{
For(int i=0;i<length;i++) //分配过程
{
If(L[i]<m)
Temp[0][n]=L[i];
Else
Lsp=(L[i]/m)%10; //确定关键字
Temp[lsp][n]=L[i];
n++;
}
CollectElement(L,Temp); //收集
n=0;
m=m*10;
k++;
}
}
Bucket sort:
Bucket sort, or bin sort, is a sorting algorithm that works by partitioning an array into a number of buckets. Each bucket is then sorted individually, either using a different sorting algorithm, or by recursively applying the bucket sorting algorithm. It is a distribution sort, and is a cousin of radix sort in the most to least significant digit flavour. Bucket sort is a generalization of pigeonhole sort. Since bucket sort is not a comparison sort, the Ω(n log n) lower bound is inapplicable. The computational complexity estimates involve the number of buckets.
Bucket sort works as follows:
- Set up an array of initially empty "buckets."
- Scatter: Go over the original array, putting each object in its bucket.
- Sort each non-empty bucket.
- Gather: Visit the buckets in order and put all elements back into the original array.
Pseudocode
function bucketSort(array, n) is
buckets ← new array of n empty lists
for i = 0 to (length(array)-1) do
insert array[i] into buckets[msbits(array[i], k)]
for i = 0 to n - 1 do
nextSort(buckets[i])
return the concatenation of buckets[0], ...., buckets[n-1]
Here array is the array to be sorted and n is the number of buckets to use. The function msbits(x,k) returns the k most significant bits of x (floor(x/2^(size(x)-k))); different functions can be used to translate the range of elements in array to n buckets, such as translating the letters A–Z to 0–25 or returning the first character (0–255) for sorting strings. The function nextSort is a sorting function; using bucketSort itself as nextSort produces a relative of radix sort; in particular, the case n = 2 corresponds toquicksort (although potentially with poor pivot choices).
Heap Sort: Runtime:O(nlgn) average and worse case.
//堆排序
template
void Sort::HeapSort(T* array, int size)
{
int lastP = size / ;
//从最后一个有孩子的结点开始建初始堆
for(int i = lastP - ; i >= ; i--)
{
HeapAjust(array, i, size);
}
int j = size;
//将堆顶元素和无序区间的最后一个元素交换,再调整堆
while(j > )
{
Swap(array, , j - );
j--;
HeapAjust(array, , j);
}
}
//调整堆
template
void Sort::HeapAjust(T *array, int toAjust, int size)
{
int pos = toAjust;
while((pos * + ) < size)
{
int lChild = pos * + ;
if(array[lChild] > array[pos])
{
pos = lChild;//左孩子大
}
int rChild = lChild + ;
if(rChild < size && array[rChild] > array[pos])
{
pos = rChild;//右孩子更大
}
if(pos != toAjust) //父结点比其中一个孩子小
{
Swap(array, toAjust, pos);
toAjust = pos;
}
else
{
break;
}
}
}
Insertion Sort: Runtime O(n2).
//插入排序
template
void Sort::InsertSort(T* array, int size)
{
for(int i = ; i < size; i++)
{
for(int j = i; j > ; j--)
{
if(array[j] < array[j - ])
{
Swap(array, j, j-);
}
}
}
}
Shell Sort: Runtim: O(nlog2^n) ~ O(n^1.5).
void ShellSortArray()
{
for(int incr=3;incr<0;incr--)//增量递减,以增量3,2,1为例
{
for(int L=0;L<(n-1)/incr;L++)//重复分成的每个子列表
{
for(int i=L+incr;i<n;i+=incr)//对每个子列表应用插入排序
{
int temp=arr[i];
int j=i-incr;
while(j>=0&&arr[j]>temp)
{
arr[j+incr]=arr[j];
j-=incr;
}
arr[j+incr]=temp;
}
}
}
}
总结:
1.O(n^2)性能分析
平均性能为O(n^2)的有:直接插入排序,选择排序,冒泡排序
在数据规模较小时(9W内),直接插入排序,选择排序差不多。当数据较大时,冒泡排序算法的时间代价最高。性能为O(n^2)的算法基本上是相邻元素进行比较,基本上都是稳定的。
2.O(nlogn)性能分析
平均性能为O(nlogn)的有:快速排序,归并排序,希尔排序,堆排序。其中,快排是最好的, 其次是归并和希尔,堆排序在数据量很大时效果明显。
这四种排序可看作为“先进算法”,其中,快排效率最高,但在待排序列基本有序的情况下,会变成冒泡排序,接近O(n^2).
希尔排序对增量的标准没有较为满意的答案,增量对性能会有影响。
归并排序效率非常不错,在数据规模较大的情况下,比希尔排序和堆排序要好。
多数先进的算法都是因为跳跃式的比较,降低了比较次数,但牺牲了排序的稳定性。
3. 插入排序,冒泡排序,二叉树排序,归并排序都是稳定的
选择排序,希尔排序,快速排序,堆排序是不稳定的。
四、排序算法选择
1.数据规模较小
(1)待排序列基本序的情况下,可以选择直接插入排序;
(2)对稳定性不作要求宜用选择排序,对稳定性有要求宜用插入或冒泡
2.数据规模不是很大
(1)完全可以用内存空间,序列杂乱无序,对稳定性没有要求,快速排序,此时要付出log(N)的额外空间。
(2)序列本身可能有序,对稳定性有要求,空间允许下,宜用归并排序
3.海量级别的数据,必须按块放在外存上
(1)对稳定性有求,则可考虑归并排序。
(2)对稳定性没要求,宜用堆排序
4.序列初始基本有序(正序),宜用直接插入,冒泡,随机快排
外部排序
外部排序指的是大文件的排序,面试的时候,面试官喜欢问,给你一个非常非常大的文件(比如1T),一行一个数(或者一个单词),内存最多只有8G,硬盘足够大,CPU很高级……然后要你给这个文件里面的数据排序。你要怎么办?
这其实就要用到外部排序。就是说要借助外存储器进行多次的内/外存数据的交换,因为内存不足以加载所有的数据,所以只能一部分一部分地加载。
所以外部排序的思想就是:分两个独立的阶段。
首先,可按内存的大小,将外存上含n个记录的文件分成若干长度为 x 的子文件或段,依次读入内存,并利用有效的内部排序方法对它们进行排序,并将排序后得到的有序子文件 重新写入外存,通常称这些有序的子文件为归并段或顺串。然后,对这些归并段进行逐趟归并,使归并段逐渐由小到大,直至得到整个有序文件为止。
因此现在的问题就转化为如何归并两个大文件。这个读者朋友们想一下就明白了。就是把这两个文件按内存的大小,一部分一部分从小到大加载出来并,再写回外存。
Questions:
11.1 Given two sorted arrays, A and B, where A has a large enough buffer at the end to hold B.
Merge a and b, starting from the last element in each!
11.2 Write a method to sort an array of strings so that all the anagrams are next to each other.
Implement comparator for this problem:
public class AnagramComparator implements Comparator<String>{
public String sortChars(String s){
char[] content = s.toCharArray();
Arrays.sort(content);
return new String(content);
}
public int compare(String s1, String s2){
return sortChars(s1).compareTo(sortChars(s2));
}
}
public void sort(String[] array){
Hashtable<String, LinkedList<String>> hash = new Hashtable<String, LinkedList<String>>();
for(String s : array){
String key = sortChars(s);
if(!hash.containsKey(key)) hash.put(key, new LinkedList<String>());
LinkedList<String> anagrams = hash.get(key);
anagrams.push(s);
}
int index = 0;
for(String key : hash.keySet()){
LinkedList<String> list = hash.get(key);
for(String t : list){
array[index] = t;
index ++;
}
}
}
The algorithm above is a modification of bucket sort.
11.3 Given a sorted array of n integers that has been rotated an unknown number of times, write code to find an element in the array. the array is sorted in increasing order at begining.
If we look a bit deeper, we can see that one half of the array must be ordered normally(in increasing order).We can therefore look at the normally ordered half to determine whether we should search the left or right half.
public int search(int[] array, int left, int right, int x){
int mid = (left + right) / 2;
if(x == array[mid]) return mid;
if(left < right) return -1;
//either the left or right half must be normally ordered. find out which side is normally ordered, and then use the normally ordered half to figure out which side to search to find x.
if(array[left] < array[mid]){//left half normally ordered
if(x >= array[left] && x <= array[mid]) return search(array, left, mid - 1, x);
else return search(array, mid + 1, right, x);
}else if(array[mid] < array[left]){//right is normally ordered
if(x >= array[mid] && x <= array[right]) return search(array, mid + 1, right, x);
else return search(array, left, mid - 1, x);
}else if(array[left] == array[mid]){// left half is all repeats
if(array[mid] != array[right]) return search(array, mid + 1, right, x);
else{// else we have to search both halves
int result = search(array, left, mid - 1, x);
if(result == -1) return search(array, mid + 1, right, x);
else return result;
}
}
return -1;
}
11.4 Imagine you hace a 20GB file with one string per line. Explain how you would sort the file.
When an interviewer gives a size limit, it should tell you that they don't want you to bring all the data into memory.
So we should only bring part of the data into memory.
We'll divide the file into chunks which are xMB each, where x is the amout of memory we have available. Each chunk is sorted separately and then saved back to the file system.
Once all the chunks are sorted, we then merge the chunks, one by one. At the end, we have a fully sorted file.
11.8 Imagine you are reading in a stream of integers. Periodically, you wish to be able to look up the rank of a number x(the number of values less than or equal to x). Implement the data structures and algorithms to support these operations.
public class Question{
private static RankNode root = null;
public static void track(int number){
if(root == null) root = new RankNode(number);
else root.insert(number);
}
public static int getRankOfNumber(int number){
return root.getRank(number);
}
...
}
public class RankNode{
public int left_size = 0;
public RankNode left, right;
public int data = 0;
public RankNode(int d){
data = d;
}
public void insert(int d){
if(d <= data){
if(left != null) left.insert(d);
else left = new RankNode(d);
left_size ++;
}else{
if(right != null) right.insert(d);
else right = new RankNode(d);
}
}
public int getRank(int d){
if(d == data) return left_size;
else if(d < data){
if(left == null) return -1;
else return left.getRank(d);
}else{
int right_rank = right == null ? -1 : right.getRank(d);
if(right_rank == -1) return -1;
else return left_size + 1 + right_rank;
}
}
}
Chp11: Sorting and Searching的更多相关文章
- Algorithm in Practice - Sorting and Searching
Algorithm in Practice Author: Zhong-Liang Xiang Date: Aug. 1st, 2017 不完整, 部分排序和查询算法, 需添加. Prerequisi ...
- 20162314 Experiment 3 - Sorting and Searching
Experiment report of Besti course:<Program Design & Data Structures> Class: 1623 Student N ...
- CareerCup Chapter 9 Sorting and Searching
9.1 You are given two sorted arrays, A and B, and A has a large enough buffer at the end to hold B. ...
- [Java in NetBeans] Lesson 15. Sorting and Searching.
这个课程的参考视频和图片来自youtube. 主要学到的知识点有: Build in functions in java.util.Collections Need to implement a co ...
- [转]Paging, Searching and Sorting in ASP.Net MVC 5
本文转自:http://www.c-sharpcorner.com/UploadFile/4b0136/perform-paging-searching-sorting-in-Asp-Net-mvc- ...
- OpenGL的学习资源
OpenGL是3D图形接口工业标准,使用上非常简单,所有API不过上百个函数,但理解OpenGL就没那么简单,本文总结OpenGL的学习资源,包括官方资料.网上教程.示例程序等. Wikipedia: ...
- 用python语言讲解数据结构与算法
写在前面的话:关于数据结构与算法讲解的书籍很多,但是用python语言去实现的不是很多,最近有幸看到一本这样的书籍,由Brad Miller and David Ranum编写的<Problem ...
- CareerCup All in One 题目汇总 (未完待续...)
Chapter 1. Arrays and Strings 1.1 Unique Characters of a String 1.2 Reverse String 1.3 Permutation S ...
- [0x00 用Python讲解数据结构与算法] 概览
自从工作后就没什么时间更新博客了,最近抽空学了点Python,觉得Python真的是很强大呀.想来在大学中没有学好数据结构和算法,自己的意志力一直不够坚定,这次想好好看一本书,认真把基本的数据结构和算 ...
随机推荐
- 利用CSS3打造一组质感细腻丝滑的按钮
CSS3引入了众多供功能强大的新特性,让设计和开发人员能够轻松的创作出各种精美的界面效果.下面这些发出闪亮光泽的按钮,漂亮吧?把鼠标悬停在按钮上,还有动感的光泽移动效果. 温馨提示:为保证最佳的效果, ...
- 6款基于SVG的HTML5应用和动画
1.HTML5 SVG 3D蝴蝶飞舞动画 逼真超酷 这次我们要分享的这款HTML5动画简直就是逆天,利用SVG制作的3D蝴蝶飞舞动画,蝴蝶飞舞动画非常逼真,蝴蝶飞舞的路线是利用SVG构造的.另外,动画 ...
- startup.bat闪退---tomcat环境变量配置中遇到的问题
常用的方法: 1.在已解压的tomcat的bin文件夹下找到startup.bat,右击->编辑.在文件头加入下面两行: SET JAVA_HOME=D:\Java\jdk1.6.0_10 ...
- 【风马一族_Java】使用java,画出任意大小的菱形
public class rhombic { public static void main(String[] args){ /** * scriber()画菱形的方法,参数 9 是指菱形的对角线的长 ...
- ADO.NET笔记——SQL注入攻击
相关知识: 可以通过字符串的拼接来构造一个SQL命令字符串,但是SQL命令字符串的拼接确是造成“SQL注入攻击”的重要原因. 考虑下列例子:从ProductCategory表中检索出Name为“Bik ...
- javascript对象与实例
var person=new Object(); var person2={}; 一切都是对象 person是Object的实例, 也是对象. 第二个person2也是如此,只不过它是采用字面量的方式 ...
- 基础学习总结(四)---内存获取、XML之PULL解析
外部项目引入如果没找到工程文件要先创建一个android项目在引入. 根据要查看的项目名在项目中搜索逐步查看 ==================== 内存详情获取: public class Mai ...
- CSS3 text-rendering属性
这种非标准的属性目前不被推荐.我们一般会找一个可以替代的方法来完成相同的功能,不到外不得已,最好别用. CSS的这个text-rendering属性通常被用在Windows和Linux系统中,用来 ...
- C# 顺序表操作
虽然.NET已经是现实了Reverse(),但是学习算法有必要知道其是怎么实现的: private static void ReverseArray(int[] array) { int temp; ...
- Resource temporarily unavailable
数据库版本:5.5.14 操作系统版本:contos 6.3 服务器256G内存,安装90个实例.通过脚本启动90个mysql数据库实例,会有几个实例无法启动,进程启动后直接被杀死.查看mysql日志 ...