- 插入类排序
- 直接插入排序:适用于基本有序(减少比较和移动的次数),数量较小的情况
- 希尔排序:插入排序的基础上引入delta
- 交换类排序
- 冒泡排序:两两交换,注意change标记位的设计
- 快速排序
- 选择类排序
- 简单选择类排序
- 堆排序
void insSort(int r[],int n)
{
int i,j;
for(i = 2;i <= n;i++){
r[0] = r[i];
j = i - 1;
while(r[0] < r[j]){
r[j+1] = r[j];
j--;
}
r[j+1] = r[0];
}
}
void ShellInsert(int r[],int n,int delta)
{
int j;
for(int i = 1 + delta;i <= n;i++){
//从第一个子序列的第二个元素开始
if(r[i] < r[i-delta]){
r[0] = r[i]; //对r[i]的值进行一个备份
//将前面的数字全部进行移动
for(j = i - delta;j > 0&& r[j] > r[0];j -= delta ){
r[j + delta] = r[j];
}
r[j+delta] = r[0];
}
}
for(int i = 1;i <= n;i++)
cout<>x;
while(x){
r[i] = x;
i++;
cin>>x;
}
int n = i - 1;
for(i = 0;i < 3;i++){
cin>>delta[i];
}
ShellSort(r,n,delta,3);
return 0;
}
冒泡排序和快排
-
快排的本质类似于二叉排序树,在排序好的情况下速度最差
//冒泡排序算法,相比之前多了一个change的标记元素 void BubbleSort(int r[],int n) { int temp; bool change = true; for(int i = 1;i <= n-1 && change;i++){ //大循环控制趟数,change减少不必要的循环次数(如已经排序好的数组) change = false; for(int j = 1;j <= n - i;j++){ if(r[j] > r[j+1]){ temp = r[j]; r[j] = r[j+1]; r[j + 1] = temp; change = true; } } } }//单趟次的快速排序 (核心也是冒泡排序,类似于希尔和插入排序的关系,这个是分组版本的冒泡排序) int QKPass(int r[],int low,int high) { //选定一个基准,注意单趟次的基准是保持不变的 int x = r[low]; while(low < high){ while(low < high && r[high] >= x) high--; if(low < high){ //相当于两者交换位置,此时r[high]变为虚位,右侧均比其大,但左侧没有均比其小 r[low] = r[high]; low++; } while(low < high && x > r[low]) low++; if(low < high){ r[high] = r[low]; high--; } } r[low] = x; //返回基准所在位置 return low; } //完整版本的快速排序 void QKSort(int r[],int low,int high,int n) { int pos; if(low < high){ //初次选定一个轴分出左右子表 pos = QKPass(r,low,high); QKSort(r,low,pos - 1,n); QKSort(r,pos+1,high,n); } if(high - low + 1 == n){ for(int i = 1;i <= high;i++) cout<
一个选出每趟的最小一个选出每趟的最大
//简单选择排序算法
void selectSort(int r[],int n)
{
int k;
for(int i = 1;i <= n-1;i++){
//控制趟数,每趟选出本趟次最小的数字来
k = i;
for(int j = i + 1;j <= n;j++){
if(r[j] < r[k])
k = j;
}
if(k != i){
//执行三步交换代码
}
}
}
//除了low以外,low节点(根节点的左右节点均为已经构造好的大根堆)
void Sift(int r[],int low,int high)
{
bool finished = false;
int f = low,i = 2*low;
while(i <= high && !finished){
if(i < high && r[i] < r[i + 1])
i++;
if(r[f] > r[i])
finished = true;
else{
int temp;
temp = r[f];
r[f] = r[i];
r[i] = temp;
//i记录的是Low的较大节点(该节点最后与根节点交换了),此时开始调换以i为根节点的左右子树为大根堆
//(此时I位置的树不一定全部大于左右子树)
f = i;
i = 2*i;
}
}
}
//接受到一个无序数组,并将它调整为一个大根堆函数
void createHeap(int r[],int n)
{
//由完全二叉的性质,n/2的向下取整是第一个非叶子节点,从该节点开始调整,使其具有大根堆性质
//然后自底向上逐渐调整,使其可以成为一个大根堆
for(int i = n/2;i >= 1;i--)
Sift(r,i,n);
}
void HeapSort(int r[],int n)
{
int i;
int temp;
createHeap(r,n);
for(i = 1;i <= n;i++)
cout<= 2;i--){
//每趟以后换顺序
temp = r[1];
r[1] = r[i];
r[i] = temp;
Sift(r,1,i - 1);
for(int j = 1;j <= n;j++)
cout<



