数据结构-算法的时间复杂度

一、插入排序       1)直接插入排序       2)折半插入排序       3)希尔排序

 

               二、交换排序       1)冒泡排序             2)快速排序      

 

               三、选择排序       1)简单选 择排序       2)堆 排序      

 

               四、归并排序      

 

               五、基数排序     

 

         一、插入排序

 

              1)直接插入排序     算法 演示

               时间复杂度: 平均情况 —O(n2 )     最坏情况—O(n2 )     辅助空间: O(1)      稳定性: 稳定

 

复制到剪贴板 折叠 C 代码
  1. void  InsertSort(SqList &L) {       
  2.    // 对顺序表L作直接插入排序。   
  3.    int  i,j;   
  4.    for  (i=2; i<=L.length; ++i)   
  5.      if  (LT(L.r[i].key, L.r[i-1].key)) {    
  6.        // "<"时,需将L.r[i]插入有序 子表   
  7.       L.r[0] = L.r[i];                  // 复制为哨兵   
  8.        for  (j=i-1;  LT(L.r[0].key, L.r[j].key);  --j)   
  9.         L.r[j+1] = L.r[j];              // 记录后移   
  10.       L.r[j+1] = L.r[0];                // 插入到正确位置   
  11.     }   
  12. // InsertSort   

 

              2)折半插入排序

               时间复杂度: 平均情况 —O(n2 )     稳定性: 稳定

 

复制到剪贴板 折叠 C 代码
  1. void  BInsertSort(SqList &L) {       
  2.    // 对顺序表L作折半插入排序。   
  3.    int  i,j,high,low,m;   
  4.    for  (i=2; i<=L.length; ++i) {   
  5.     L.r[0] = L.r[i];        // 将L.r[i]暂存到L.r[0]   
  6.     low = 1;   high = i-1;   
  7.      while  (low<=high) {     // 在r[low..high]中折半查找有序插入的位置   
  8.       m = (low+high)/2;                             // 折半   
  9.        if  (LT(L.r[0].key, L.r[m].key)) high = m-1;   // 插入点在低半区   
  10.        else   low = m+1;                              // 插入点在高半区   
  11.     }   
  12.      for  (j=i-1; j>=high+1; --j) L.r[j+1] = L.r[j];   // 记录后移   
  13.     L.r[high+1] = L.r[0];                            // 插入   
  14.   }   
  15. // BInsertSort   

 

              3)希尔排序 算法演示

               时间复杂度: 理想情况 —O(nlog2 n)     最坏情况—O(n2 )     稳定性: 不稳定

 

复制到剪贴板 折叠 C 代码
  1. void  ShellInsert(SqList &L,  int  dk) {     
  2.    // 对顺序表L作一趟希尔插入排序。本算法对算法 10.1作了以下修改:   
  3.    //     1. 前后记录位 置的增量是dk,而不是1;   
  4.    //     2. r[0]只是暂存单元,不是哨兵。当 j<=0时,插入位置已找到。   
  5.    int  i,j;   
  6.    for  (i=dk+1; i<=L.length; ++i)   
  7.      if  (LT(L.r[i].key, L.r[i-dk].key)) {  // 需将L.r[i]插入有序增量子表   
  8.       L.r[0] = L.r[i];                    // 暂存在L.r[0]   
  9.        for  (j=i-dk; j>0 && LT(L.r[0].key, L.r[j].key); j-=dk)   
  10.         L.r[j+dk] = L.r[j];               // 记录后移,查找插入位置   
  11.       L.r[j+dk] = L.r[0];                 // 插入   
  12.     }   
  13. // ShellInsert   
  14.   
  15.   
  16. void  ShellSort(SqList &L,  int  dlta[],  int  t) {   
  17.     // 按增量序列 dlta[0..t-1]对顺序表L作希尔排序。   
  18.     for  ( int  k=0; k<t; ++k)   
  19.       ShellInsert(L, dlta[k]);   // 一趟增量为dlta[k]的插入排序   
  20. // ShellSort   

 

        、交换排序

 

              1)冒泡排序 算法演示

               时间复杂度: 平均情况 —O(n2 )     最坏情况—O(n2 )     辅助空间: O(1)      稳定性: 稳定

 

复制到剪贴板 折叠 C 代码
  1. void  BubbleSort(SeqList R) {   
  2.    int  i,j;   
  3.   Boolean exchange;  //交换标志    
  4.    for (i=1;i<n;i++){  //最多做n-1趟排序    
  5.        exchange=FALSE;  //本趟排序开始前,交换标志应为假    
  6.         for (j=n-1;j>=i;j--)  //对当前无序区R[i..n]自下向上扫描    
  7.              if (R[j+1].key<R[j].key){ //交换记录    
  8.                 R[0]=R[j+1];  //R[0] 不是哨兵,仅做暂存单元    
  9.                 R[j+1]=R[j];    
  10.                 R[j]=R[0];   
  11.                 exchange=TRUE;  //发生了交换,故将交换标志置为真    
  12.             }    
  13.              if (!exchange)  //本趟排序未发生交换,提前终止算法    
  14.              return ;   
  15.   }  //endfor(外循 环)    
  16. //BubbleSort    

 

              2)快速排序 算法演示

               时间复杂度: 平均情况 —O(nlog2 n)     最坏情况—O(n2 )     辅助空间: O(log2 n)      稳定性: 不稳定

 

复制到剪贴板 折叠 C 代码
  1. int  Partition(SqList &L,  int  low,  int  high) {     
  2.   // 交换顺序表L中子序列L.r[low..high]的 记录,使枢轴记录到位,       
  3.     // 并返回其所在位置,此 时,在它之前(后)的记录均不大(小)于它       
  4.    KeyType pivotkey;       
  5.    RedType temp;       
  6.    pivotkey = L.r[low].key;      // 用子表的第一个记录作枢轴记录       
  7.     while  (low<high) {            // 从表的两端交替地向中间扫描       
  8.        while  (low<high && L.r[high].key>=pivotkey) --high;       
  9.       temp=L.r[low];       
  10.       L.r[low]=L.r[high];       
  11.       L.r[high]=temp;            // 将比枢轴记录小的记录交换到低端       
  12.        while  (low<high && L.r[low].key<=pivotkey) ++low;       
  13.       temp=L.r[low];       
  14.       L.r[low]=L.r[high];       
  15.       L.r[high]=temp;            // 将比枢轴记录大的记录交换到高端       
  16.    }       
  17.     return  low;                   // 返回枢轴所在位置       
  18. // Partition       
  19.       
  20. int  Partition(SqList &L,  int  low,  int  high) {      
  21. // 交换顺序表L中子序列L.r[low..high]的记 录,使枢轴记录到位,       
  22.     // 并返回其所在位置,此时,在它之前(后)的记录均 不大(小)于它       
  23.    KeyType pivotkey;       
  24.    L.r[0] = L.r[low];             // 用子表的第一个记录作枢轴记录       
  25.    pivotkey = L.r[low].key;       // 枢轴记录关键字       
  26.     while  (low<high) {             // 从表的两端交替地向中间扫描       
  27.        while  (low<high && L.r[high].key>=pivotkey) --high;       
  28.       L.r[low] = L.r[high];       // 将比枢轴记录小的记录移到低端       
  29.        while  (low<high && L.r[low].key<=pivotkey) ++low;       
  30.       L.r[high] = L.r[low];       // 将比枢轴记录大的记录移到高端       
  31.    }       
  32.    L.r[low] = L.r[0];             // 枢轴记录到位       
  33.     return  low;                    // 返回枢轴位置       
  34. // Partition       
  35.       
  36.       
  37. void  QSort(SqList &L,  int  low,  int  high) {         
  38.    // 对顺序表L中的子序列L.r[low..high] 进行快速排序       
  39.    int  pivotloc;       
  40.    if  (low < high) {                       // 长度大于1       
  41.     pivotloc = Partition(L, low, high);   // 将L.r[low..high]一分为二       
  42.     QSort(L, low, pivotloc-1);  // 对低子表递归排序,pivotloc是枢轴位置       
  43.     QSort(L, pivotloc+1, high);           // 对高子表递归排序       
  44.   }       
  45. // QSort    
  46.   
  47. void  QuickSort(SqList &L) {   // 算法10.8   
  48.     // 对顺序表L进行快速排序   
  49.    QSort(L, 1, L.length);   
  50. // QuickSort   

 

        、选择排序

 

              1)简单选择排序 算 法演示

               时间复杂度: 平均情况 —O(n2 )     最坏情况—O(n2 )     辅助空间: O(1)      稳定性: 不稳定

 

复制到剪贴板 折叠 C 代码
  1. void  SelectSort(SqList &L) {     
  2.    // 对顺序表L作简单选择排序。   
  3.    int  i,j;   
  4.    for  (i=1; i<L.length; ++i) {  // 选择第i小的记录,并交换到位   
  5.     j = SelectMinKey(L, i);   // 在L.r[i..L.length]中选择key最小的记录   
  6.      if  (i!=j) {                 // L.r[i]←→L.r[j];   与第i个记录交换   
  7.       RedType temp;   
  8.       temp=L.r[i];   
  9.       L.r[i]=L.r[j];   
  10.       L.r[j]=temp;       
  11.     }    
  12.   }   
  13. // SelectSort   

 

              2)堆排序 算法演示

               时间复杂度: 平均情况 —O(nlog2 n)     最坏情况—O(nlog2 n)     辅助空间: O(1)      稳定性: 不稳定

 

复制到剪贴板 折叠 C 代码
  1. void  HeapAdjust(HeapType &H,  int  s,  int  m) {     
  2.    // 已知H.r[s..m]中记录的关键字除 H.r[s].key之外均满足堆的定义,   
  3.    // 本函数调整H.r[s]的 关键字,使H.r[s..m]成为一个大顶堆   
  4.    // (对其中记录的关键字而言)   
  5.    int  j;   
  6.   RedType rc;   
  7.   rc = H.r[s];   
  8.    for  (j=2*s; j<=m; j*=2) {    // 沿key较大的孩子结点向下筛选   
  9.      if  (j<m && H.r[j].key<H.r[j+1].key) ++j;  // j为key较大的记录的下标   
  10.      if  (rc.key >= H.r[j].key)  break ;          // rc应插入在位置s上   
  11.     H.r[s] = H.r[j];  s = j;   
  12.   }   
  13.   H.r[s] = rc;   // 插 入   
  14. // HeapAdjust   
  15.   
  16. void  HeapSort(HeapType &H) {     
  17.     // 对顺序表H进行堆排序。   
  18.     int  i;   
  19.    RedType temp;   
  20.     for  (i=H.length/2; i>0; --i)   // 把H.r[1..H.length]建成大顶堆   
  21.       HeapAdjust ( H, i, H.length );   
  22.        for  (i=H.length; i>1; --i) {   
  23.          temp=H.r[i];   
  24.          H.r[i]=H.r[1];   
  25.          H.r[1]=temp;   // 将堆顶记录和当前未经排序子序列Hr[1..i]中   
  26.                         // 最后一 个记录相互交换   
  27.          HeapAdjust(H, 1, i-1);   // 将H.r[1..i-1] 重新调整为大顶堆   
  28.       }   
  29. // HeapSort   

 

        、归并排序

 

              1)归并排序 算法演示

               时间复杂度: 平均情况 —O(nlog2 n)      最坏情况—O(nlog2 n)      辅助空间: O(n)      稳定性: 稳定

 

复制到剪贴板 折叠 C 代码
  1. void  Merge (RedType SR[], RedType TR[],  int  i,  int  m,  int  n) {   
  2.     // 将有序的SR[i..m]和SR[m+1..n] 归并为有序的TR[i..n]   
  3.     int  j,k;   
  4.     for  (j=m+1, k=i;  i<=m && j<=n;  ++k) {      
  5.        // 将SR中记录由小 到大地并入TR   
  6.        if  LQ(SR[i].key,SR[j].key) TR[k] = SR[i++];   
  7.        else  TR[k] = SR[j++];   
  8.    }   
  9.     if  (i<=m)   // TR[k..n] = SR[i..m];  将剩余的SR[i..m]复制到TR   
  10.        while  (k<=n && i<=m) TR[k++]=SR[i++];   
  11.     if  (j<=n)   // 将剩余的SR[j..n]复制到TR   
  12.        while  (k<=n &&j <=n) TR[k++]=SR[j++];   
  13. // Merge   
  14.   
  15. void  MSort(RedType SR[], RedType TR1[],  int  s,  int  t) {    
  16.     // 将SR[s..t]归并排序为 TR1[s..t]。   
  17.     int  m;   
  18.    RedType TR2[20];   
  19.     if  (s==t) TR1[t] = SR[s];   
  20.     else  {   
  21.       m=(s+t)/2;             // 将SR[s..t]平分为SR[s..m]和SR[m+1..t]   
  22.       MSort(SR,TR2,s,m);     // 递 归地将SR[s..m]归并为有序的TR2[s..m]   
  23.       MSort(SR,TR2,m+1,t);   // 将SR[m+1..t]归并为有序的TR2[m+1..t]   
  24.       Merge(TR2,TR1,s,m,t);  // 将 TR2[s..m]和TR2[m+1..t]归并到TR1[s..t]   
  25.    }   
  26. // MSort   
  27.   
  28. void  MergeSort(SqList &L) {     
  29.    // 对顺序表L作归并排序。   
  30.   MSort(L.r, L.r, 1, L.length);   
  31. // MergeSort   

 

        、基数排序

 

              1)基数排序 算法演示

               时间复杂度: 平均情况 —O(d(n+rd))      最坏情况—O(d(n+rd))      辅助空间: O(rd)      稳定性: 稳定

 

复制到剪贴板 折叠 C 代码
  1. void  Distribute(SLList &L,  int  i, ArrType &f, ArrType &e) {     
  2.    // 静态链表L的r域中记录已按 (keys[0],...,keys[i-1])有序,   
  3.    // 本算法按第i个关键字 keys[i]建立RADIX个子表,   
  4.    // 使同一子表中记录的keys[i]相同。 f[0..RADIX-1]和e[0..RADIX-1]   
  5.    // 分别指向各子表中第一个和 最后一个记录。   
  6.    int  j, p;   
  7.    for  (j=0; j<RADIX; ++j) f[j] = 0;      // 各子表初始化为空表   
  8.    for  (p=L.r[0].next;  p;  p=L.r[p].next) {   
  9.     j = L.r[p].keys[i]- '0' ;   // 将记录中第i 个关键字映射到[0..RADIX-1],   
  10.      if  (!f[j]) f[j] = p;   
  11.      else  L.r[e[j]].next = p;   
  12.     e[j] = p;                 // 将 p所指的结点插入第j个子表中   
  13.   }   
  14. // Distribute   
  15.   
  16. void  Collect(SLList &L,  int  i, ArrType f, ArrType e) {     
  17.    // 本算法按keys[i]自 小至大地将f[0..RADIX-1]所指各子表依次链接成   
  18.    // 一个链表,e[0..RADIX-1]为各子表的尾 指针   
  19.    int  j,t;   
  20.    for  (j=0; !f[j]; j++);   // 找第一个非空子表,succ为求后继函数: ++   
  21.   L.r[0].next = f[j];   // L.r[0].next指向第一个非空子表中第一个结点   
  22.   t = e[j];   
  23.    while  (j<RADIX) {   
  24.      for  (j=j+1; j<RADIX && !f[j]; j++);        // 找下一个非空子表   
  25.      if  (j<RADIX)  // 链接两个非空子表   
  26.       { L.r[t].next = f[j];  t = e[j]; }   
  27.   }   
  28.   L.r[t].next = 0;    // t指向最后 一个非空子表中的最后一个结点   
  29. // Collect   
  30.   
  31. void  RadixSort(SLList &L) {     
  32.     // L是采用静态链表表示的顺序表。   
  33.     // 对L作基数排序,使得L 成为按关键字自小到大的有序静态链表,   
  34.     // L.r[0]为头结点。   
  35.     int  i;   
  36.    ArrType f, e;   
  37.     for  (i=1; i<L.recnum; ++i) L.r[i-1].next = i;   
  38.    L.r[L.recnum].next = 0;      // 将L改造为静态链表   
  39.     for  (i=0; i<L.keynum; ++i) {     
  40.        // 按最低位优先依次对各关键字进行分配和收集   
  41.       Distribute(L, i, f, e);     // 第i趟分配   
  42.       Collect(L, i, f, e);        // 第i趟收集   
  43.       print_SLList2(L, i);   
  44.    }   
  45. // RadixSort  
转自:http://www.shilin8805.cn/article.asp?id=73
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值