程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 10種排序方法

10種排序方法

編輯:C#入門知識

一、冒泡(Bubble)排序


[csharp]  void BubbleSortArray() 

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

void BubbleSortArray()
{
      for(int i=1;i<n;i++)
      {
        for(int j=0;i<n-i;j++)
         {
              if(a[j]>a[j+1])//比較交換相鄰元素
               {
                   int temp;
                   temp=a[j]; a[j]=a[j+1]; a[j+1]=temp;
               }
         }
      }
}
二、選擇排序

 

[cpp]  void SelectSortArray() 

    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)//找到最小項交換,即將這一項移到列表中的正確位置  
         { 
             int temp; 
             temp=arr[i]; arr[i]=arr[min_index]; arr[min_index]=temp; 


void SelectSortArray()
{
    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)//找到最小項交換,即將這一項移到列表中的正確位置
         {
             int temp;
             temp=arr[i]; arr[i]=arr[min_index]; arr[min_index]=temp;
}
}
}
 

三、插入排序

 

[cpp]  void InsertSortArray() 

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; 

void InsertSortArray()
{
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;
}
}
四、殼(Shell)排序

 

 

[cpp]  void ShellSortArray() 

  for(int incr=3;incr<0;incr--)//增量遞減,以增量3,2,1為例  

       for(int L=0;L<(n-1)/incr;L++)//重復分成的每個子列表  

   for(int i=L+incr;i<n;i+=incr)//對每個子列表應用插入排序  
   { 
      int temp=arr[i]; 
      int j=i-incr; 
      while(j>=0&&arr[j]>temp) 
      { 
          arr[j+incr]=arr[j]; 
          j-=incr; 

arr[j+incr]=temp; 



void ShellSortArray()
{
  for(int incr=3;incr<0;incr--)//增量遞減,以增量3,2,1為例
{
       for(int L=0;L<(n-1)/incr;L++)//重復分成的每個子列表
{
   for(int i=L+incr;i<n;i+=incr)//對每個子列表應用插入排序
   {
      int temp=arr[i];
      int j=i-incr;
      while(j>=0&&arr[j]>temp)
      {
          arr[j+incr]=arr[j];
          j-=incr;
}
arr[j+incr]=temp;
}
}
}
}
五、歸並排序五、歸並排序

 

[cpp]  void MergeSort(int low,int high) 

   if(low>=high)   return;//每個子列表中剩下一個元素時停止  
   else int mid=(low+high)/2;/*將列表劃分成相等的兩個子列表,若有奇數個元素,則在左邊子列表大於右側子列表*/ 
   MergeSort(low,mid);//子列表進一步劃分  
   MergeSort(mid+1,high); 
   int [] B=new int [high-low+1];//新建一個數組,用於存放歸並的元素  
   for(int i=low,j=mid+1,k=low;i<=mid && j<=high;k++)/*兩個子列表進行排序歸並,直到兩個子列表中的一個結束*/ 
   { 
       if (arr[i]<=arr[j];) 

    B[k]=arr[i]; 
    I++; 

else 
    { B[k]=arr[j]; j++; } 

for(   ;j<=high;j++,k++)//如果第二個子列表中仍然有元素,則追加到新列表  
      B[k]=arr[j]; 
   for(   ;i<=mid;i++,k++)//如果在第一個子列表中仍然有元素,則追加到新列表中  
      B[k]=arr[i]; 
   for(int z=0;z<high-low+1;z++)//將排序的數組B的 所有元素復制到原始數組arr中  
      arr[z]=B[z]; 

void MergeSort(int low,int high)
{
   if(low>=high)   return;//每個子列表中剩下一個元素時停止
   else int mid=(low+high)/2;/*將列表劃分成相等的兩個子列表,若有奇數個元素,則在左邊子列表大於右側子列表*/
   MergeSort(low,mid);//子列表進一步劃分
   MergeSort(mid+1,high);
   int [] B=new int [high-low+1];//新建一個數組,用於存放歸並的元素
   for(int i=low,j=mid+1,k=low;i<=mid && j<=high;k++)/*兩個子列表進行排序歸並,直到兩個子列表中的一個結束*/
   {
       if (arr[i]<=arr[j];)
{
    B[k]=arr[i];
    I++;
}
else
    { B[k]=arr[j]; j++; }
}
for(   ;j<=high;j++,k++)//如果第二個子列表中仍然有元素,則追加到新列表
      B[k]=arr[j];
   for(   ;i<=mid;i++,k++)//如果在第一個子列表中仍然有元素,則追加到新列表中
      B[k]=arr[i];
   for(int z=0;z<high-low+1;z++)//將排序的數組B的 所有元素復制到原始數組arr中
      arr[z]=B[z];
}
六、快速排序

 

[cpp]  int Partition(int [] arr,int low,int high) 

    int pivot=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 ;//返回樞紐元素所在的位置  

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

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

        int Partition(int [] arr,int low,int high)
        {
            int pivot=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 ;//返回樞紐元素所在的位置
        }
        void QuickSort(int [] a,int low,int high)
        {
            if (low <high )
            {
                int n=Partition (a ,low ,high );
                QuickSort (a ,low ,n );
                QuickSort (a ,n +1,high );
            }
        }
 

七、堆排序

 

[cpp]  void HeapSort(SeqIAst R) 
{    //對R[1..n]進行堆排序,不妨用R[0]做暫存單元  
    int I; 
    BuildHeap(R); //將R[1-n]建成初始堆  
    for(i=n;i>1;i--) //對當前無序區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]可能違反堆性質  
    } 

void HeapSort(SeqIAst R)
{    //對R[1..n]進行堆排序,不妨用R[0]做暫存單元
    int I;
    BuildHeap(R); //將R[1-n]建成初始堆
    for(i=n;i>1;i--) //對當前無序區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]可能違反堆性質
    }
}
八、拓撲排序八、拓撲排序

 

[cpp] void TopologicalSort()/*輸出拓撲排序函數。若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("排序成功。"); 

void TopologicalSort()/*輸出拓撲排序函數。若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("排序成功。");
}
 

九、錦標賽排序(轉)

[cpp] #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; 

#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;
}
十、基數排序

十、基數排序(轉 C#)

[csharp]  using System; 
  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, int iMaxLength) 
  { 
  List<int> list = new List<int>();//存放每次排序後的元素  
  List<int>[] listArr = new List<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("unknow error"); 
  } 
  } 
  for (int j = 0; j < listArr.Length; j++)//將十個桶裡的數據重新排列,壓入list  
  foreach (int number in listArr[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(int iLength) 
  { 
  int[] arr = new int[iLength]; 
  Random random = new Random(); 
  for (int i = 0; i < iLength; i++) 
  arr[i] = random.Next(0,1001); 
  return arr; 
  } 
  } 
  } 

using System;
  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, int iMaxLength)
  {
  List<int> list = new List<int>();//存放每次排序後的元素
  List<int>[] listArr = new List<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("unknow error");
  }
  }
  for (int j = 0; j < listArr.Length; j++)//將十個桶裡的數據重新排列,壓入list
  foreach (int number in listArr[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(int iLength)
  {
  int[] arr = new int[iLength];
  Random random = new Random();
  for (int i = 0; i < iLength; i++)
  arr[i] = random.Next(0,1001);
  return arr;
  }
  }
  }
 

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved