数据结构笔记(排序技术)

  • /**

  • 排序技术的概念

  •     排序:

  •     正序:按关键码排好序

  •     逆序(反序): 与正序序列顺序相反

  •     趟: 在排序过程中, 将待排序的记录序列扫描一遍称为一趟

  •         排序算法的稳定性: 假定在待排序的记录集中, 存在多个具有相同

  •         键值的记录, 若经过排序 这些记录的相对次序仍然保持不变, 即

  •         排序算法具有稳定性(效率高的算法一般不稳定, 效率低的算法一

  •         般稳定)

  •     时间复杂度:

  •         比较: (关键码之间的比较)

  •         移动: (记录从一个位置移动到另一一个位置)

  •     空间复杂度: 辅助存储空间

  •         辅助存储空间是指在数据规模一定的条件下, 除了存放待排序记录

  •         占用的存储空间之外, 执行算法所需要的其他存储空间

  • **/

  • /**

  • 插入类排序

  •     主要操作: 插入

  •     基本思想: 每次将一个待排序的记录按其关键码的大小插入到一个已经

  •     排好序的有序序列中, 直到全部记录排好序为止

  •     方法:

  •         直接插入排序

  •             基本思想: 在插入第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]<<" ";

  • }

  •  
发布了21 篇原创文章 · 获赞 4 · 访问量 2518
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章