分享
分销 收藏 举报 申诉 / 19
播放页_导航下方通栏广告

类型数据结构算法大全有代码.doc

  • 上传人:天****
  • 文档编号:2653344
  • 上传时间:2024-06-03
  • 格式:DOC
  • 页数:19
  • 大小:162.05KB
  • 下载积分:8 金币
  • 播放页_非在线预览资源立即下载上方广告
    配套讲稿:

    如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。

    特殊限制:

    部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。

    关 键  词:
    数据结构 算法 大全 代码
    资源描述:
    排序算法有:插入排序,合并排序,冒泡排序,选择排序,希尔排序,堆排序,快速排序,计数排序,基数排序,桶排序(没有实现)。比较一下学习后的心得。 我不是很清楚他们的时间复杂度,也真的不知道他们到底谁快谁慢,因为书上的推导我确实只是小小了解,并没有消化。也没有完全理解他们的精髓,所以又什么错误的还需要高手指点。呵呵。 1.普及一下排序稳定,所谓排序稳定就是指:如果两个数相同,对他们进行的排序结果为他们的相对顺序不变。例如A={1,2,1,2,1}这里排序之后是A = {1,1,1,2,2} 稳定就是排序后第一个1就是排序前的第一个1,第二个1就是排序前第二个1,第三个1就是排序前的第三个1。同理2也是一样。这里用颜色标明了。不稳定呢就是他们的顺序不应和开始顺序一致。也就是可能会是A={1,1,1,2,2}这样的结果。 2.普及一下原地排序:原地排序就是指不申请多余的空间来进行的排序,就是在原来的排序数据中比较和交换的排序。例如快速排序,堆排序等都是原地排序,合并排序,计数排序等不是原地排序。 3.感觉谁最好,在我的印象中快速排序是最好的,时间复杂度:n*log(n),不稳定排序。原地排序。他的名字很棒,快速嘛。当然快了。我觉得他的思想很不错,分治,而且还是原地排序,省去和很多的空间浪费。速度也是很快的,n*log(n)。但是有一个软肋就是如果已经是排好的情况下时间复杂度就是n*n,不过在加入随机的情况下这种情况也得以好转,而且他可以做任意的比较,只要你能给出两个元素的大小关系就可以了。适用范围广,速度快。 4.插入排序:n*n的时间复杂度,稳定排序,原地排序。插入排序是我学的第一个排序,速度还是很快的,特别是在数组已排好了之后,用它的思想来插入一个数据,效率是很高的。因为不用全部排。他的数据交换也很少,只是数据后移,然后放入要插入的数据。(这里不是指调用插入排序,而是用它的思想)。我觉得,在数据大部分都排好了,用插入排序会给你带来很大的方便。数据的移动和交换都很少。 插入排序主要思想是:把要排序的数字插入到已经排好的数据中。(我自己理 解的哈)。例如12356是已经排好的序,我们将4插入到他们中,时插入之后也是排好序的。这里显而易见是插入到3的后面。变为123456. 实现思路:插入排序就是先是一个有序的数据,然后把要插入的数据插到指定的位置,而排序首先给的就是无序的,我们怎么确定先得到一个有序的数据呢?答案就是:如果只有一个,当然是有序的咯。我们先拿一个出来,他是有序的,然后把数据一个一个插入到其中,那么插入之后是有序的,所以直到最后都是有序的。。哈哈。结果就出来了! 当然在写的时候还是有一个技巧的,不需要开额外的数组,下标从第二个元素开始遍历直到最后一个,然后插入到前面已经有序的数据中。这样就不会浪费空间了。插入排序用处还是很多的,特别是链表中,因为链表是指针存放的,没有数组那么好准确的用下标表示,插入是简单有效的方法。嘻嘻。。废话少说, 源代码奉上:  1 #include <stdio.h>  2 #include <stdlib.h>  3   4 //插入排序从小到大,nData为要排序的数据,nNum为数据的个数,该排序是稳定的排序  5 bool InsertionSort(int nData[], int nNum)  6 {  7     for (int i = 1; i < nNum; ++i)        //遍历数组,进行插入排序  8     {  9         int nTemp = nData[i]; 10         for (int j = 0; j < i; ++j)        //对该数,寻找他要插入的位置 11         { 12             if (nData[j] > nTemp)    //找到位置,然后插入该位置,之后的数据后移 13             { 14                 for (int k = i; k > j; --k)    //数据后移 15                 { 16                     nData[k] = nData[k -1]; 17                 } 18                 nData[j] = nTemp;        //将数据插入到指定位置 19                 break; 20             } 21         } 22     } 23  24     return true; 25 } 26  27 int main() 28 { 29     int nData[10] = {4,10,9,8,7,6,5,4,3,2};    //创建10个数据,测试 30     InsertionSort(nData, 10);        //调用插入排序 31  32     for (int i = 0; i < 10; ++i)         33     { 34         printf("%d ", nData[i]); 35     } 36  37     printf("\n"); 38     system("puase"); 39     return 0; 40 } 5.冒泡排序,n*n的时间复杂度,稳定排序,原地排序。冒泡排序的思想很不错,一个一个比较,把小的上移,依次确定当前最小元素。因为他简单,稳定排序,而且好实现,所以用处也是比较多的。还有一点就是加上哨兵之后他可以提前退出。 冒泡排序的主要思路:我们把要排序的数组A = {3,4,2,1} 看成一组水泡,就像冒泡一样,轻的在上面,重的在下面,换成数据,就是小的在上面,大的在下面。 我们先把最轻的冒出到顶端,然后冒出第二轻的在最轻的下面,接着冒出第三轻的。依次内推。直到所有都冒出来了为止。 我们怎么做到把最轻的放在顶端呢?我们从最底下的数据开始冒,如果比他上面的数据小,就交换(冒上去),然后再用第二第下的数据比较(此时他已经是较轻的一个),如果他比他上面的小,则交换,把小的冒上去。直到比到第一位置,得到的就是最轻的数据咯,这个过程就像是冒泡一样,下面的和上面的比较,小的冒上去。大的沉下来。呵呵。 画个图先: 最初 第一次结果 第二次结果 第三次结果 3 3 3 1 4 4 1 3 2 1 4 4 1 2 2 2 开始:1 和2 比,1比2小,浮上,然后1跟4比,再1跟3比,这样结构就变为1,3,4,2。最小的位置确定了,然后我们确定第二小的,同理2 vs 4, 2 vs 3 得到2, 再确定第3小数据,3 vs 4得到3,最后就是4为最大的数据,我们冒泡就排好了。 注:这里红色的1,2是前一次比较1 vs 2交换的结构。后面也一样。 大概思路就这样了,奉上源代码:   #include <stdio.h> #include <stdlib.h> //冒泡排序, pnData要排序的数据, nLen数据的个数 int BubbleSort(int* pnData, int nLen) {     bool isOk = false;        //设置排序是否结束的哨兵     //i从[0,nLen-1)开始冒泡,确定第i个元素     for (int i = 0; i < nLen - 1 && !isOk; ++i)     {         isOk = true;        //假定排序成功         //从[nLen - 1, i)检查是否比上面一个小,把小的冒泡浮上去         for (int j = nLen- 1; j > i; --j)         {             if (pnData[j] < pnData[j - 1])    //如果下面的比上面小,交换             {                 int nTemp = pnData[j];                 pnData[j] = pnData[j - 1];                 pnData[j - 1] = nTemp;                 isOk = false;             }         }     }     return 1; } int main() {     int nData[10] = {4,10,9,8,7,6,5,4,3,2};    //创建10个数据,测试     BubbleSort(nData, 10);        //调用冒泡排序     for (int i = 0; i < 10; ++i)             {         printf("%d ", nData[i]);     }     printf("\n");     system("pause");     return 0; }  我这里用了一个哨兵做标记,就是如果在已经是排好序的情况下我们能检测出来并退出。随便说一下,冒泡排序是稳定的排序。 6.选择排序,n*n的时间复杂度, 稳定排序,原地排序。选择排序就是冒泡的基本思想,从小的定位,一个一个选择,直到选择结束。他和插入排序是一个相反的过程,插入是确定一个元素的位置,而选择是确定这个位置的元素。他的好处就是每次只选择确定的元素,不会对很多数据进行交换。所以在数据交换量上应该比冒泡小。 选择排序和冒泡排序思路上有一点相似,都是先确定最小元素,再确定第二笑元素,最后确定最大元素。他的主要流程如下: 1.加入一个数组A = {5,3,6,2,4,7},我们对他进行排序 2.确定最小的元素放在A[0]位置,我们怎么确定呢,首先默认最小元素为5,他的索引为0,然后用它跟3比较,比他打,则认为最小元素为3,他的索引为1,然后用3跟6比,发现比他小,最小元素还是3,然后跟2比,最小元素变成了2,索引为3,然后跟4比,跟7比。当比较结束之后,最小元素也尘埃落定了。就是2,索引为3,然后我们把他放在A[0]处。为了使A[0]原有数据部丢失,我们使A[0](要放的位置) 与A[3](最小数据的位置)交换。这样就不可以了吗? 3.然后我们在来找第二小元素,放在A[1],第三小元素,放在A[2]。。当寻找完毕,我们排序也就结束了。 4.不过,在找的时候要注意其实位置,不能在找A[2]的时候,还用A[2]的数据跟已经排好的A[0],A[1]比,一定要跟还没有确定位置的元素比。还有一个技巧就是我们不能每次都存元素值和索引,我们只存索引就可以了,通过索引就能找到元素了。呵呵。 5.他和冒泡的相似和区别,冒泡和他最大的区别是他发现比他小就交换,把小的放上面,而选择是选择到最小的在直接放在确定的位置。选择也是稳定的排序。 基本思路就这样了,奉上源代码: #include <stdio.h> #include <stdlib.h> //选择排序, pnData要排序的数据, nLen数据的个数 int SelectSort(int* pnData, int nLen) {     //i从[0,nLen-1)开始选择,确定第i个元素     for (int i = 0; i < nLen - 1; ++i)     {         int nIndex = i;         //遍历剩余数据,选择出当前最小的数据         for (int j = i + 1; j < nLen; ++j)         {             if (pnData[j] < pnData[nIndex])                 {                 nIndex = j;             }         }         //如果当前最小数据索引不是i,也就是说排在i位置的数据在nIndex处         if (nIndex != i)                 {             //交换数据,确定i位置的数据。             int nTemp = pnData[i];             pnData[i] = pnData[nIndex];             pnData[nIndex] = nTemp;         }     }     return 1; } int main() {     int nData[10] = {4,10,9,8,7,6,5,4,3,2};    //创建10个数据,测试     SelectSort(nData, 10);        //调用选择排序     for (int i = 0; i < 10; ++i)             {         printf("%d ", nData[i]);     }     printf("\n");     system("pause");     return 0; } 7.插入排序,选择排序,冒泡排序的比较,他们的时间复杂度都是n*n。我觉得他们的效率也是差不多的,我个人喜欢冒泡一些,因为要用它的时候数据多半不多,而且可以提前的返回已经排序好的数组。而其他两个排序就算已经排好了,他也要做全部的扫描。在数据的交换上,冒泡的确比他们都多。呵呵。举例说明插入一个数据在末尾后排序,冒泡只要一次就能搞定,而选择和插入都必须要n*n的复杂度才能搞定。就看你怎么看待咯。 8.合并排序:n*log(n)的时间复杂度, 稳定排序,非原地排序。他的思想是分治,先分成小的部分,排好部分之后合并,因为我们另外申请的空间,在合并的时候效率是0(n)的。速度很快。貌似他的上限是n*log(n),所以如果说是比较的次数的话,他比快速排序要少一些。对任意的数组都能有效地在n*log(n)排好序。但是因为他是非原地排序,所以虽然他很快,但是貌似他的人气没有快速排序高。 合并排序的主要思想是:把两个已经排序好的序列进行合并,成为一个排序好的序列。例如:13579 2468这两个序列,各自都是排好序的,然后我们进行合并,成为123456789这样一个排好序的序列。貌似这个跟排序关系不大,因为排序给的是一个乱的序列,而合并是合并的两个已经排序好的序列。且慢,我们可以把需要排序的数据分解成N个子序列,当分解的子序列所包含数据个数为1的时候,那么这个序列不就是有序了吗?然后再合并。这个就是有名的”分治“了。。(哈哈。没有想到这么好的思想能在这里学到。)。例如321分成3,2,1三个序列,1这个序列是有序的啦。(只有一个数据当然是有序的啦。当我傻的啊。哈哈)。同理2,3都是有序的。然后我们逐一的合并他们。3,2合并为23,然后在23与1合并为123。哈哈,排序成功。合并排序主要思路就是这样了。但是,问题又出来了,怎么合并两个有序列呢?我相信我应该理解了数组的存储方式,所以直接用数组说事啦。。我们先把下标定位到各有序子序列的开始,也把合并之后数组的下标定位到最初。那么下标对应的位置就是他们当前的最小值了。然后拿他们来比较,把更小的那个放到合并之后数组的下标位置。这样,合并后数组的第一个元素就是他们的最小值了。接着,控制合并后数组的下标后移一个,把比较时小数字所在序列对应的下标后移一个。这样。下次比较的时候,他得到就是他的第二小,(第一下已经合并了)就是当前最小值了,在于另一个序列的当前最小值比较,用小的一个放到合并后数组的相应位置。依次类推。接着当数据都合并玩了结束,合并完成。(这样说忒空泛了,云里雾里的,BS一下以前的我。) 1357 2468 来做例子: (1回合)    1357 2468 00000(合并后数据空) (2)  357 2468 100000(0表示空) 因为1 < 2所以把1放到合并后位置中了(这里1并不是丢掉了,而是下标变为指向3了,1是没有写而已。呵呵。理解为数组的下标指向了3) (3) 357 468 120000  因为3 > 2,所以把2放进去 (4) 57 468  123000  同理3 < 4 (5) 57 68   1234000 同理5 > 4 (6) 7 68    1234500 同理5 > 6 (7) 7 8        1234560 同理7 > 6 (8) 0(空了) 8 12345670 同理7 < 8 (9) 0 0 12345678  弄最后一个 PS:这是用记事本写的哈,没有钱买office而且也不是很会用。哈哈。我想以后的我也不见怪的哈。。关键还有书嘛,这里看不懂还有教科书。。 当然,这些只是思路。并不是一定一成不变的这样。合并OK,那么我们就可以用合并排序了哦!哈哈。。不过注意,那个321全部弄成一个单个数字,然后一个一个合并这样来合并似乎不是很好,貌似还有更好的解决方案。哈哈,对了,就是我先分一半来合并。如果这一半是排好序的,那么合并不久简单了吗?但是我怎么让一般排好序呢。呵呵简单,我一半在分一半合并排序,在分一半合并排序,直到分到两个都是1个了,就合并,ok! 例如,81726354: (1)分成9172 6354  (2)把8172 分成 81 和72 把6354分成63和54 (3)81分成8和1,哦能合并了哦。合并为18, 同理72,63,54,也可以分解成单个合并为27,36,45 (4) 现在变为了 18, 27, 36, 45了,这个时侯,18 和27能合并了,合并为1278 同理36,合并为45 3456 (5) 好了最好吧,1278和3456合并为12345678.ok排序成功。哈哈。 这样把一个问题分解为两个或多个小问题,然后在分解,最后解决小小问题,已达到解决打问题的目的。 哈哈。分治很强大。哈哈。如果看不懂,我也没有办法啦。。看教科书吧。呵呵 思路主要就是这样了哦: 程序实现上也有点技巧。这个就不说了,直接奉上源代码:   1 #include <stdio.h>   2 #include <stdlib.h>   3    4 //合并排序的合并程序他合并数组nData中位置为[nP,nM) 和[nM,nR).这个是更接近标准的思路   5 bool MergeStandard(int nData[], int nP, int nM, int nR)   6 {   7     int n1 = nM - nP;        //第一个合并数据的长度   8     int n2 = nR - nM;        //第二个合并数据的长度   9   10     int *pnD1 = new int[n1 + 1];        //申请一个保存第一个数据的空间  11     int *pnD2 = new int[n2 + 1];        //申请二个保存第一个数据的空间  12   13     for (int i = 0; i < n1; ++i)        //复制第一个数据到临时空间里面  14     {  15         pnD1[i] = nData[nP + i];  16     }  17     pnD1[n1] = INT_MAX;                    //将最后一个数据设置为最大值(哨兵)  18   19     for (int i = 0; i < n2; ++i)        //复制第二个数据到临时空间里面  20     {  21         pnD2[i] = nData[nM + i];  22     }  23     pnD2[n2] = INT_MAX;                    //将最后一个数据设置为最大值(哨兵)  24       25     n1 =  n2 = 0;  26   27     while(nP < nR)  28     {  29         nData[nP++] = pnD1[n1] <  pnD2[n2] ? pnD1[n1++] : pnD2[n2++];        //取出当前最小值到指定位置  30     }  31   32     delete pnD1;  33     delete pnD2;  34     return true;  35 }  36   37 //合并排序的合并程序他合并数组nData中位置为[nP,nM) 和[nM,nR).  38 bool Merge(int nData[], int nP, int nM, int nR)  39 {  40     //这里面有几个注释语句是因为当时想少写几行而至。看似短了,其实运行时间是一样的,而且不易阅读。  41   42     int nLen1 = nM - nP;        //第一个合并数据的长度  43     int nLen2 = nR - nM;         //第二个合并数据的长度  44     int* pnD1 = new int[nLen1];    //申请一个保存第一个数据的空间  45     int* pnD2 = new int[nLen2];   //申请一个保存第一个数据的空间  46       47     int i = 0;   48     for ( i = 0; i < nLen1; ++i)        //复制第一个数据到临时空间里面  49     {  50         pnD1[i] = nData[nP + i];  51     }  52   53     int j = 0;  54     for (j = 0; j < nLen2; ++j)        //复制第二个数据到临时空间里面  55     {  56         pnD2[j] = nData[nM + j];  57     }  58   59     i = j = 0;  60     while (i < nLen1 && j < nLen2)  61     {  62         //nData[nP++] = pnD1[i] < pnD2[j] ? pnD1[i++] : pnD2[j++];        //取出当前最小值添加到数据中  63           64         if (pnD1[i] < pnD2[j])        //取出最小值,并添加到指定位置中,如果pnD1[i] < pnD2[j]  65         {  66             nData[nP] = pnD1[i];    //取出pnD1的值,然后i++,定位到下一个个最小值。  67             ++i;  68         }  69         else                        //这里同上  70         {  71             nData[nP] = pnD2[j];  72             ++j;  73         }  74         ++nP;                        //最后np++,到确定下一个数据  75     }  76   77     if (i < nLen1)                    //如果第一个数据没有结束(第二个数据已经结束了)  78     {  79         while (nP < nR)                //直接把第一个剩余的数据加到nData的后面即可。  80         {  81             //nData[nP++] = pnD1[i++];  82             nData[nP] = pnD1[i];  83             ++nP;  84             ++i;  85         }  86     }  87     else                            //否则(第一个结束,第二个没有结束)  88     {  89         while (nP < nR)                //直接把第一个剩余的数据加到nData的后面即可。  90         {  91             //nData[nP++] = pnD2[j++];  92             nData[nP] = pnD2[j];  93             ++nP;  94             ++j;  95         }  96     }  97   98     delete pnD1;        //释放申请的内存空间  99     delete pnD2; 100  101     return true; 102 } 103  104 //合并的递归调用,排序[nBegin, nEnd)区间的内容 105 bool MergeRecursion(int nData[], int nBegin, int nEnd) 106 { 107     if (nBegin >= nEnd - 1)        //已经到最小颗粒了,直接返回 108     { 109         return false; 110     } 111  112     int nMid = (nBegin + nEnd) / 2;            //计算出他们的中间位置,便于分治 113     MergeRecursion(nData, nBegin, nMid);    //递归调用,合并排序好左边一半 114     MergeRecursion(nData, nMid, nEnd);        //递归调用,合并排序好右边一半 115     //Merge(nData, nBegin, nMid, nEnd);        //将已经合并排序好的左右数据合并,时整个数据排序完成 116     MergeStandard(nData, nBegin, nMid, nEnd);//(用更接近标准的方法合并) 117  118     return true; 119 } 120  121 //合并排序 122 bool MergeSort(int nData[], int nNum) 123 { 124     return MergeRecursion(nData, 0, nNum);        //调用递归,完成合并排序 125 } 126  127 int main() 128 { 129     int nData[10] = {4,10,3,8,5,6,7,4,9,2};    //创建10个数据,测试 130  131     MergeSort(nData, 10); 132     for (int i = 0; i < 10; ++i)         133     { 134         printf("%d ", nData[i]); 135     } 136  137     printf("\n"); 138     system("pause"); 139     return 0; 140 } 141  9.堆排序:n*log(n)的时间复杂度, 非稳定排序,原地排序。他的思想是利用的堆这种数据结构,堆可以看成一个完全二叉树,所以在排序中比较的次数可以做到很少。加上他也是原地排序,不需要申请额外的空间,效率也不错。可是他的思想感觉比快速难掌握一些。还有就是在已经排好序的基础上添加一个数据再排序,他的交换次数和比较次数一点都不会减少。虽然堆排序在使用的中没有快速排序广泛,但是他的数据结构和思想真的很不错,而且用它来实现优先队列,效率没得说。堆,还是要好好学习掌握的。 #include <stdio.h> #include <stdlib.h> //交换两个整数。注意一定要if判断是否两个相等,如果 //不相等才交换,如果相等也交换会出错的。a^a = 0 inline void Swap(int& a, int& b) {     if (a != b)     {         a^= b;         b^= a;         a^= b;     } } //维持一个最大堆 int Heapify(int* npData, int nPos, int nLen) {     int nMax = -1;                        //暂存最大值     int nChild = nPos * 2;                //他的左孩子位置     while(nChild <= nLen)                //判断他是否有孩子     {         nMax = npData[nPos];            //是当前最大值为他         if (nMax < npData[nChild])        //与左孩子比较         {             nMax = npData[nChild];        //如果比左孩子小,就时最大值为左孩子         }         //同理与右孩子比较,这里要注意,必须要保证有右孩子。         if (nChild + 1 <= nLen && nMax < npData[nChild + 1])             {             ++nChild;                    //赋值最大值的时候把孩子变为右孩子,方便最后的数据交换             nMax = npData[nChild];         }         if (nMax != npData[nPos])        //判断是否该节点比孩子都打,如果不大         {             Swap(npData[nPos], npData[nChild]);    //与最大孩子交换数据             nPos = nChild;                        //该节点位置变为交换孩子的位置             nChild *= 2;                        //因为只有交换后才使不满足堆得性质。         }         else                            //都最大了,满足堆得性质了。退出循环         {             break;         }     }     return 1;                        //维持结束。 } //建立一个堆 int BuildHeap(int* npData, int nLen) {     //从nLen / 2最后一个有叶子的数据开始,逐一的插入堆,并维持堆得平衡。     //因为堆是一个完全二叉树,所以nlen/2+1- nLen之间肯定都是叶子。     //叶子还判断什么呢。只有一个数据,肯定满足堆得性质咯。     for (int i = nLen / 2; i >= 1; --i)     {         Heapify(npData, i, nLen);     }     return 1; } //堆排序 int HeapSort(int* npData, int nLen) {     BuildHeap(npData, nLen);        //建立一个堆。     while(nLen >= 1)                //逐一交和第一个元素交换数据到最后     {                                //完成排序         Swap(npData[nLen], npData[1]);         --nLen;         Heapify(npData, 1, nLen);//交换之后一定要维持一下堆得性质。     }                            //不然小的成第一个元素,就不是堆了。     return 1; } //main函数, int main() {     int nData[11] = {0,9,8,7,6,5,4,3,2,1,0};    //测试数据,下标从1开始哦。     HeapSort(nData, 10);                        //堆排序     for (int i = 1; i <= 10; ++i)                //输出排序结果。     {         printf("%d ", nData[i]);     }     printf("\n");      system("pause");     return 0; } 10.希尔排序:n*log(n)的时间复杂度(这里是错误的,应该是n^lamda(1 < lamda < 2), lamda和每次步长选择有关。), 非稳定排序,原地排序。主要思想是分治,不过他的分治和合并排序的分治不一样,他是按步长来分组的,而不是想合并那样左一半右一半。开始步长为整个的长度的一半。分成nLen/2个组,然后每组排序。接个步长减为原来的一半在分组排序,直到步长为1,排序之后希尔排序就完成了。这个思路很好,据说是插入排序的升级版,所以在实现每组排序的时候我故意用了插入排序。我觉得他是一个特别好的排序方法了。他的缺点就是两个数可能比较多次,因为两个数据会多次分不过他们不会出现数据的交换。效率也是很高的。 主要思想借用了合并排序的思想。不过他不是左边一半右边一半,而是按照步长来分,随着步长减少,分成的组也越少。然后进行各组的插入排序。 11.快速排序,堆排序,合并排序,希尔排序的比较,他们的时间复杂的都是n*log(n),我认为在使用上快速排序最广泛,他原地排序,虽然不稳定,可是很多情况下排序根本就不在意他是否稳定。他的比较次数是比较小的,因为他把数据分成了大和小的两部分。每次都
    展开阅读全文
    提示  咨信网温馨提示:
    1、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
    2、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,个别因单元格分列造成显示页码不一将协商解决,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
    3、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
    4、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前可先查看【教您几个在下载文档中可以更好的避免被坑】。
    5、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
    6、文档遇到问题,请及时联系平台进行协调解决,联系【微信客服】、【QQ客服】,若有其他问题请点击或扫码反馈【服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【版权申诉】”,意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:0574-28810668;投诉电话:18658249818。

    开通VIP折扣优惠下载文档

    自信AI创作助手
    关于本文
    本文标题:数据结构算法大全有代码.doc
    链接地址:https://www.zixin.com.cn/doc/2653344.html
    页脚通栏广告

    Copyright ©2010-2025   All Rights Reserved  宁波自信网络信息技术有限公司 版权所有   |  客服电话:0574-28810668    微信客服:咨信网客服    投诉电话:18658249818   

    违法和不良信息举报邮箱:help@zixin.com.cn    文档合作和网站合作邮箱:fuwu@zixin.com.cn    意见反馈和侵权处理邮箱:1219186828@qq.com   | 证照中心

    12321jubao.png12321网络举报中心 电话:010-12321  jubao.png中国互联网举报中心 电话:12377   gongan.png浙公网安备33021202000488号  icp.png浙ICP备2021020529号-1 浙B2-20240490   


    关注我们 :微信公众号  抖音  微博  LOFTER               

    自信网络  |  ZixinNetwork