一些最基本的排序算法:

* 插入排序
* 交换排序
* 选择排序
@ 插入排序:

1-直接插入排序:

* 从前端插入
* 从后端插入
2-希尔(Shell)排序

1-直接插入排序:

* 从前端插入: int arr[]={999,1,2,5,8,4,3,9,7};//"999"是一个容储器(arr[0]是一个监视哨),不参与排序。
void InsertSort(int n) { int i,j; for(i=2;i<=n;i++)//进行n-1次排序 { arr[0]=arr[i];
//设置监视哨---减少扫描量,提高效率。 j=i-1;//j代表有序序列的最后一个元素 while(arr[0]<arr[j]) { arr[j+1]=arr
[j];//记录后移 j--; } arr[j+1]=arr[0];//把存放在arr[0]中的原记录插入到正确位置 } }
* 从后端插入: int arr[]={0,1,2,5,8,4,3,9,7,999};
//"999"是一个容储器(arr[n+1]是一个监视哨),"0"是填补i=0的空白位置,"999"与"0"均不参与排序。 void InsertSort(
int n)//从第n-1个元素开始向它前面插入,直到第一个元素插入为止。 { int i,j; for(i=n-1;i>=1;i--)//进行n-1次排序 {
arr[n+1]=arr[i];//设置监视哨 j=i+1;//j代表有序序列的最后一个元素 while(arr[n+1]>arr[j]) { arr[j-1
]=arr[j];//记录前移 j++; } arr[j-1]=arr[n+1];//把存放在arr[n+1]中的原记录插入到正确位置 } }
2-希尔(Shell)排序==>直接插入排序的改进版
void InsertSort(int n) { int i,j,d; for(d=n/2;d>=1;d=d/2)//进行n-1次排序 { for(i=d+1
;i<=n;i++) { arr[0]=arr[i];//设置监视哨 j=i-d;//前后位置的增量为d,而不是1 while(j>0&&arr[0]<arr[
j]) { arr[j+d]=arr[j];//记录后移,查找插入位置 j=j-d; } arr[j+d]=arr[0];//插入 } } }
------》源代码:
#include<iostream> using namespace std; //1.数组的初始化: int arr[]={999,1,2,5,8,4,3,
9,7};//"999"是一个容储器(arr[0]是一个监视哨),不参与排序。 //2.希尔排序: void InsertSort(int n) { int i
,j,d; for(d=n/2;d>=1;d=d/2)//进行n-1次排序 { for(i=d+1;i<=n;i++) { arr[0]=arr[i];
//设置监视哨 j=i-d;//前后位置的增量为d,而不是1 while(j>0&&arr[0]<arr[j]) { arr[j+d]=arr[j];
//记录后移,查找插入位置 j=j-d; } arr[j+d]=arr[0];//插入 } } } void Show_arr(int n) { int i;
for(i=1;i<=n;i++) cout<<arr[i]<<'\t'; cout<<endl; } void main() { InsertSort(8);
Show_arr(8); }
直接插入排序的算法的时间复杂度为O(n^2),直接插入排序是一种稳定的排序方法。而shell_sort的算法的时间复杂度为O(n* log2^n)~ O(n
^2) 大略为O(n^(3/2)),shell_sort不是一种稳定的排序方法

@交换排序:

* 冒泡排序
* 快速排序
1- 冒泡排序:
void Bubble_Sort(int *a,int n) { int i, j, t; for(i=0;i<n-1;i++) { for(j=0;j<n-
i-1;j++) if(a[j]>a[j+1]) { t=a[j]; a[j]=a[j+1]; a[j+1]=t; } } }
2-快速排序:
void Quick_Sort(int low,int high) { if(low>=high) return ; int i=low,j=high;
//避免引起歧义 arr[0]=arr[low]; while(i<j) { while(i<j&&arr[0]<=arr[j])
//"i<j"绝对不能省,此处与外循环的含义不同 j--; arr[i]=arr[j]; while(i<j&&arr[i]<=arr[0]) i++; arr
[j]=arr[i]; } arr[i]=arr[0]; Quick_Sort(low,i-1); Quick_Sort(i+1,high); }
------》源代码:
#include<iostream> using namespace std; //1.数组的初始化: int arr[]={0,1,2,5,8,4,3,9,
7}; //2.快速排序:一个形象的比喻-》“选取一个中间点,两边互相扔石头” void Quick_Sort(int low,int high) { if(
low>=high) return ; int i=low,j=high;//避免引起歧义 arr[0]=arr[low]; while(i<j) {
while(i<j&&arr[0]<=arr[j])//"i<j"绝对不能省,此处与外循环的含义不同 j--; arr[i]=arr[j]; while(i<j
&&arr[i]<=arr[0]) i++; arr[j]=arr[i]; } arr[i]=arr[0]; Quick_Sort(low,i-1);
//这里采用递归来化简算法的难度 Quick_Sort(i+1,high); } void Show_arr(int n) { int i; for(i=1;i
<=n;i++) cout<<arr[i]<<'\t'; cout<<endl; } void main() { Quick_Sort(1,8);
Show_arr(8); }
冒泡排序的算法的时间复杂度为O(n^2),是一种稳定的排序方法。
快速排序的算法的时间复杂度为O(n* log2^n)~ O(n ^2),不是一种稳定的排序方法。

@选择排序:

* 直接选择排序
* 堆排序
直接选择排序:
void Sort(int *a,int len) { int i,j,min,t; for(i=0;i<len-1;i++) { for(min=i,j=i
+1;j<len;j++) if(a[min]>a[j]) { min=j; } if(min!=i) { t=a[i]; a[i]=a[min]; a[min
]=t; } } }
------》源代码:
#include<iostream> using namespace std; //1.数组的初始化: int arr[]={1,2,5,8,4,3,9,7}
; //2.选择排序: void Sort(int *a,int len) { int i,j,min,t; for(i=0;i<len-1;i++) {
for(min=i,j=i+1;j<len;j++) if(a[min]>a[j]) { min=j; } if(min!=i) { t=a[i]; a[i]=
a[min]; a[min]=t; } } } void Show_arr(int n) { int i; for(i=0;i<n;i++) cout<<arr
[i]<<'\t'; cout<<endl; } void main() { Sort(arr,8); Show_arr(8); }
堆排序:==>选择排序的改进版
*什么是堆?—
堆是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的数值或索引总是小于(或者大于)它的父节点。
堆排序的生成及其排序原理:



堆排序的实现:
void Adjust(int i,int n)//i代表待调整元素的下标,n代表最后一元素的下标。 { int j; arr[0]=arr[i];
while(i<n&&2*i<=n) { j=2*i;//j为i左孩子下标 if(j<n&&arr[j]>arr[j+1]) j++;//j指向较小的孩子 if
(arr[0]>arr[j]) { arr[i]=arr[j]; i=j; } else break; } arr[i]=arr[0]; } void
Build_Heap(int n) { int i; for(i=n/2;i>0;i--) Adjust(i,n); } void Show_arr(int n
) { int i; for(i=1;i<=n;i++) cout<<arr[i]<<'\t'; cout<<endl; } void Heap_Sort(
int n) { int i,t; Build_Heap(n); cout<<"初始堆积树:"<<endl; Show_arr(8); cout<<endl;
for(i=n;i>1;i--) { t=arr[1]; arr[1]=arr[i]; arr[i]=t; cout<<endl<<"第 "<<n-i+1<<
"趟:"<<endl; Show_arr(8); Adjust(1,i-1); } }
------》源代码:
#include<iostream> using namespace std; //1.数组的初始化: int arr[]={0,1,2,5,8,4,3,9,
7}; /*2.堆积树的调整过程: 从二叉树的叶子节点处往上逐一比较来建立最大堆积树:*/ void Adjust(int i,int n)
//i代表待调整元素的下标,n代表最后一元素的下标。 { int j; arr[0]=arr[i]; while(i<n&&2*i<=n) { j=2*i;
//j为i左孩子下标 if(j<n&&arr[j]>arr[j+1]) j++;//j指向较小的孩子 if(arr[0]>arr[j]) { arr[i]=
arr[j]; i=j; } else break; } arr[i]=arr[0]; } //3.堆积树的建立: void Build_Heap(int n)
{ int i; for(i=n/2;i>0;i--) Adjust(i,n); } //显示: void Show_arr(int n) { int i;
for(i=1;i<=n;i++) cout<<arr[i]<<'\t'; cout<<endl; } //4.堆积排序: void Heap_Sort(int
n) { int i,t; Build_Heap(n); cout<<"初始堆积树:"<<endl; Show_arr(8); cout<<endl; for
(i=n;i>1;i--) { t=arr[1]; arr[1]=arr[i]; arr[i]=t; cout<<endl<<"第 "<<n-i+1<<"趟:"
<<endl; Show_arr(8); Adjust(1,i-1); } } void main() { Show_arr(8); cout<<endl;
Heap_Sort(8); }

直接选择排序的算法的时间复杂度为O(n^2),由于直接选择排序交换次数少,当记录占用的字节数较多时,通常比直接插入排序的执行速度要快一些。但它却并不是一种稳定的排序方法,综合来看其性价比
较低.
堆排序方法对记录数较小的排序效果并不理想,但对于n较大的文件很有意义,因为其运行时间主要建立在初始建堆和反复调整堆上。
建堆的时间复杂度与堆所对应的完全二叉树的深度的数量级log2^n 有关,而调用数量级为n,所以整个堆排序的时间复杂度为O(n*
log2^n)。在空间复杂度方面,堆排序只需要一个辅助空间,为O(1)。此外,堆排序并不是稳定的排序哦。

*ps:在算法的设计中排序的方法有很多种,但具体情况还需要具体分析,在情景中应当采取最合适的排序算法。

友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:[email protected]
QQ群:637538335
关注微信