为什么需要外部排序 指的是待排序记录的数量很大,以致内存一次不能容纳全部记录,在排序过程中需要对外存进行访问的排序过程。 定义 外部排序指的是大文件的排序,即待排序的记录存储在外部存储器上,在排序过程中需进行多次的内、外存之间的交换。 怎么实现 首先将打文件记录分成若干个子文件,然后读入内存中,并利用内部排序的方法进行排序;然后把排序好的有序子文件,重新写入外存,再对这些归并段进行逐个归并,直到整个有序文件为止。
指的是待排序记录存放在计算机随机存储器(内存)中进行的排序过程; 下面总结我们常用的内部排序算法:
算法平均时间复杂度空间复杂度最坏情况最好情况稳定性算法插入排序O( n2 n 2 )O(1)O(n)O( n2 n 2 )稳定性算法选择排序O( n2 n 2 )O(1)O( n2 n 2 )O( n2 n 2 )稳定性算法冒泡排序O( n2 n 2 )O(1)O( n2 n 2 )O(n)稳定性算法基数排序O( d(n+rd) d ( n + r d ) )O( rd r d )O( d(n+rd) d ( n + r d ) )稳定性算法归并排序O( nlogn n l o g n )O( n n ) O(nlognnlogn)O( nlogn n l o g n )稳定性算法快速排序O( nlogn n l o g n )O( logn l o g n )-O( n n ) O(n2n2)O( nlogn n l o g n )不稳定算法希尔排序O( nlogn n l o g n )-O( n2 n 2 )O(1)O( n2 n 2 )O(n^1.3)不稳定算法堆排序O( nlogn n l o g n )O(1)O( nlogn n l o g n )O( nlogn n l o g n )不稳定算法稳定性的定义:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,ri=rj,且ri在rj之前,而在排序后的序列中,ri仍在rj之前,则称这种排序算法是稳定的;否则称为不稳定的。
将一个待排序的记录,按照其关键字的大小将其插入到前边已经排好序的子序列的适当的位置,直到全部插入完毕.这就像我们在玩扑克牌时,将每一张拍插入到其他已经有序的牌中适当的位置.在计算及中,为了给要插入的元素腾出位置,需要将其余所有元素在插入位置之前都向右移动一位。 [] 5 7 9 3 1 [5] 7 9 3 1 [5 7] 9 3 1 [5 7 9] 3 1 [3 6 7 9] 1 [1 3 6 7 9]
void insertSort(int *data, int n){ int i, j, k; for(i=1;i<n;i++){ for(j=i-1;j>=0;j--){ if(data[j] > data[i]) break; } if (j!=i-1) { int temp = data[i];//比data[i]大的数据往后移动 for(k=i-1; k>j; k--){ data[k+1] = data[k]; }//将data[i]放在待插入的位置 data[k+1] = temp; } } }刚开始数组为空,i从0开始,对于第i个位置,选择(i+1,n)之间最小值存入。
[] 5 7 9 3 1 [1] 5 7 9 3 [1 3] 5 7 9 [1 3 5] 7 9 [1 3 5 7] 9 [1 3 5 7 9]
void selectSort(int *data, int n){ for(int i=0;i<n;i++){ int min = data[i]; int min_index = i; for(int j=i+1;j<n;j++){ if(data[j]<min){ min = data[j]; min_index = j; } } if(min_index != i){ swap(data, i, min_index); } } }两两相邻进行比较,如果它们的排序与排序要求不符合,则交换两个相邻的值。 [5 7 9 3 1] [5 7 9 3 1] [5 7 3 9 1] [5 3 7 9 1] [3 5 7 9 1] [3 5 7 1 9] [3 5 1 7 9] [1 3 5 7 9]
void bubbleSort(int *data, int n){ for(int i=1;i<n;i++){ for(int j=i-1;j>=0;j--){ if(data[j] > data[j+1]){ swap(data, j,j+1); } } } }选择增量,根据增量来划分数组,然后排序子数组,交换位置,然后再改变增量,再划分子数组,再排序,最后直至增量为1,全排序。 592 401 874 141 348 72 911 887 820 283 增量为5 72 401 874 141 283 592 911 887 820 348 增量为5/2=2 72 141 283 348 820 401 874 592 911 887 增量为1 72 141 283 348 401 592 820 874 887 911
先分组,再排序 2个一组,4个一组,8个一组… 10,8,12,7,5 第一趟:(10,8),(12,7),5->(8,10),(7,12),5 第二趟:(8,10,7,12),5->(7,8,10,12),5 第三趟:5,7,8,10,12
void _mergeSort(vector<int>& nums, int start, int mid, int end){ int index1 = start; int index2 = mid+1; int index = start; vector<int> tmp; while((index1<=mid)&&(index2<=end)){ if(nums[index1]<nums[index2]){ tmp.push_back(nums[index1++]); } else{ tmp.push_back(nums[index2++]); } } while(index1<=mid){ tmp.push_back(nums[index1++]); } while(index2<=end){ tmp.push_back(nums[index2++]); } int count = 0; for(int i=0;i<tmp.size();i++){ nums[start+i] = tmp[i]; } } void mergeSort(vector<int>& nums, int start, int end){ if(start>=end){ return; } int mid = (start+end)>>1; mergeSort(nums, start, mid); mergeSort(nums, mid+1, end); _mergeSort(nums, start, mid, end); }[5 7 9 3 1] key=5, first = 0, last=4 [1 7 0 3 1] data[first]=data[last] [1 7 0 3 7] data[last]=data[first] [1 3 0 3 7] [1 3 0 5 7] [1 3 0] 5 [7] 1. 先选控制值key,这里默认数组的第一个值 2. 然后设置头尾指针, 3. while(头指针<尾指针) 首先从尾指针开始移动,直至遇到比key小的值,就把该值移动到data[first]的位置 然后从头指针开始移动,直至遇到比key大的值,就把该值移动到data[last]的位置 4. 最后将a[first]设置为控制值key
void quickSort(int *data, int low, int high){ if(low>=high) return; int first = low; int last = high; int key = data[first]; while(first < last){ while(first<last && data[last]>=key){ last --; } data[first] = data[last];//将较小的值移到左端 while(first<last && data[first]<=key){ first++; } data[last] = data[first];//将较大的值移到右端 } data[first] = key; quickSort(data, low, first-1); quickSort(data, first+1, high); }步骤 1. 将无需序列构建成一个堆,根据升序降序需求选择大顶堆或小顶堆; 2. 将堆顶元素与末尾元素交换,将最大元素”沉”到数组末端; 3. 重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列有序。
先比较个位,再比较十位
92 35 67 76 84 51 第一趟:51→92→84→35→67→76 第二趟:35→51→67→76→84→92
参考: https://bbs.csdn.net/topics/390360278?page=1 http://blog.csdn.net/guyuealian/article/details/51151674
