Ⅰ C语言中最常用的排序方法有哪些
选择排序法,冒泡排序法等,书上关于冒泡法有个例子。
Ⅱ 几种常用的排序算法比较
排序,从小大,0坐标的在下面,即排序后小的在下面,大的在上面。
1,冒泡Bubble:从第0个开始,一直往上,与相邻的元素比较,如果下面的大,则交换。
Analysis:
Implementation:
void BubbleSort(int *pData, int iNum)
2,插入Insertion:与打扑克牌时整理牌很想象,假定第一张牌是有序的,从第二张牌开始,拿出这张牌来,往下比较,如果有比这张牌大的,则把它拨到上一个位置,直到找到比手上的这张更小的(或到顶了),
则把手上的这张牌插入到这张更小的牌的后面。
Analysis:
Implementation:
void InsertionSort(int *list, int length)
{
int i, j, temp;
for (i = 1; i < length; i++)
{
temp = list[i];
j = i - 1;
while ((j >= 0) && (list[j] > temp))
{
list[j+1] = list[j];
j--;
}
list[j+1] = temp;
}
}
3,选择Selection:从所有元素中找到最小的放在0号位置,从其它元素(除了0号元素)中再找到最小的,放到1号位置,......。
Analysis:
Implementation:
void SelectionSort(int data[], int count)
{
int i, j, min, temp;
for (i = 0; i < count - 1; i++)
{
/* find the minimum */
min = i;
for (j = i+1; j < count; j++)
{
if (data[j] < data[min])
{
min = j;
}
}
/* swap data[i] and data[min] */
temp = data[i];
data[i] = data[min];
data[min] = temp;
}
}
4,快速Quick:先拿出中间的元素来(值保存到temp里),设置两个索引(index or pointer),一个从0号位置开始往最大位置寻找比temp大的元素;一个从最大号位置开始往最小位置寻找比temp小的元素,找到了或到顶了,则将两个索引所指向的元素
互换,如此一直寻找交换下去,直到两个索引交叉了位置,这个时候,从0号位置到第二个索引的所有元素就都比temp小,从第一个索引到最大位置的所有元素就都比temp大,这样就把所有元素分为了两块,然后采用前面的办法分别排序这两个部分。总的来
说,就是随机找一个元素(通常是中间的元素),然后把小的放在它的左边,大的放右边,对左右两边的数据继续采用同样的办法。只是为了节省空间,上面采用了左右交换的方法来达到目的。
Analysis:
Implementation:
void QuickSort(int *pData, int left, int right)
{
int i, j;
int middle, iTemp;
i = left;
j = right;
middle = pData[(left + right) / 2]; //求中间值
do
{
while ((pData[i] < middle) && (i < right)) //从左扫描大于中值的数
i++;
while ((pData[j] > middle) && (j > left)) //从右扫描小于中值的数
j--;
if (i <= j) //找到了一对值
{
//交换
iTemp = pData[i];
pData[i] = pData[j];
pData[j] = iTemp;
i++;
j--;
}
} while (i <= j); //如果两边扫描的下标交错,就停止(完成一次)
//当左边部分有值(left<j),递归左半边
if(left < j)
QuickSort(pData, left, j);
//当右边部分有值(right>i),递归右半边
if(right > i)
QuickSort(pData, i, right);
}
5,希尔Shell:是对Insertion Sort的一种改进,在Insertion Sort中,从第2个位置开始取出数据,每次都是与前一个(step/gap==1)进行比较。Shell Sort修改为,在开始时采用较大的步长step,
从第step位置开始取数据,每次都与它的前step个位置上的数据进行比较(如果有8个数据,初始step==4,那么pos(4)与pos(0)比较,pos(0)与pos(-4),pos(5)与pos(1),pos(1)与pos(-3),
...... pos(7)与pos(3),pos(3)与pos(-1)),然后逐渐地减小step,直到step==1。step==1时,排序过程与Insertion Sort一样,但因为有前面的排序,这次排序将减少比较和交换的次数。
Shell Sort的时间复杂度与步长step的选择有很大的关系。Shell排序比冒泡排序快5倍,比插入排序大致快2倍。Shell排序比起QuickSort,MergeSort,HeapSort慢很多。但是它相对比较简单,它适合
于数据量在5000以下并且速度并不是特别重要的场合。它对于数据量较小的数列重复排序是非常好的。
Analysis:
Implementation:
template<typename RandomIter, typename Compare>
void ShellSort(RandomIter begin, RandomIter end, Compare cmp)
{
typedef typename std::iterator_traits<RandomIter>::value_type value_type;
typedef typename std::iterator_traits<RandomIter>::difference_type diff_t;
diff_t size = std::distance(begin, end);
diff_t step = size / 2;
while (step >= 1)
{
for (diff_t i = step; i < size; ++i)
{
value_type key = *(begin+i);
diff_t ins = i; // current position
while (ins >= step && cmp(key, *(begin+ins-step)))
{
*(begin+ins) = *(begin+ins-step);
ins -= step;
}
*(begin+ins) = key;
}
if(step == 2)
step = 1;
else
step = static_cast<diff_t>(step / 2.2);
}
}
template<typename RandomIter>
void ShellSort(RandomIter begin, RandomIter end)
{
typedef typename std::iterator_traits<RandomIter>::value_type value_type;
ShellSort(begin, end, std::less<value_type>());
}
6,归并Merge:先将所有数据分割成单个的元素,这个时候单个元素都是有序的,然后前后相邻的两个两两有序地合并,合并后的这两个数据再与后面的两个合并后的数据再次合并,充分前面的过程直到所有的数据都合并到一块。
通常在合并的时候需要分配新的内存。
Analysis:
Implementation:
void Merge(int array[], int low, int mid, int high)
{
int k;
int *temp = (int *) malloc((high-low+1) * sizeof(int)); //申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
int begin1 = low;
int end1 = mid;
int begin2 = mid + 1;
int end2 = high;
for (k = 0; begin1 <= end1 && begin2 <= end2; ++k) //比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
{
if(array[begin1]<=array[begin2])
{
temp[k] = array[begin1++];
}
else
{
temp[k] = array[begin2++];
}
}
if(begin1 <= end1) //若第一个序列有剩余,直接拷贝出来粘到合并序列尾
{
memcpy(temp+k, array+begin1, (end1-begin1+1)*sizeof(int));
}
if(begin2 <= end2) //若第二个序列有剩余,直接拷贝出来粘到合并序列尾
{
memcpy(temp+k, array+begin2, (end2-begin2+1)*sizeof(int));
}
memcpy(array+low, temp, (high-low+1)*sizeof(int));//将排序好的序列拷贝回数组中
free(temp);
}
void MergeSort(int array[], unsigned int first, unsigned int last)
{
int mid = 0;
if (first < last)
{
mid = (first+last)/2;
MergeSort(array, first, mid);
MergeSort(array, mid+1,last);
Merge(array,first,mid,last);
}
}
Ⅲ Excel表格中常用的排序方法有哪些
制作Excel表格的过程中,对其中的内容进行排序是大家经常会遇到的情况,下面小编介绍几种最为常用但是很多人却不知道的排序方法。
01
首先就是按照笔划来排序,我们经常会看到课本或者花名册上都有按照姓氏笔画来排序的提示,也就是说按照笔划的多少进行排列的,如何设置这种排序呢?首先我们选中需要排序的那一列,比如下图中的B列;
02
然后依次点击工具栏中的“数据”-“排序”,如图一所示...然后在弹出的排序提醒对话框勾选下方的“以当前选定区域排序”;
03
接下来点击排序对话框右上角的“选项”,然后勾选排序选项对话框最下方的“笔划排序”;
04
点击确定返回到表格以后,我们就会发现这一列的所有文字全部按照首个文字的笔划多少来进行排序了;此外如果有时候不知道应该按照何种规则来排序的话,那么就可以用到下面小编介绍的随机排序方法了,在表格的最后一列输入公式“=RAND()”,见图二...
05
点击回车键以后,该单元格中就会弹出一个随机数字,将其下拉拖动应用到所有列,最终效果如图一所示...然后依次点击“数据”-“升序”或者“降序”,这样表格里面的内容就会随机排序了;
06
最后我们还能按照表格中文字的颜色来排序,比如下图的表格中既有红色文字,也有蓝色文字...
07
依旧按照以上的方法将排序对话框打开,然后勾选排序依旧中的“字体颜色”,并且自定义每种颜色文字的次序,我们以红色文字在顶端,蓝色文字在底端为例做介绍;
08
同样点击对话框中的确定,返回到表格以后,我们就会发现红色的文字内容在表格最顶端,而蓝色的文字则被排序到了最底端,如下图所示...
Ⅳ JAVA中有哪几种常用的排序方法每个排序方法的实现思路是如何的每个方法的思想是什么
一、冒泡排序
已知一组无序数据a[1]、a[2]、……a[n],需将其按升序排列。首先比较 a[1]与a[2]的值,若a[1]大于a[2]则交换两者的值,否则不变。再比较a[2]与a[3]的值,若a[2]大于a[3]则交换两者的值,否则不变。再比较a[3]与a[4],以此类推,最后比较a[n-1]与a[n]的值。这样处理一轮后,a[n]的值一定是这组数据中最大的。再对 a[1]~a[n-1]以相同方法处理一轮,则a[n-1]的值一定是a[1]~a[n-1]中最大的。再对a[1]~a[n-2]以相同方法处理一轮,以此类推。共处理n-1轮后a[1]、a[2]、……a[n]就以升序排列了。
优点:稳定;
缺点:慢,每次只能移动相邻两个数据。
二、选择排序
冒泡排序的改进版。
每一趟从待排序的数据元素中选出最小(或最大)的一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。
选择排序是不稳定的排序方法。
n个记录的文件的直接选择排序可经过n-1趟直接选择排序得到有序结果:
①初始状态:无序区为R[1..n],有序区为空。
②第1趟排序
在无序区R[1..n]中选出关键字最小的记录R[k],将它与无序区的第1个记录R[1]交换,使R[1..1]和R[2..n]分别变为记录个数增加1个的新有序区和记录个数减少1个的新无序区。
……
③第i趟排序
第i趟排序开始时,当前有序区和无序区分别为R[1..i-1]和R(1≤i≤n- 1)。该趟排序从当前无序区中选出关键字最小的记录 R[k],将它与无序区的第1个记录R交换,使R[1..i]和R分别变为记录个数增加1个的新有序区和记录个数减少1个的新无序区。
这样,n个记录的文件的直接选择排序可经过n-1趟直接选择排序得到有序结果。
优点:移动数据的次数已知(n-1次);
缺点:比较次数多。
三、插入排序
已知一组升序排列数据a[1]、a[2]、……a[n],一组无序数据b[1]、 b[2]、……b[m],需将二者合并成一个升序数列。首先比较b[1]与a[1]的值,若b[1]大于a[1],则跳过,比较b[1]与a[2]的值,若b[1]仍然大于a[2],则继续跳过,直到b[1]小于a数组中某一数据a[x],则将a[x]~a[n]分别向后移动一位,将b[1]插入到原来 a[x]的位置这就完成了b[1]的插入。b[2]~b[m]用相同方法插入。(若无数组a,可将b[1]当作n=1的数组a)
优点:稳定,快;
缺点:比较次数不一定,比较次数越少,插入点后的数据移动越多,特别是当数据总量庞大的时候,但用链表可以解决这个问题。
三、缩小增量排序
由希尔在1959年提出,又称希尔排序(shell排序)。
已知一组无序数据a[1]、a[2]、……a[n],需将其按升序排列。发现当n不大时,插入排序的效果很好。首先取一增量d(d<n),将a[1]、a[1+d]、a[1+2d]……列为第一组,a[2]、a[2+d]、 a[2+2d]……列为第二组……,a[d]、a[2d]、a[3d]……列为最后一组以次类推,在各组内用插入排序,然后取d'<d,重复上述操作,直到d=1。
优点:快,数据移动少;
缺点:不稳定,d的取值是多少,应取多少个不同的值,都无法确切知道,只能凭经验来取。
四、快速排序
快速排序是目前已知的最快的排序方法。
已知一组无序数据a[1]、a[2]、……a[n],需将其按升序排列。首先任取数据 a[x]作为基准。比较a[x]与其它数据并排序,使a[x]排在数据的第k位,并且使a[1]~a[k-1]中的每一个数据<a[x],a[k+1]~a[n]中的每一个数据>a[x],然后采用分治的策略分别对a[1]~a[k-1]和a[k+1]~a[n] 两组数据进行快速排序。
优点:极快,数据移动少;
缺点:不稳定。
五、箱排序
已知一组无序正整数数据a[1]、a[2]、……a[n],需将其按升序排列。首先定义一个数组x[m],且m>=a[1]、a[2]、……a[n],接着循环n次,每次x[a]++.
优点:快,效率达到O(1)
缺点:数据范围必须为正整数并且比较小
六、归并排序
归并排序是多次将两个或两个以上的有序表合并成一个新的有序表。最简单的归并是直接将两个有序的子表合并成一个有序的表。
归并排序是稳定的排序.即相等的元素的顺序不会改变.如输入记录 1(1) 3(2) 2(3) 2(4) 5(5) (括号中是记录的关键字)时输出的 1(1) 2(3) 2(4) 3(2) 5(5) 中的2 和 2 是按输入的顺序.这对要排序数据包含多个信息而要按其中的某一个信息排序,要求其它信息尽量按输入的顺序排列时很重要.这也是它比快速排序优势的地方.
Ⅳ 几种排序方法
这两天复习了一下排序方面的知识,现将目前比较常见的整理一下。 选择排序选择排序的思想是首先先找到序列中最大元素并将它与序列中最后一个元素交换,然后找下一个最大元素并与倒数第二个元素交换,依次类推。此排序很简单,这不做多说,代码实现如下:View Code插入排序算法流程:1. 从第一个元素开始,该元素可以认为已经被排序 2. 取出下一个元素,在已经排序的元素序列中从后向前扫描 3. 如果该元素(已排序)大于新元素,将该元素移到下一位置 4. 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置 5. 将新元素插入到下一位置中 6. 重复步骤2View Code冒泡排序依次比较相邻的两个数,将小数放在前面,大数放在后面。即在第一趟:首先比较第1个和第2个数,将小数放前,大数放后。然后比较第2个数和第3个数,将小数放前,大数放后,如此继续,直至比较最后两个数,将小数放前,大数放后。至此第一趟结束,将最大的数放到了最后。在第二趟:仍从第一对数开始比较(因为可能由于第2个数和第3个数的交换,使得第1个数不再小于第2个数),将小数放前,大数放后,一直比较到倒数第二个数(倒数第一的位置上已经是最大的),第二趟结束,在倒数第二的位置上得到一个新的最大数(其实在整个数列中是第二大的数)。如此下去,重复以上过程,直至最终完成排序。 View Code合并排序在介绍合并排序之前,首先介绍下递归设计的技术,称为分治法。分治法的核心思想是:当问题比较小时,直接解决。当问题比较大时,将问题分为两个较小的子问题,每个子问题约为原来的一半。使用递归调用解决每个子问题。递归调用结束后,常常需要额外的处理,将较小的问题的结果合并,得到较大的问题的答案。 合并排序算法在接近数组中间的位置划分数组,然后使用递归运算对两个一半元素构成的数组进行排序,最后将两个子数组进行合并,形成一个新的已排好序的数组。 代码如下:View Code快速排序快速排序与合并排序有着很多相似性。将要排序的数组分成两个子数组,通过两次递归调用分别对两个数组进行排序,再将已经排好序的两个数组合并成一个独立的有序数组。但是,将数组一分为二的做法比合并排序中使用的简单方法复杂的多。它需要将所有小于或者等于基准元素的元素放置到基准元素前面的位置,将大于基准的元素放置到基准后面的位置。 View Code堆排序View Code大概常用的几种排序就这几种,希望大家多多指正。
Ⅵ JAVA中有哪几种常用的排序方法
1、冒泡排序
冒泡排序是一个比较简单的排序方法。在待排序的数列基本有序的情况下排序速度较快。若要排序的数有n个,则需要n-1轮排序,第j轮排序中,从第一个数开始,相邻两数比较,若不符合所要求的顺序,则交换两者的位置;直到第n+1-j个数为止,第一个数与第二个数比较,第二个数与第三个数比较,......,第n-j个与第n+1-j个比较,共比较n-1次。此时第n+1-j个位置上的数已经按要求排好,所以不参加以后的比较和交换操作。例如:第一轮排序:第一个数与第二个数进行比较,若不符合要求的顺序,则交换两者的位置,否则继续进行二个数与第三个数比较......。直到完成第n-1个数与第n个数的比较。此时第n个位置上的数已经按要求排好,它不参与以后的比较和交换操作;第二轮排序:第一个数与第二个数进行比较,......直到完成第n-2个数与第n-1个数的比较;......第n-1轮排序:第一个数与第二个数进行比较,若符合所要求的顺序,则结束冒泡法排序;若不符合要求的顺序,则交换两者的位置,然后结束冒泡法排序。
共n-1轮排序处理,第j轮进行n-j次比较和至多n-j次交换。
从以上排序过程可以看出,较大的数像气泡一样向上冒,而较小的数往下沉,故称冒泡法。
2、选择排序
选择法的原理是先将第一个数与后面的每一个数依次比较,不断将将小的赋给第一个数,从而找出最小的,然后第二个数与后面的每一个数依次比较,从而找出第二小的,然后第三个数与后面的
3、插入排序
插入排序的原理是对数组中的第i个元素,认为它前面的i-1个已经排序好,然后将它插入到前面的i-1个元素中。插入排序对少量元素的排序较为有效.
4、快速排序
快速排序是对冒泡排序的一种改进。它的基本思想是:通过一次排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按次方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此大道整个数据变成有序序列。
Ⅶ 重温数据结构写的几种常用排序方法,给新手参考
#include <stdio.h> #include <stdlib.h> #include <assert.h> #include <malloc.h> #include <memory.h> #include <time.h>void print(int a[], int n) { int i =1; while(i<=n) { printf("%d,", a[i]); i++; } printf("\n"); return; } //直接插入排序,时间复杂度O(n^2),空间复杂度O(1),稳定排序 //a[0]不参与排序,实际排序空间为a[1]~a[n]void InsertSort(int a[], int n) { for(int i=2; i<=n; i++) { if(a[i]<a[i-1]) { a[0] = a[i]; int j = i -1; //扫描有序空间,while(a[0]<a[j]) { a[j+1] = a[j]; j--; } a[j+1] = a[0]; } } printf("InsertSort : "); print(a, n); return; } //一次Shell排序过程void ShellPass(int a[], int n, int increment) { for(int i=increment+1; i<=n; i++) { if(a[i]<a[i-increment]) { a[0] = a[i]; int j=i-increment; while(j>0&& a[0]<a[j]) { a[j+increment] = a[j]; j -= increment; } a[j+increment] = a[0]; } } return; } //Shell排序,时间复杂度依赖于增量序列,应避免互为倍数的增量序列, //目前较好时间复杂度为n^1.25~1.6n^1.25,空间复杂度为O(1),不稳定排序void ShellSort(int a[], int n) { int increment =20; do { increment = increment/3+1; ShellPass(a, n, increment); }while(increment>1); printf("ShellSort : "); print(a, n); return; } //冒泡排序,时间复杂度O(n^2),空间复杂度O(1),稳定排序void BubbleSort(int a[], int n) { for(int i=1; i<n; ) { int lastExchangePos = n;//记录一次排序中最后一次交换的位置,此位置之前的所有数据都已有序for(int j=n-1; j>=i; j--) { if(a[j+1]<a[j]) { a[0] = a[j+1]; a[j+1] = a[j]; a[j] = a[0]; lastExchangePos = j+1; } } i = lastExchangePos; } printf("BubbleSort : "); print(a, n); return; } ////快速排序,平均时间复杂度为O(nlgn),空间复杂度为O(lgn)~O(n),快速排序不稳定。//C++中快速排序的实现,void QuickSort(int a[], int low, int high) { srand(time(0)); a[0] = a[rand()%(high-low+1)+low];//随机选择基准,改善快排的性能int tmp =0; int i = low, j = high; while(i<=j) { while(i<high && a[i]<a[0]) i++; while(j>low && a[j]>a[0]) j--; if(i<=j) { tmp = a[i]; a[i] = a[j]; a[j] = tmp; i++; j--; } } if(j>low) QuickSort(a, low, j); if(i<high) QuickSort(a, i, high); return; } //快速排序的一次划分int Partition(int a[], int low, int high) { srand(time(0)); int pos = rand()%(high-low+1)+low; a[0] = a[pos]; a[pos] = a[low]; while(low<high) { while(low<high && a[0]<a[high]) high--; if(low<high) a[low++] = a[high]; while(low<high && a[0]>a[low]) low++; if(low<high) a[high--] = a[low]; } a[low] = a[0]; return low; } //数据结构中标准的快速排序算法void QSort(int a[], int low, int high) { if(low<high) { int p = Partition(a, low, high); QSort(a, low, p-1); QSort(a, p+1, high); } return; } //直接选择排序,时间复杂度为O(n^2),空间复杂度为O(1),不稳定排序void SelectSort(int a[], int n) { for(int i=1; i<=n; i++) { int min = i; for(int j=i+1; j<=n; j++) { if(a[j]<a[min]) min = j; } if(min!=i) { a[0] = a[i]; a[i] = a[min]; a[min] = a[0]; } } printf("SelectSort : "); print(a, n); return; } //调整堆void Heapify(int a[], int s, int to) { /* //Heapify方法的递归算法 a[0] = a[s]; int tmp = 2*s; if(tmp+1<=to && a[tmp]<a[tmp+1])tmp++; if(tmp<=to && a[0]<a[tmp]) { a[s] = a[tmp]; a[tmp] = a[0]; Heapify(a, tmp, to); }*///Heapify方法的递推算法 a[0] = a[s]; for(int j=2*s; j<=to; j*=2) { if(j+1<=to && a[j]<a[j+1])j++; if(j<=to && a[0]>=a[j]) break; a[s] = a[j]; // a[j] = a[0]; s = j; } a[s] = a[0]; return; } //堆排序,最坏时间复杂度nlgn,空间复杂度为O(1),不稳定排序,适合大量数据的排序void HeapSort(int a[], int n) { for(int j=n/2; j>0; j--) Heapify(a, j, n); for(int j=n; j>1; j--) { a[0] = a[j]; a[j] = a[1]; a[1] = a[0]; Heapify(a, 1, j-1); } printf("HeapSort : "); print(a, n); return; } //归并排序的一次合并过程void MergePass(int a[], int low, int mid, int high) { int*p = (int*)malloc(sizeof(int)*(high-low+1)); assert(p!=NULL); int*pi = p; int i = low, j = mid+1; while(i<=mid && j<=high) *(pi++) = (a[i]<=a[j])? a[i++] : a[j++]; while(i<=mid) *(pi++) = a[i++]; while(j<=high) *(pi++) = a[j++]; pi = p; while(low<=high) a[low++] =*(pi++); free(p); return; } //归并排序,时间复杂度O(nlgn),空间复杂度O(n),稳定排序void MergeSort(int a[], int low, int high) { if(low<high) { int mid = (low+high)/2; MergeSort(a, low, mid); MergeSort(a, mid+1, high); MergePass(a, low, mid, high); } return; } int main() { //source[0]不参与排序,做为辅助空间使用int source[] = {0, 10, 8, 30, 55, 6, 0, 99, 87, -5, 32, 66, 54, 33, 21, 32, 96, 121, 70}; int n =sizeof(source)/sizeof(source[0])-1; int a[sizeof(source)/sizeof(source[0])]; memcpy(a, source, sizeof(source)); InsertSort(a, n); memcpy(a, source, sizeof(source)); ShellSort(a, n); memcpy(a, source, sizeof(source)); BubbleSort(a, n); memcpy(a, source, sizeof(source)); QuickSort(a, 1, n); printf("QuickSort : "); print(a, n); memcpy(a, source, sizeof(source)); QSort(a, 1, n); printf("QSort : "); print(a, n); memcpy(a, source, sizeof(source)); SelectSort(a, n); memcpy(a, source, sizeof(source)); HeapSort(a, n); memcpy(a, source, sizeof(source)); MergeSort(a, 1, n); printf("MergeSort : "); print(a, n); return0; }
Ⅷ Excel表常用排序技巧
按图示操作:
假设 需要看A列再看B,C,D
那操作就是先点D列任一单元格,点击a->z,(ak Z->A),再选中C列任一单元格,点击a->Z....类推直至A列,这是其中一种方法
Ⅸ 常用排序方法的应用
排序简介
排序是数据处理中经常使用的一种重要运算,在计算机及其应用系统中,花费在排序上的时间在系统运行时间中占有很大比重;并且排序本身对推动算法分析的发展也起很大作用。目前已有上百种排序方法,但尚未有一个最理想的尽如人意的方法,本章介绍常用的如下排序方法,并对它们进行分析和比较。
1、插入排序(直接插入排序、折半插入排序、希尔排序);
2、交换排序(起泡排序、快速排序);
3、选择排序(直接选择排序、堆排序);
4、归并排序;
5、基数排序;
学习重点
1、掌握排序的基本概念和各种排序方法的特点,并能加以灵活应用;
2、掌握插入排序(直接插入排序、折半插入排序、希尔排序)、交换排序(起泡排序、快速排序)、选择排序(直接选择排序、堆排序)、二路归并排序的方法及其性能分析方法;
3、了解基数排序方法及其性能分析方法。
排序(sort)或分类
所谓排序,就是要整理文件中的记录,使之按关键字递增(或递减)次序排列起来。其确切定义如下:
输入:n个记录R1,R2,…,Rn,其相应的关键字分别为K1,K2,…,Kn。
输出:Ril,Ri2,…,Rin,使得Ki1≤Ki2≤…≤Kin。(或Ki1≥Ki2≥…≥Kin)。
1.被排序对象--文件
被排序的对象--文件由一组记录组成。
记录则由若干个数据项(或域)组成。其中有一项可用来标识一个记录,称为关键字项。该数据项的值称为关键字(Key)。
注意:
在不易产生混淆时,将关键字项简称为关键字。
2.排序运算的依据--关键字
用来作排序运算依据的关键字,可以是数字类型,也可以是字符类型。
关键字的选取应根据问题的要求而定。
【例】在高考成绩统计中将每个考生作为一个记录。每条记录包含准考证号、姓名、各科的分数和总分数等项内容。若要惟一地标识一个考生的记录,则必须用"准考证号"作为关键字。若要按照考生的总分数排名次,则需用"总分数"作为关键字。
排序的稳定性
当待排序记录的关键字均不相同时,排序结果是惟一的,否则排序结果不唯一。
在待排序的文件中,若存在多个关键字相同的记录,经过排序后这些具有相同关键字的记录之间的相对次序保持不变,该排序方法是稳定的;若具有相同关键字的记录之间的相对次序发生变化,则称这种排序方法是不稳定的。
注意:
排序算法的稳定性是针对所有输入实例而言的。即在所有可能的输入实例中,只要有一个实例使得算法不满足稳定性要求,则该排序算法就是不稳定的。
排序方法的分类
1.按是否涉及数据的内、外存交换分
在排序过程中,若整个文件都是放在内存中处理,排序时不涉及数据的内、外存交换,则称之为内部排序(简称内排序);反之,若排序过程中要进行数据的内、外存交换,则称之为外部排序。
注意:
① 内排序适用于记录个数不很多的小文件
② 外排序则适用于记录个数太多,不能一次将其全部记录放人内存的大文件。
2.按策略划分内部排序方法
可以分为五类:插入排序、选择排序、交换排序、归并排序和分配排序。
排序算法分析
1.排序算法的基本操作
大多数排序算法都有两个基本的操作:
(1) 比较两个关键字的大小;
(2) 改变指向记录的指针或移动记录本身。
注意:
第(2)种基本操作的实现依赖于待排序记录的存储方式。
2.待排文件的常用存储方式
(1) 以顺序表(或直接用向量)作为存储结构
排序过程:对记录本身进行物理重排(即通过关键字之间的比较判定,将记录移到合适的位置)
(2) 以链表作为存储结构
排序过程:无须移动记录,仅需修改指针。通常将这类排序称为链表(或链式)排序;
(3) 用顺序的方式存储待排序的记录,但同时建立一个辅助表(如包括关键字和指向记录位置的指针组成的索引表)
排序过程:只需对辅助表的表目进行物理重排(即只移动辅助表的表目,而不移动记录本身)。适用于难于在链表上实现,仍需避免排序过程中移动记录的排序方法。
3.排序算法性能评价
(1) 评价排序算法好坏的标准
评价排序算法好坏的标准主要有两条:
① 执行时间和所需的辅助空间
② 算法本身的复杂程度
(2) 排序算法的空间复杂度
若排序算法所需的辅助空间并不依赖于问题的规模n,即辅助空间是O(1),则称之为就地排序(In-PlaceSou)。
非就地排序一般要求的辅助空间为O(n)。
(3) 排序算法的时间开销
大多数排序算法的时间开销主要是关键字之间的比较和记录的移动。有的排序算法其执行时间不仅依赖于问题的规模,还取决于输入实例中数据的状态。
Ⅹ 数据结构中常见的排序方式都有哪些比如冒泡排序,快速排序等。每种排序具体是怎么排的
1.直接插入:就是有一个已经排好的子序列,它是有序的。然后来一个插入一个仍是这个序列有序。比如a1本身就是有序的。a2来了,要和a1比较,a2大就插在a1之后,小就在a1之前,那么a1、a2就是新的有序子序列,然后a3来了,又要插入进来,逐个与a2、a1比较插在它的适当位置再次形成子序列,就按这样一步步进行,知道最后一个插入时,以前的都已经有序了。
2.希尔排序:由于有时候数据量大,用直接插入就不太合适。于是把你的一组待排序数据按如8、4、2、1的一组增量数来分组,即第一次,a1和a9和a17甚至还有更多间隔为八的数分为一组进行直接插入排序,第二次则是新的a1和a5、a9、a13……依次知道最后比较数据之间的间隔数为1,每次都进行插入排序
3.直接选择:n个数逐个比较,谁大的谁放最后(n的位置),比较范围减一;然后又从n-1个数中找最大的,又放最后(n-1的位置),依次这样进行就可以。
4.冒泡:比较的时候如果前者比后者大就要进行值的交换。那么最大的每次都会沉到底下。比较范围减一。
5、快速排序:要采用分划控制。比较复杂。