-
/**
-
排序技术的概念
-
排序:
-
正序:按关键码排好序
-
逆序(反序): 与正序序列顺序相反
-
趟: 在排序过程中, 将待排序的记录序列扫描一遍称为一趟
-
排序算法的稳定性: 假定在待排序的记录集中, 存在多个具有相同
-
键值的记录, 若经过排序 这些记录的相对次序仍然保持不变, 即
-
排序算法具有稳定性(效率高的算法一般不稳定, 效率低的算法一
-
般稳定)
-
时间复杂度:
-
比较: (关键码之间的比较)
-
移动: (记录从一个位置移动到另一一个位置)
-
空间复杂度: 辅助存储空间
-
辅助存储空间是指在数据规模一定的条件下, 除了存放待排序记录
-
占用的存储空间之外, 执行算法所需要的其他存储空间
-
**/
-
/**
-
插入类排序
-
主要操作: 插入
-
基本思想: 每次将一个待排序的记录按其关键码的大小插入到一个已经
-
排好序的有序序列中, 直到全部记录排好序为止
-
方法:
-
直接插入排序
-
基本思想: 在插入第i (i>1) 个记录时, 前面的 i-1 个记录已
-
经排好序
-
解决方法: 将第一个记录看成是初始有序表, 然后从第2个记录
-
其依次插入到这个有序表中, 直到第n个记录的插入
-
最好情况(正序): 比较次数n-1, 移动次数2(n-1)
-
时间复杂度: O(n)
-
最坏情况(逆序):
-
时间复杂度O(n^2)
-
平均情况: 时间复杂度O(n^2), 空间复杂度O(1)
-
适用于待排序记录基本有序, 或者排序记录个数较小
-
希尔排序(减小增量的排序)
-
基本思想: 将整个待排序记录分割成若干个子序列
-
在子序列内分别进行直接插入排序
-
待排序序列中的记录基本有序时, 对全体记录进行
-
直接插入排序
-
解决方法: d=n/2, d(i+1)=d(i)/2
-
即for(int d=n/2;d>=1;d=d/2)
-
时间复杂度: O(nlog_2~n)
-
**/
-
/**
-
交换排序
-
主要操作: 交换
-
主要思想: 在待排序列中选两个记录, 将它们的关键码相比较, 如果反
-
序(即排列顺序与排序后的次序正好相反), 则交换它们的存储位置
-
方法:
-
冒泡排序:
-
基本思想: 基本思想:两两比较相邻记录的关键码, 如果反序则
-
交换, 直到没有反序的记录为止
-
最好情况: 比较次数n-1, 移动次数0
-
时间复杂度: O(n)
-
最坏情况:
-
时间复杂度: O(n^2)
-
平均情况: 时间复杂度O(n^2)
-
快速排序:
-
基本思想: 首先选一个轴值(即比较的基准)通过一趟排序将
-
待排序记录分割成独立的两部分, 前一部分记
-
录的关键码均小于或等于轴值, 后一部分记录
-
的关键码均大于或等于轴值然后分别对这两部
-
分重复上述方法, 直到整个序列有序
-
时间复杂度: O(nlog_2~n)
-
**/
-
/**
-
选择排序
-
简单选择排序:
-
基本思想: 第i趟在n-i+1(i=1, 2, ..., n-1)个记录中选取关键码最
-
小的记录作为有序序列中的第i个记录
-
堆排序
-
**/
-
#include<iostream>
-
using namespace std;
-
//数组复制
-
void copyArray(int data[],int data0[],int n){
-
for(int i=1;i<=n;i++){
-
data0[i]=data[i];
-
}
-
}
-
//直接插入排序
-
void insertSort(int data[],int n){
-
for(int i=2;i<=n;i++){
-
data[0]=data[i];
-
int j=i-1;
-
while(data[j]>data[0]){
-
data[j+1]=data[j];
-
j--;
-
}
-
data[j+1]=data[0];
-
}
-
}
-
//希尔排序
-
void xierSort(int data[],int n){
-
for(int d=n/2;d>=1;d=d/2){
-
for(int i=d+1;i<=n;i++){
-
data[0]=data[i];
-
int j=i-d;
-
while(j>0&&data[j]>data[0]){
-
data[j+d]=data[j];
-
j-=d;
-
}
-
data[j+d]=data[0];
-
}
-
}
-
}
-
//冒泡排序
-
void maopaoSort(int data[],int n){
-
for(int i=1;i<=n;i++){
-
int exchange=0;
-
for(int j=1;j<=n-i;j++){
-
if(data[j+1]<data[j]){
-
data[0]=data[j];
-
data[j]=data[j+1];
-
data[j+1]=data[0];
-
exchange=1;
-
}
-
}
-
if(exchange==0) break;
-
}
-
}
-
//快速排序
-
int myPartition(int data[],int first,int last){
-
int i=first;
-
int j=last;
-
data[0]=data[i];
-
while(i<j){
-
while(i<j&&data[0]<=data[j]) j--;
-
if(i<j){
-
data[i]=data[j];
-
i++;
-
}
-
while(i<j&&data[0]>=data[i]) i++;
-
if(i<j){
-
data[j]=data[i];
-
j--;
-
}
-
}
-
data[i]=data[0];
-
return i;
-
}
-
void mySort(int data[],int first,int last,int n){
-
if(first<last){
-
int p=myPartition(data,first,last);
-
mySort(data,first,p-1,n);
-
mySort(data,p+1,last,n);
-
}
-
}
-
//简单选择排序
-
void jianDanSort(int data[],int n){
-
for(int i=1;i<=n;i++){
-
data[0]=data[i];
-
int index=i;
-
for(int j=i+1;j<=n;j++){
-
if(data[j]>data[0])
-
index=j;
-
}
-
if(index!=i){
-
data[0]=data[i];
-
data[i]=data[index];
-
data[index]=data[0];
-
}
-
}
-
}
-
int main(){
-
int n;
-
int data[100];
-
int data0[100];
-
cin>>n;
-
for(int i=1;i<=n;i++)
-
cin>>data[i];
-
cout<<"插入排序"<<endl;
-
copyArray(data,data0,n);
-
insertSort(data,n);
-
for(int k=1;k<=n;k++)
-
cout<<data[k]<<" ";
-
cout<<endl;
-
cout<<"希尔排序"<<endl;
-
copyArray(data0,data,n);
-
xierSort(data0,n);
-
for(int k=1;k<=n;k++)
-
cout<<data0[k]<<" ";
-
cout<<endl;
-
cout<<"冒泡排序"<<endl;
-
copyArray(data,data0,n);
-
maopaoSort(data,n);
-
for(int k=1;k<=n;k++)
-
cout<<data[k]<<" ";
-
cout<<endl;
-
cout<<"快速排序"<<endl;
-
copyArray(data0,data,n);
-
mySort(data0,0,n,n);
-
for(int k=1;k<=n;k++)
-
cout<<data0[k]<<" ";
-
cout<<endl;
-
copyArray(data,data0,n);
-
jianDanSort(data,n);
-
for(int k=1;k<=n;k++)
-
cout<<data0[k]<<" ";
-
cout<<endl;
-
}
-
-
/**
-
简单选择排序
-
基本思想: 第i趟在n-i+1(i=1,2,...,n-1)个记录中选取关键码最小的记录作为有序序列的第i个记录
-
解决方法: 设置一个整型变量index, 用于记录在一趟比较过程中关键码最小的记录位置
-
简单选择排序算法性能分析
-
时间复杂度O(n^2)
-
空间复杂度O(1)
-
简单选择排序是不稳定的
-
堆排序
-
减少关键码间的比较次数
-
查找最小值的同时, 找出最小值
-
堆是具有下列性质的完全二叉树: 每个结点的值都小于或等于其左右孩子结点的值(称为小根堆)
-
或每个结点的值都大于或等于其左右孩子结点的值(称为大根堆)
-
小根堆的根结点是所有结点的最小值
-
较小结点靠近根结点,但不绝对
-
大根堆的根结点是所有结点中的最大者
-
较大结点靠近根节点, 但不绝对
-
将堆用顺序存储结构来存储, 则堆对应一组序列
-
基本思想:
-
首先将待排序的记录序列构造成一个堆(大顶堆)
-
此时, 选出了堆中所有记录的最大者, 然后将它从堆中移走
-
将剩余的记录在调整成堆
-
这样又找出了次大的记录, 以此类推, 直到堆中只有一个记录
-
**/
-
#include<iostream>
-
using namespace std;
-
void selectSort(int a[],int n){
-
for(int i=1;i<=n;i++){
-
int index=i;
-
for(int j=i+1;j<=n;j++)
-
if(a[j]<a[index]) index=j;
-
if(index!=i){
-
a[0]=a[i];
-
a[i]=a[index];
-
a[index]=a[0];
-
}
-
}
-
}
-
void sift(int a[],int k,int m){
-
int i=k;
-
int j=2*i;
-
a[0]=a[i];
-
while(j<=m){
-
if(j<m&&a[j]<a[j+1]) j++;
-
if(a[0]>a[j]) break;
-
else{
-
a[i]=a[j];i=j;j=2*i;
-
}
-
}
-
a[i]=a[0];
-
for(int k=1;k<=5;k++)
-
cout<<a[k]<<" ";
-
cout<<endl;
-
}
-
void heapSort(int a[],int n){
-
for(int i=n/2;i>=1;i--)
-
sift(a,i,n);
-
for(int i=1;i<n;i++){
-
a[0]=a[1];
-
a[1]=a[n-i+1];
-
a[n-i+1]=a[0];
-
sift(a,1,n-i);
-
}
-
}
-
int main(){
-
int a[6]={0,34,67,21,43,56};
-
heapSort(a,5);
-
for(int i=1;i<=5;i++)
-
cout<<a[i]<<" ";
-
}
数据结构笔记(排序技术)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.