标签:i++ 过程 操作 ble 除了 数列 另一个 int pre
生活中处处存在排序,考试成绩要排序,年龄大小要排序,图书馆的藏书也要排序。排序也是数据结构课程的一个重要组成部分。教材中的出现的排序有名次排序、选择排序冒泡排序等,下面我们一一进行介绍。
所谓排序,也就是给排列的内容一个“排名”,也就是“第几”的“几”。比如,第三个,也就是前面有两个,“小于等于第三名”的有3个。名次排序的原理就来源于此:
参考代码:
template <class T>
void Rank(T a[], int n, int r[])
{ //计算元素的排名
for (int i = 0; i < n; i++) r[i] = 0; //初始化
//逐对比较所有的元素。任两个都做比较,次数为(n-1)n/2
for (int i = 1; i < n; i++)
for ( int j = 0; j < i; j++)
if (a [j] <= a[i]) r[i]++;
else r[j]++;
}
template <class T>
void Rearrange (T a[], int n, int r[])
{ //按序重排数组a中的元素,使用附加数组u,数组r即为“排名”数组
T *u = new T[n+1];
//在u中按排名排列
for (int i = 0; i < n; i++)
u[r[i]] = a[i];
//把u中的元素移回到a中
for (int i = 0; i < n; i++)
a[i] = u[i] ;
delete [ ]u;
}
算法性能分析:
在计算排名的Rank函数中,比较次数为${\frac{(n-1)n}{2}}$,Rearrange函数中移动次数为${2n}$,该排序算法的时间复杂度为O(${n^2}$)。
{
对于给定的n个元素的数组:
参考代码:
template<class T>
int Max(T a[], int n)
{// 确定a [0 : n-1]中的最大元素
int pos = 0;
for (int i = 1; i < n; i++)
if (a[pos] < a[i])
pos = i;
return pos;
}
template <class T>
void selectionSort (T a[], int n)
{
for ( int size = n; size>1; size- -) { //作比较并交换
int j= Max(a, size);//size-1次比较
Swap(a[j],a[size-1] ); //移动3次
}
}
算法性能分析:
每次调用Max函数需要执行size-1次比较,总比较次数为${\frac{(n-1)n}{2}}$,移动次数为${3(n-1)}$。时间复杂度O(${n^2}$)。
冒泡排序是一种简单的排序算法。它重复地走访要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。
template <class T>
void bubbleSort (T a[], int n)
{
for (int i =n; i>1; i--) {
for (int j = 0; j < n-1; j++) {
if (a[j] > a[j + 1])
swap(a[j], a[j + 1]);
}
}
}
算法性能分析:
该算法时间复杂度是${O(n^2)}$。
插入排序是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。在从后向前扫描过程中,反复把已排序元素逐步向后挪位,为最新元素提供插入空间。举个形象的例子:打扑克牌摸牌的时候按牌的大小整理牌。
步骤:
template<class T>
void insertionSort(T a[], int n)
{
for (int i=1; i < n; i++) {
//将a[i]插入a [0 : i-1]
T t=a[i];
int j;
for (j=i-1; j >= 0 && t<a[j]; j--)
a[j+1]=a[j];//向后移位,空出位置来插入
a[j+1]=t;
}
}
算法性能分析:
该算法时间复杂度是${O(n^2)}$。
箱子排序是指利用链表这种数据结构所设计的一种排序算法。这种排序首先把元素相同的节点放在同一个箱子里,然后通过把箱子链接起来就可以创建一个有序的链表。
箱子的理解和实现:
步骤:
void binSort(Chain<Node>& X,int range)
{//按分数排序
intlen=X.Length(); Node x;
Chain<Node> *bin;
bin=new Chain<Node>[range+1];
//分配到每个箱子中
for(int i=1; i<=len; i++){
X.Delete(1,x); //从X摘取第一个节点
bin[x.score].Insert(0,x);
//向bin的合适位置插入节点
}
//从箱子中收集各元素,
for(int j=range; j>=0; j--)
while(!bin[j].IsEmpty()){
bin[j].Delete(1,x);
X.Insert(0,x);//链成新链表
}
delete[]bin;
}
算法性能分析:
两个for循环中执行的每一次插入和删除操作所需要的时间均为${Θ}$(1),因此第一个for循环的复杂性为${Θ}$(n),其中n为输入链表的长度。第二个for循环的复杂性为${Θ}$(n+range)。因此函数binSort总的复杂性为${Θ}$(n+range)。
基数排序也是非比较的排序算法。它是一种稳定的排序算法。有两种方法:最高位优先法(MSD)和最低位优先法(LSD)。通常用于对数的排序选择的是最低位优先法,即先对最次位关键字进行排序,再对高一位的关键字进行排序,以此类推。
类似于桶排序,我们需要给待排序记录准备10个桶,因为一个数的任何一位上,其数字大小都位于0~9之间,因此采用10个桶,桶的编号分别为0,1,2,3,4...9,与待排序记录中每个数相应位的数值对应,基数排序也是因此而得名。
步骤:
算法性能分析:
总结:
|排序法|时间复杂度|稳定性|
|--|---|--|
|名次排序|$O(n^2)$|稳定|
|冒泡排序|$O(n^2)$|稳定 |
|选择排序|$O(n^2)$|不稳定|
|插入排序|$O(n^2)$|稳定|
|箱子排序|$Θ$(n+range)|稳定|
|基数排序|$Θ(n)$|稳定|
标签:i++ 过程 操作 ble 除了 数列 另一个 int pre
原文地址:https://www.cnblogs.com/suqingdong/p/11878035.html