IOS自学第五篇

常用数据结构排序与查找

      黑马IOS培训期待与您交流!




  常用的数据结构之排序算法

/*插入排序*/

插入排序的过程为:从一堆牌的上面开始拿牌,每次拿一张牌,按排序原则把牌放到手中正确的位置。桌上的牌拿完后,手中的牌也就排好序了。
 BiInsertsort(int r[], int n)                 //插入排序(折半)
{
 for(int i=2;i<=n;i++)
 {
  if (r[i]<r[i-1])
       {
    r[0] = r[i];   //设置哨兵   
    int low=1,high=i-1;            //折半查找
    while (low<=high)
    {
    int mid=(low+high)/2;
    if (r[0]<r[mid])  
        {  high=mid-1};
    else    
        {low = mid+1;}
     }
    int j;
    for (j=i-1;j>high;j--)    r[j+1] = r[j];   //后移
    r[j+1] = r[0];
         }
 }
 for(int k=1;k<=n;k++)     printf(“%d”,r[k]);   
printf(“\n”);
}

 //希尔排序
void ShellSort ( int r[], int n) {
    for(int d=n/2;d>=1;d=d/2)   //以d为增量进行直接插入排序
  {
        for (int i=d+1;i<=n;i++)  
        {
    r[0] = r[i];   //暂存被插入记录
    int j;
    for( j=i-d; j>0 && r[0]<r[j]; j=j-d)  r[j+d] = r[j];  //记录后移d个位置
    r[j+d] = r[0];
             
      }
   }
   for(int i=1;i<=n;i++)       printf(“%d”,r[k]);   
printf(“\n”);
}

 //起泡排序
void BubbleSort(int r[], int n) {
 int temp,exchange,bound;
    exchange=n;                       //第一趟起泡排序的范围是r[0]到r[n-1]
 while (exchange)                    //仅当上一趟排序有记录交换才进行本趟排序
 {
  bound=exchange;
  exchange=0;  
     for (int j=1; j<bound; j++)     //一趟起泡排序
     if (r[j]>r[j+1])
  {
    temp=r[j];
    r[j]=r[j+1];
    r[j+1]=temp;
    exchange=j;                   //记录每一次发生记录交换的位置
      }
 }
 for(int i=1;i<=n;i++)         printf(“%d”,r[k]);   
printf(“\n”);
}


int Partition(int r[], int first, int end)        //快速排序一次划分
{
 int i=first;                        //初始化
 int j=end;
 r[0]=r[first];
    while (i<j)
 {  
       while (i<j && r[0]<= r[j])       j--;    //右侧扫描
       r[i]=r[j];
       while (i<j && r[i]<= r[0])       i++;    //左侧扫描
       r[j]=r[i];
 }
 r[i]=r[0];
    return i;                           //i为轴值记录的最终位置
}




 //快速排序
void QuickSort(int r[], int first, int end)
{
    if (first<end)
 {                                   //递归结束
           int pivot=Partition(r, first, end);  //一次划分
           QuickSort(r, first, pivot-1);//递归地对左侧子序列进行快速排序
           QuickSort(r, pivot+1, end);  //递归地对右侧子序列进行快速排序
 }
}


 //简单选择排序,选择排序的过程为:在桌上的牌中找出最小的一张牌,拿在手中;重复这种操作,直到把所有牌都拿在手中。
void SelectSort(int r[ ], int n)  {
 int i,j,index,temp;
    for (i=1; i<n; i++)               //对n个记录进行n-1趟简单选择排序
 {  
       index=i;   
       for (j=i+1; j<=n; j++)            //在无序区中选取最小记录
           if (r[j]<r[index])   index=j;
       if (index!=i)
    {
    temp=r[i];
    r[i]=r[index];
    r[index]=temp;
    }
  }
    for(i=1;i<=n;i++)        printf(“%d”,r[k]);   
printf(“\n”);
}

 本章所有算法的复杂度
————————————————————————————————   
    算    法    最好情况          平均情况          最坏情况
————————————————————————————————  
  快速排序      O(NlogN)     O(NlogN)             O(N2)
  归并排序      O(N)            O(NlogN)             O(NlogN)
  基数排序      O(N)            O(N)                     O(N)   
  线性查找                          O(N)
  折半查找                          O(NlogN)
  哈希查找                          O(N/M)*
  健树查找                          O(1)**
————————————————————————————————  


和排序算法一样,查找(searching)算法也是计算机科学中研究得最多的问题之一。查找算法和排序算法是有联系的,因为许多查找算法依赖于要查找的数据集的有序程度。
基本的查找算法有以下4种:

    顺序查找(sequential searching)
int sequential_search(char *item, int count,char key)

{

       register int t;

       for(t=0;t<count;t++)

              if(key==item[t])

                     return t;/*找到返回数组下标*/

       return -1;/*no math*/

}
设n为总元素量:

顺序查找平均情况下要测试你n/2个元素;

最优情况下只需测试一个元素;

最差情况下要测试完n个元素。

对于无序的数据而言顺序查找是唯一可行的方法。
    比较查找(comparison searching)

    基数查找(radix searching)
    哈希查找(hashing)

下面仍然以一付乱序的牌为例来描述这些算法的工作过程。
顺序查找的过程为:从第一张开始查看每一张牌,直到找到要找的牌。

比较查找(也被称作binarysearching,即折半查找)要求牌已经排好序,其过程为:任意抽一张牌,如果这张牌正是要找的牌,则查找过程结束。如果抽出的这张牌比要找的牌大,则在它前面的牌中重复查找操作;反之,则在它后面的牌中重复查找操作,直到找到要找的牌。

基数查找的过程为:先将牌按点数分成13堆,或者按花色分成4堆。然后找出与要找的牌的点数或花色相同的那一堆牌,再在这堆牌中用任意一种查找算法找到要找的牌。

哈希查找的过程为:
    (1)在桌面上留出可以放若干堆牌的空间,并构造一个函数,使其能根据点数和花色将牌映射到特定的堆中(这个函数被称为hashfunction,即哈希函数)。
    (2)根据哈希函数将牌分成若干堆。   
    (3)根据哈希函数找到要找的牌所在的堆,然后在这一堆牌中找到要找的牌。   

例如,可以构造这样一个哈希函数:   
  pile=rank+suit
其中,rank是表示牌的点数的一个数值;suit是表示牌的花色的一个数值;pile表示堆值,它将决定一张牌归入到哪一堆中。如果用1,2,……,13分别表示A,2,…….K,用0,1,2和3分别表示梅花、方块、红桃和黑桃,则pile的值将为1,2,……,16,这样就可以把一付牌分成16堆。

哈希查找虽然看上去有些离谱,但它确实是一种非常实用的查找算法。各种各样的程序,从压缩程序(如Stacker)到磁盘高速缓存程序(如SmartDrive),几乎都通过这种方法来提高查找速度,

以下是一个对字符数组进行对分查找的函数:

/* The Binary search*/

int binary_search(char *items,int count,char key)

{

       int low,high,mid;

       low=0;high=count-1;

       while(low<=high)

       {

              mid=(low+high)/2;

              if(key<items[mid])

                     high=mid-1;

              if(key>items[mid])

                     low=mid+1;

              else

                     return mid; /*found*/

       }

       return -1;

}
对分查找的最优情况也是只比较一次;

最差情况下的比较次数为:log2n。





                  

     黑马IOS培训期待与您交流!


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值