C++学习之:查找与排序

 对于查找一个数组中某个元素的方法最基本、最简单的查找是顺序查找,对于已经排好序的数组,可以采用二分查找。二分比顺序查找更高效。

1.查找

1.1 顺序查找

从数组的第一个元素开始,依次往后比较,直达找到满足条件的那个位置的元素,输出元素位置或该位置上元素的值。

int array[7]={2,3,4,6,7,9,10};
int x;
cout<<"请输入要查找的数据";
cin>>x;
for(k=0;k<7;++k)
{
 if(x==array[k]) break;
 if(k==7)
 cout<<"没有找到";
}

1. 2 二分查找

 当被查找的数组很大,要查找的元素又靠近数组的尾端,或在数组中根本不存在,则查找的时间就可能会很长。
 二分查找的思想是:(先将待查数组排序好)
  (1)首先在整个表中查找中间元素;
  (2)根据这个元素的值确定下一步将在哪半边进行查找,将查找范围缩小一半,继续用同样的方法查找。
 注:要实现这种查找方法,需要记录两个下标值,分别表示要被搜索范围的两个端点的下标值。这两个值分别存储于变量low和high中,表示左边界和右边界。开始时,搜索范围覆盖整个数组,而随着查找的继续进行,搜索区间将逐渐缩小,直到元素被找到。如果最后两个下标值交叉了,那么表示所要查找的值不在数组中。

//二分查找
#include<iostream>
using namespace std;
int main()
{
 int low,high,,mid,x;
 int array[]={0,1,2,3,4,5,6,7,8,9};
 cout<<"请输入要查找的数据"; cin>>x;
 low=0;high=9;

 while(low<high)  //只要查找区间存在,基于哨兵的循环
  {
  mid=(low+high)/2;          //计算中间位置
  if(x==array[mid]) break;   //找到了
  if(x<array[mid]) 
   {
      high=mid-1;
   }                    //修改查找区间
   else      
   {
      low=mid+1;   
   }
   if(low>high)
      cout<<"没有找到"<<endl;
   else
      cout<<x<<"的位置是:"<<mid<<endl;
  }

   return 0
}

1.3 顺序查找vs二分查找

对于n个数据元素的数组,假如都是最坏结果–都要查找到最后一步,顺序查找法要查找n次,而二分查找只需要查找log2(n)次。

n 10 100 1000 1 000 000 1 000 000 000
log2(n) 3 7 10 20 30

2.排序

上边提到使用二分查找之前,需要先将数组按次序排序。常用的排序方法很多,如插入排序、选择排序、交换排序

2.1 直接选择排序法

  (1)在所有元素中找到最小的元素放在数组的第0个位置;
  (2)在剩余元素中找到最小的元素放在素组的第1个位置,以此类推,知道所有元素都放在适当的位置。
注:找出第一个元素要比较n次,找出第二个元素比较n-1次,…,找出第n个元素比较一次。因此,总的比较次数为:
1 + 2 + 3 + … + n = n ( n + 1 ) / 2则称时间复杂性为O(n2)
这里写图片描述

//直接选择排序
#include <iostream>
using namespace std;

int main( )
{
    int lh, rh, k, tmp;
    int array[ ] = {2, 5, 1, 9, 10, 0, 4, 8, 7, 6};

    for (lh = 0; lh < 10; ++lh)   {         // 依次将正确的元素放入array[lh]
        rh = lh;
        for (k = lh; k < 10; ++k)           // 找出从lh到最后一个元素中的最小元素的下标rh
            if ( array[k] < array[rh] )   rh = k;
        tmp = array[lh];                    //交换lh和rh的值
        array[lh] = array[rh];
        array[rh] = tmp;  
    }

    for (lh =0; lh<10; ++lh)  cout << array[lh] << ' ';

    return 0;
}

2.2冒泡排序

 冒泡排序适合原先数据就是比较有序的数组元素。
 总结如下:排序n个元素,需要进行n-1次起泡,这个n-1次起泡过程可以用一个1到n-1的for循环来控制。第i次起泡的结果是将第i大的元素交换到第n-i号单元,而第n-i单元在数组中存放在第n-i-1位置中。第i次起泡就是检查下标0到n-i-1的元素,如果这个元素和它后边的元素违反了排序要求,则交换这两个元素。这个过程可以用一个从0到n-i-1的for循环来实现。所以整个冒泡排序就是一个两层嵌套的for循环。

#include <iostream>
using namespace std;

int main()
{
    int a[11] = { 0, 3, 5, 1, 8, 7, 9, 4, 2, 10, 6};//11个元素需要10次冒泡
    int i, j, tmp;
    bool flag; //记录一趟起泡中有没有发生过交换
    int n=11;
    for (i=1; i<n-1; i++) {    // 控制10次起泡,n-1次起泡过程
        flag = false;
        for (j=0; j<n-1-i; j++)  // 一次起泡过程
            if (a[j+1] < a[j])
                {tmp = a[j]; a[j] = a[j+1]; a[j+1] = tmp; flag = true;}
        if (!flag) break; //一趟起泡中没有发生交换,排序提前结束
    }

    cout << endl;
    for (i=0; i<n; ++i)  cout << a[i] << ' ';

    return 0;
}

猜你喜欢

转载自blog.csdn.net/wu_qz/article/details/80136742
今日推荐