排序算法总结

排序算法有很多,所以在特定情景中使用哪一种算法很重要。为了选择合适的算法,可以按照建议的顺序考虑以下标准: 
1)执行时间 
2)存储空间 
3编程工作 
   
对于数据量较小的情形,(1)(2)差别不大,主要考虑(3);而对于数据量大的,(1)为首要。 
  
主要排序法有: 
一、冒泡(Bubble)排序——相邻交换 
二、选择排序——每次最小/大排在相应的位置 
三、插入排序——将下一个插入已排好的序列中 
四、Shell排序——缩小增量 
五、归并排序 
六、快速排序 
七、堆排序 
八、拓扑排序 
九、锦标赛排序 
十、基数排序 

  
  
一、冒泡(Bubble)排序 
冒泡排序是经过n-1趟子排序完成的,第i趟子排序从第1个数至第n-i个数,若第i个数比后一个数大(则升序,小则降序)则交换两数。 

----------------------------------Code 从小到大排序n个数------------------------------------ 
void BubbleSortArray(int a[] , int n) 

      for(int j=0;j<n-1;j++)           
//
      { 
       for(int i=0;i<n-1-j;i++)         
// 
         { 
             if(a[i]>a[i+1])//
比较交换相邻元素 
              { 
                  int temp; 
                  temp= a[i+1]; a[i+1]=a[i]; a[i]=temp; 
              } 
        } 
      } 

-------------------------------------------------Code------------------------------------------------ 
效率 O(n²),适用于排序小列表。 



  

 

二、选择排序 
选择排序时每一趟从待排序的数据元素中选出最小(或最大)的一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。 选择排序是不稳定的排序方法。

----------------------------------Code 从小到大排序n个数-------------------------------- 
void SelectSortArray(int a[] , int n) 

    int min_index; 
    for(int i=0;i<n-1;i++) 
    { 
         min_index=i; 
         for(int j=i+1;j<n;j++)         //
每次扫描选择最小项 
              if(arr[j]<arr[min_index]) min_index=j; 
         if(min_index!=i)              //
找到最小项交换,即将这一项移到列表中的正确位置 
         { 
              inttemp; 
              temp=arr[i]; arr[i]=arr[min_index]; arr[min_index]=temp; 
        } 
    } 

-------------------------------------------------Code----------------------------------------- 
效率O(n²),适用于排序小的列表。 


  
  

 


三、插入排序 
插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据。

--------------------------------------------Code从小到大排序n个数------------------------------------- 
void InsertSortArray(int a[] , int n) 

    for(int i=1;i<n;i++)             //
循环从第二个数组元素开始,因为arr[0]作为最初已排序部分 
    { 
          int temp=arr[i];             //temp标记为未排序第一个元素 
          int j=i-1; 
          while (j>=0 &&arr[j]>temp)     /*将temp与已排序元素从小到大比较,寻找temp应插入的位置*/ 
         { 
              arr[j+1]=arr[j]; 
              j--; 
         } 
         arr[j+1]=temp; 
     } 

------------------------------Code-------------------------------------------------------------- 
最佳效率On);最糟效率On²)与冒泡、选择相同,适用于排序小列表 
若列表基本有序,则插入排序比冒泡、选择更有效率。 


 

 


四、Shell排序——缩小增量排序 
先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组。所有距离为dl的倍数的记录放在同一个组中。先在各组内进行直接插人排序;然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量dt=1(dt<dt-l<;…<d2<d1),即所有记录放在同一组中进行直接插入排序为止。

-------------------------------------Code 从小到大排序n个数------------------------------------- 
voidshellsort(int data[], int n)

{

     int d, i, j, x;

     d = n / 2;         //d作为增量

     while(d>= 1)       // loop until d = 1

    {

          for(i = d; i < n; i++)

          {

                x = data[i];

                j = i -d;      // prev data index

                while(j >= 0 && data[j] > x)

                {

                        data[j + d] = data[j];

                          j = j - d;

                }

                data[j + d] = x;

        }

        d/= 2;

    }

}
--------------------------------------Code------------------------------------------- 
适用于排序小列表。     分组插入排序
效率估计Onlog2^n~On^1.5),取决于增量值的最初大小。建议使用质数作为增量值,因为如果增量值是2的幂,则在下一个通道中会再次比较相同的元素。 
壳(Shell)排序改进了插入排序,减少了比较的次数。是不稳定的排序,因为排序过程中元素可能会前后跳跃。 
 



五、归并排序 
归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。

----------------------------------------------Code从小到大排序--------------------------------------- 
#include<stdio.h>

void MergeSort(int a[], int size);

void MergePass(int a[], int b[], int seg, int size);

void Merge(int a[], int b[], int low, int mid, int high); 

int main()

{

       int i;

       int a[] = {1, 5,3, 6, 24, 37, 55, 7, 4,56,12,65,36,25};

       MergeSort(a,sizeof(a) / sizeof(*a));

       for(i=0;i< sizeof(a)/sizeof(*a);i++)

            printf("%d ",a[i]);

       printf("\n");

       return 0;

}

 

void MergeSort(int a[], int size)

{

      int temp[size];

      int seg = 1;

      while(seg < size)

      {

            MergePass(a, temp,seg, size);

            seg += seg;

            MergePass(temp, a,seg, size);

            seg += seg;

      }

}

void MergePass(int a[], int b[], int seg, int size)

{

      int seg_start_ind = 0;

      int  j;

      while(seg_start_ind<= size - 2 * seg) //#size - 2 * seg的意思是滿足可兩兩歸併的最低臨界值#%

      {

            Merge(a, b,seg_start_ind, seg_start_ind + seg - 1, seg_start_ind + seg * 2 - 1);

            seg_start_ind += 2* seg;

      }

      //#如果一段是正好可歸併的數量而另一段則少於正好可歸併的數量#%

      if(seg_start_ind + seg< size)

            Merge(a, b,seg_start_ind, seg_start_ind + seg - 1, size - 1);

      else

           for(j =seg_start_ind; j < size; j++) //#如果只剩下一段或者更少的數量#%

               b[j] = a[j];

}

//#只完成兩段之間歸併的功能#%

void Merge(int a[], int b[], int low, int mid, int high)

{

      int k = low;

      int begin1 = low;

      int end1 = mid;

      int begin2 = mid + 1;

      int end2 = high;

      int q;

      while(begin1 <=end1 && begin2 <= end2)

      {

             if(a[begin1] <=a[begin2])

                    b[k++] =a[begin1++];

             else

                    b[k++] =a[begin2++];

    }

    if(begin1 <= end1)

        for(q = begin1; q<= end1; q++)

            b[k++] = a[q];

    else

        for(q = begin2; q<= end2; q++)

            b[k++] = a[q];

}

 

 

方法二

template<typename T>

void merge(T array[], int low, int mid, int high)

{

         int k;

         T *temp = new T[high-low+1];//申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列

         int begin1 = low;

         int end1 = mid;

         int begin2 = mid +1;

         int end2 = high;

        

         for (k = 0; begin1<= end1 && begin2 <= end2; ++k) //比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置

         {

                   if(array[begin1]<=array[begin2])

                            temp[k]= array[begin1++];

                   else

                            temp[k]= array[begin2++];  

         }

                  

         if(begin1 <= end1)//若第一个序列有剩余,直接拷贝出来粘到合并序列尾

                   memcpy(temp+k,array+begin1, (end1-begin1+1)*sizeof(T));

         if(begin2 <= end2)//若第二个序列有剩余,直接拷贝出来粘到合并序列尾

                   memcpy(temp+k,array+begin2, (end2-begin2+1)*sizeof(T));

         memcpy(array+low,temp, (high-low+1)*sizeof(T));//将排序好的序列拷贝回数组中


        delete temp;

}

 

template<typename T>

void merge_sort(T array[], unsigned int first, unsigned intlast)

{

         int mid = 0;

         if(first<last)

         {

                   //mid =(first+last)/2; /*注意防止溢出*/

                   mid =first/2 + last/2;

                   //mid =(first & last) + ((first ^ last) >> 1);

                   merge_sort(array,first, mid);

                   merge_sort(array,mid+1,last);

                   merge(array,first,mid,last);

         }

}

-----------------------------------------------------Code--------------------------------------------------- 
效率Onlogn),归并的最佳、平均和最糟用例效率之间没有差异。 
适用于排序大列表,基于分治法。  

 

 


六、快速排序

快速排序的算法思想:选定一个枢纽元素,对待排序序列进行分割,分割之后的序列一个部分小于枢纽元素,一个部分大于枢纽元素,再对这两个分割好的子序列进行上述的过程。               
-----------------------------------Code--------------------------------------------

void QuickSort(int [] a,int low,inthigh) 

 { 
         if (low<high ) 
         { 
               int n=Partition (a ,low ,high ); 
               QuickSort (a ,low ,n ); 
               QuickSort (a ,n +1,high ); 
          } 
  } 
       

 

int Partition(int [] arr,intlow,int high) 
 { 
       intpivot=arr[low];//
采用子序列的第一个元素作为枢纽元素 
       while (low< high) 
        { 
               //
从后往前栽后半部分中寻找第一个小于枢纽元素的元素 
               while (low < high && arr[high] >= pivot) 
               { 
                      --high; 
               } 
               //将这个比枢纽元素小的元素交换到前半部分 
               swap(arr[low], arr[high]); 
               //从前往后在前半部分中寻找第一个大于枢纽元素的元素 
               while (low <high &&arr [low ]<=pivot ) 
               { 
                   ++low ; 
               } 
               swap (arr [low ],arr [high ]);//将这个枢纽元素大的元素交换到后半部分 
        } 
        return low;//返回枢纽元素所在的位置 
    

----------------------------------------Code------------------------------------- 
平均效率Onlogn),适用于排序大列表。 
此算法的总时间取决于枢纽值的位置;选择第一个元素作为枢纽,可能导致On²)的最糟用例效率。若数基本有序,效率反而最差。选项中间值作为枢纽,效率是Onlogn)。 
基于分治法。 



 七、堆排序 

堆积排序是指利用堆积树(堆)这种资料结构所设计的一种排序算法,可以利用数组的特点快速定位指定索引的元素。

最大堆:后者任一非终端节点的关键字均大于或等于它的左、右孩子的关键字,此时位于堆顶的节点的关键字是整个序列中最大的。 

思想: 
(1)
i=l,并令temp kl ; 
(2)
计算i的左孩子j=2i+1; 
(3)
j<n1,则转(4),否则转(6); 
(4)
比较kjkj+1,kj+1>kj,则令jj1,否则j不变; 
(5)
比较tempkj,若kj>temp,则令ki等于kj,并令i=j,j=2i+1,并转(3),否则转(6) 
(6)
ki等于temp,结束。 
-----------------------------------------Code--------------------------- 
void HeapSort(SeqIAst R) 
 
 { //
R[1..n]进行堆排序,不妨用R[0]做暂存单元    int I;   BuildHeap(R) //R[1-n]建成初始堆for(i=n;i>1i--) //对当前无序区R[1..i]进行堆排序,共做n-1趟。{      R[0]=R[1]; R[1]=R[i];R[i]=R[0]; //将堆顶和堆中最后一个记录交换     Heapify(R,1,i-1);  //R[1..i-1]重新调整为堆,仅有R[1]可能违反堆性质    }    }

template<typenameT>

voidMax_heap(T a[],int S,int len)

{

         int l = 2*S;

         int r = 2*S+1;

         int maxI = S;

         T elem;

         if (l < len && a[l] >a[maxI])

         {

                   maxI = l;

         }

         if (r < len && a[r] >a[maxI])

         {

                   maxI = r;

         }

         if (maxI != S)

         {

                   elem = a[S];

                   a[S] = a[maxI];

                   a[maxI] = elem;

                   Max_heap(a,maxI,len);

         }

}

 

template<typenameT>

voidHeapSort(T a[],int n)

{

         int i;

         T elem;

         for (i = n/2;i>=0;i--)

         {

                   Max_heap(a,i,n);

         }

         for (i= n-1;i>=1;i--)

         {

                   elem = a[0];

                   a[0] = a[i];

                   a[i] = elem;

                   n = n-1;

                   Max_heap(a,0,n);

         }

}

---------------------------------------Code-------------------------------------- 
      
堆排序的时间,主要由建立初始堆和反复重建堆这两部分的时间开销构成,它们均是通过调用Heapify实现的。 
      
堆排序的最坏时间复杂度为O(nlgn)。堆排序的平均性能较接近于最坏性能。    由于建初始堆所需的比较次数较多,所以堆排序不适宜于记录数较少的文件。

堆排序是就地排序,辅助空间为O(1),它是不稳定的排序方法。 

      堆排序与直接插入排序的区别
      
直接选择排序中,为了从R[1..n]中选出关键字最小的记录,必须进行n-1次比较,然后在R[2..n]中选出关键字最小的记录,又需要做n-2次比较。事实上,后面的n-2次比较中,有许多比较可能在前面的n-1次比较中已经做过,但由于前一趟排序时未保留这些比较结果,所以后一趟排序时又重复执行了这些比较操作。  堆排序可通过树形结构保存部分比较结果,可减少比较次数。 
  
 



八、拓扑排序
:学生选修课排课先后顺序 
拓扑排序:把有向图中各顶点按照它们相互之间的优先关系排列成一个线性序列的过程。 
方法: 
在有向图中选一个没有前驱的顶点且输出 
从图中删除该顶点和所有以它为尾的弧 
重复上述两步,直至全部顶点均已输出(拓扑排序成功),或者当图中不存在无前驱的顶点(图中有回路)为止。 
---------------------------------------Code-------------------------------------- 
voidTopologicalSort()/*输出拓扑排序函数。若G无回路,则输出G的顶点的一个拓扑序列并返回OK,否则返回ERROR*/ 

      int indegree[M]; 
      int i,k,j; 
      char n; 
      int count=0; 
      Stack thestack; 
      FindInDegree(G,indegree);//对各顶点求入度indegree[0....num] 
      InitStack(thestack);//初始化栈 
      for(i=0;i<G.num;i++) 
          Console.WriteLine("结点"+G.vertices[i].data+"的入度为"+indegree[i]); 
      for(i=0;i<G.num;i++) 
      { 
          if(indegree[i]==0) 
             Push(thestack.vertices[i]); 
      } 
      Console.Write("拓扑排序输出顺序为:"); 
      while(thestack.Peek()!=null) 
      { 
              Pop(thestack.Peek()); 
              j=locatevex(G,n); 
              if (j==-2) 
                 { 
                        Console.WriteLine("发生错误,程序结束。"); 
                        exit(); 
                 } 
               Console.Write(G.vertices[j].data); 
               count++; 
               for(p=G.vertices[j].firstarc;p!=NULL;p=p.nextarc) 
               { 
                    k=p.adjvex; 
                    if (!(--indegree[k])) 
                        Push(G.vertices[k]); 
               } 
      } 
      if (count<G.num) 
          Cosole.WriteLine("该图有环,出现错误,无法排序。"); 
      else
          Console.WriteLine("排序成功。"); 

----------------------------------------Code-------------------------------------- 
算法的时间复杂度On+e)。 
  
  
 


九、锦标赛排序 
锦标赛排序的算法思想与体育比赛类似。 
    
首先将n个数据元素两两分组,分别按关键字进行比较,得到n2个比较的优胜者(关键字小者),作为第一步比较的结果保留下来, 
    
然后对这n2个数据元素再两两分组,分别按关键字进行比较,…,如此重复,直到选出一个关键字最小的数据元素为止。  
--------------------------------Code inC--------------------------------------- 
#include<stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <math.h> 
#define SIZE 100000 
#define MAX 1000000 
struct node 

       long num;//
关键字 
       char str[10]; 
       int lastwin;//
最后胜的对手 
       int killer;//被击败的对手 
       long times;//比赛次数 
}data[SIZE]; 


long CompareNum=0; 
long ExchangeNum=0; 
long Read(char name[])//读取文件a.txt中的数据,并存放在数组data[]中;最后返回数据的个数 

       FILE *fp; 
       long i=1; 
       fp=fopen(name,"rw"); 
       fscanf(fp,"%d%s",&data[i].num,data[i].str); 
       while(!feof(fp)) 
       { 
               i++; 
               fscanf(fp,"%d%s",&data[i].num,data[i].str);  
       } 
       return (i-1); 

long Create(long num)//创建胜者树,返回冠军(最小数)在数组data[]中的下标 

       int i,j1,j2,max,time=1; 
       long min;//记录当前冠军的下标 
       for(i=1;pow(2,i-1)<num;i++) 
              ; 
       max=pow(2,i-1);//求叶子结点数目 
       for(i=1;i<=max;i++)//初始化叶子结点 
      { 
              data[i].killer=0; 
              data[i].lastwin=0; 
              data[i].times=0; 
              if(i>num) 
                    data[i].num=MAX; 
       } 
      for(i=1;i<=max;i+=2)//第一轮比赛 
      { 
             ++CompareNum; 
             if(data[i].num <= data[i+1].num) 
             { 
                    data[i].lastwin = i+1; 
                    data[i+1].killer=i; 
                    ++data[i].times; 
                    ++data[i+1].times; 
                    min=i; 
              } 
             else
             { 
                    data[i+1].lastwin=i; 
                    data[i].killer=i+1; 
                    ++data[i].times; 
                    ++data[i+1].times; 
                    min=i+1; 
              } 
       } 
       j1=j2=0;//记录连续的两个未被淘汰的选手的下标 
       while(time <= (log(max)/log(2)))//进行淘汰赛 
       { 
              for(i=1;i<=max;i++) 
              { 
                      if(data[i].times==time && data[i].killer==0)//找到一名选手 
                      { 
                              j2=i;//默认其为两选手中的后来的 
                              if(j1==0)//如果第一位置是空的,则刚来的选手先来的 
                              j1=j2; 

                       }
                      else//否则刚来的选手是后来的,那么选手都已到场比赛开始 
                      { 
                              ++CompareNum; 
                              if(data[j1].num <= data[j2].num)//先来的选手获胜 
                              { 
                                     data[j1].lastwin = j2;//最后赢的是j2 
                                     data[j2].killer=j1;//j2是被j1淘汰的 
                                     ++data[j1].times; 
                                     ++data[j2].times;//两选手场次均加1  
                                     min=j1;//最小数下标为j1 
                                      j1=j2=0;//将j1,j2置0 
                               } 

                       }
                       else//同理 
                       { 
                                data[j2].lastwin=j1; 
                                data[j1].killer=j2; 
                                ++data[j1].times; 
                                ++data[j2].times;      
                                min=j2; 
                                j1=j2=0; 
                        } 
               } 
       } 
       time++;//轮数加1 
       } 
 return min;//返回冠军的下标 


void TournamentSort(long num)//锦标赛排序 

       long tag=Create(num);//返回最小数下标 
       FILE *fp1; 
       fp1=fopen("sort.txt","w+");//为写入创建并打开文件sort.txt 
       while(data[tag].num != MAX)//当最小值不是无穷大时 
      { 
              printf("%d %s\n",data[tag].num,data[tag].str);//输出数据 
              fprintf(fp1,"%d %s\n",data[tag].num,data[tag].str);//写入数据 
              data[tag].num=MAX;//将当前冠军用无穷大替换 
              tag=Create(num);//返回下一个冠军的下标  
       } 

int main() 

        int num; 
        char name[10]; 
        printf("Input name of the file:"); 
        gets(name); 
        num=Read(name);//读文件 
        TournamentSort(num);//锦标赛排序 
        printf("CompareNum=%d\nExchangeNum=%d\n",CompareNum,ExchangeNum); 
        return 0; 

------------------------------------------Code------------------------------------- 
  
  

十、基数排序
基数排序又被称为桶排序。与前面介绍的几种排序方法相比较,基数排序和它们有明显的不同。 
前面所介绍的排序方法都是建立在对数据元素关键字进行比较的基础上,所以可以称为基于比较的排序; 
而基数排序首先将待排序数据元素依次“分配”到不同的桶里,然后再把各桶中的数据元素“收集”到一起。 
通过使用对多关键字进行排序的这种“分配”和“收集”的方法,基数排序实现了对多关键字进行排序。 
——————————————————————————————————————— 
例: 
    
每张扑克牌有两个“关键字”:花色和面值。其大小顺序为: 
    
花色:§<¨<©<ª 
    
面值:23<……<K
    
扑克牌的大小先根据花色比较,花色大的牌比花色小的牌大;花色一样的牌再根据面值比较大小。所以,将扑克牌按从小到大的次序排列,可得到以下序列: 
 
§2,…,§A,¨2,…,¨A©2,…,©A,ª2,…,ª
    
这种排序相当于有两个关键字的排序,一般有两种方法实现。 
    
其一:可以先按花色分成四堆(每一堆牌具有相同的花色),然后在每一堆牌里再按面值从小到大的次序排序,最后把已排好序的四堆牌按花色从小到大次序叠放在一起就得到排序的结果。 
其二:可以先按面值排序分成十三堆(每一堆牌具有相同的面值),然后将这十三堆牌按面值从小到大的顺序叠放在一起,再把整副牌按顺序根据花色再分成四堆(每一堆牌已按面值从小到大的顺序有序),最后将这四堆牌按花色从小到大合在一起就得到排序的结果。 
——————————————————————————————————————— 
实现方法: 
  最高位优先(Most Significant Digitfirst)法,简称MSD法:先按k1排序分组,同一组中记录,关键码k1相等,再对各组按k2排序分成子组,之后,对后面的关键码继续这样的排序分组,直到按最次位关键码kd对各子组排序后。再将各组连接起来,便得到一个有序序列。 
  最低位优先(Least Significant Digitfirst)法,简称LSD法:先从kd开始排序,再对kd-1进行排序,依次重复,直到对k1排序后便得到一个有序序列。 
----
-----------------------------Code inC#----------------------------------------

usingSystem; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
namespace LearnSort 

  class Program 
  { 
          static void Main(string[] args) 
         { 
                  int[] arr = CreateRandomArray(10);//产生随机数组 
                  Print(arr);//输出数组 
                  RadixSort(ref arr);//排序 
                  Print(arr);//输出排序后的结果 
                  Console.ReadKey(); 
          } 
          public static void RadixSort(ref int[] arr) 
         { 
                  int iMaxLength = GetMaxLength(arr); 
                  RadixSort(ref arr, iMaxLength); 
         } 
         private static void RadixSort(ref int[] arr, intiMaxLength) 
         { 
                  List<int> list = new List<int>();//存放每次排序后的元素 
                  List<int>[] listArr = newList<int>[10];//十个桶 
                  char currnetChar;//存放当前的字符比如说某个元素123 中的2 
                  string currentItem;//存放当前的元素比如说某个元素123 
                  for (int i = 0; i < listArr.Length; i++)//给十个桶分配内存初始化。 
                  listArr[i] = new List<int>(); 
                  for (int i = 0; i < iMaxLength; i++)//一共执行iMaxLength次,iMaxLength是元素的最大位数。 
                  { 
                            foreach (int number in arr)//分桶 
                           { 
                                    currentItem = number.ToString();//将当前元素转化成字符串 
                                    try { currnetChar =currentItem[currentItem.Length-i-1]; }//从个位向高位开始分桶 
                                    catch { listArr[0].Add(number); continue; }//如果发生异常,则将该数压入listArr[0]。比如说5 是没有十位数的,执行上面的操作肯定会发生越                                                                                                                        界异常的,这正是期望的行为,我们认为5的十位数是0,所以将它压入listArr[0]的桶里。 
                                    switch (currnetChar)//通过currnetChar的值,确定它压人哪个桶中。 
                                    { 
                                             case '0': listArr[0].Add(number); break; 
                                             case '1': listArr[1].Add(number); break; 
                                             case '2': listArr[2].Add(number); break; 
                                             case '3': listArr[3].Add(number); break; 
                                             case '4': listArr[4].Add(number); break; 
                                             case '5': listArr[5].Add(number); break; 
                                             case '6': listArr[6].Add(number); break; 
                                             case '7': listArr[7].Add(number); break; 
                                             case '8': listArr[8].Add(number); break; 
                                             case '9': listArr[9].Add(number); break; 
                                             default: throw new Exception("unknowerror"); 
                                    } 
                           } 
                           for (int j = 0; j < listArr.Length; j++)//将十个桶里的数据重新排列,压入list 
                          {         

                                         foreach (int number inlistArr[j].ToArray<int>()) 
                                   { 
                                           list.Add(number); 
                                           listArr[j].Clear();//清空每个桶 
                                   } 
                                   arr = list.ToArray<int>();//arr指向重新排列的元素 
                                   //Console.Write("{0} times:",i); 
                                   Print(arr);//输出一次排列的结果 
                                   list.Clear();//清空list 
                         } 
                  } 
                  //得到最大元素的位数 
                  private static int GetMaxLength(int[] arr) 
                 { 
                         int iMaxNumber = Int32.MinValue; 
                         foreach (int i in arr)//遍历得到最大值 
                         { 
                                 if (i > iMaxNumber) 
                                 iMaxNumber = i; 
                         } 
                         return iMaxNumber.ToString().Length;//这样获得最大元素的位数是不是有点投机取巧了... 
                 } 
                 //输出数组元素 
                 public static void Print(int[] arr) 
                 { 
                        foreach (int i in arr) 
                       System.Console.Write(i.ToString()+'\t'); 
                       System.Console.WriteLine(); 
                 } 
                 //产生随机数组。随机数的范围是0到1000。参数iLength指产生多少个随机数 
                 public static int[] CreateRandomArray(intiLength) 
                { 
                         int[] arr = new int[iLength]; 
                         Random random = new Random(); 
                         for (int i = 0; i < iLength; i++) 
                         arr[i] = random.Next(0,1001); 
                         return arr; 
                } 
       } 
      } 

}




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值