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:

  1. Set up an array of initially empty "buckets."
  2. Scatter: Go over the original array, putting each object in its bucket.
  3. Sort each non-empty bucket.
  4. 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的更多相关文章

  1. Algorithm in Practice - Sorting and Searching

    Algorithm in Practice Author: Zhong-Liang Xiang Date: Aug. 1st, 2017 不完整, 部分排序和查询算法, 需添加. Prerequisi ...

  2. 20162314 Experiment 3 - Sorting and Searching

    Experiment report of Besti course:<Program Design & Data Structures> Class: 1623 Student N ...

  3. 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. ...

  4. [Java in NetBeans] Lesson 15. Sorting and Searching.

    这个课程的参考视频和图片来自youtube. 主要学到的知识点有: Build in functions in java.util.Collections Need to implement a co ...

  5. [转]Paging, Searching and Sorting in ASP.Net MVC 5

    本文转自:http://www.c-sharpcorner.com/UploadFile/4b0136/perform-paging-searching-sorting-in-Asp-Net-mvc- ...

  6. OpenGL的学习资源

    OpenGL是3D图形接口工业标准,使用上非常简单,所有API不过上百个函数,但理解OpenGL就没那么简单,本文总结OpenGL的学习资源,包括官方资料.网上教程.示例程序等. Wikipedia: ...

  7. 用python语言讲解数据结构与算法

    写在前面的话:关于数据结构与算法讲解的书籍很多,但是用python语言去实现的不是很多,最近有幸看到一本这样的书籍,由Brad Miller and David Ranum编写的<Problem ...

  8. CareerCup All in One 题目汇总 (未完待续...)

    Chapter 1. Arrays and Strings 1.1 Unique Characters of a String 1.2 Reverse String 1.3 Permutation S ...

  9. [0x00 用Python讲解数据结构与算法] 概览

    自从工作后就没什么时间更新博客了,最近抽空学了点Python,觉得Python真的是很强大呀.想来在大学中没有学好数据结构和算法,自己的意志力一直不够坚定,这次想好好看一本书,认真把基本的数据结构和算 ...

随机推荐

  1. 洛谷 1865 A%B问题

    题目背景 题目名称是吸引你点进来的 实际上该题还是很水的 题目描述 区间质数个数 输入输出格式 输入格式: 一行两个整数 询问次数n,范围m 接下来n行,每行两个整数 l,r 表示区间 输出格式: 对 ...

  2. 模拟n步一维随机游走的情况。

    package randomWalk; import java.util.Random; import java.util.Scanner; public class RandomWalk { pub ...

  3. IntellijIDEA 使用技巧

    1:显示工具栏目  toolbar:view ->ToolBar 2:加载源码   new project ->选择java project ->选择源码所在目录 ->ok

  4. Eclispe使用Maven添加官方库的jar包

    先到百度或google搜索maven仓库,在仓库中搜索需要的jar包,如poi.jar. 搜索到之后找到需要的jar包,找到这里

  5. SequoiaDB 1.5 版本发布

    SequoiaDB 1.5 – 2013.11.13 新特性    1. 新增聚合特性,API实现 GROUPBY, MAX 等功能:    2. 全新改版的Web管理界面:    3. 提供C#语言 ...

  6. 让ImageView可以使用gif的方法

    在自己的包中添加MyGifView.java(直接复制,粘贴),读取gif资源在MyGifView中第20行读取: MyGifView.java: package com.zzw.testgifuse ...

  7. selenium+python find_element_by_css_selector方法使用

    1.通过类class获取 比如如下代码 <h1 class="important"> This heading is very important. </h1&g ...

  8. 一,XAML基础

    RuntimeNameProperty特性:为什么<Grid x:Name="grid1"></Grid>等价于<Grid Name="gr ...

  9. CodeForces 478B 第八次比赛 B题

    Description n participants of the competition were split into m teams in some manner so that each te ...

  10. vim命令总结

    前言 本文翻译自:http://bencrowder.net/files/vim-fu/,参考了VIM中文帮助. Google翻译结果和实际操作结果,对原文的部分内容重新整理,删除和添加了 部分内容并 ...