8.6 查找和排序 Searching & Sorting Methods

Search Algorithm:从一个列表中寻找某个元素有没有。在哪。

8.6.1 查找算法

线性查找
linear search algorithm 概念:按照列表中每一项出现的顺序(从头到尾的顺序),逐一查找,直到找到或者查完列表为止。

优点 缺点
不必排序,从头到尾 但比较次数无法避免的多(N/2次)
如果被查找的在数组前面,将很快找到 但不适用于列表长度特别长的查找
#include 
#define TRUE 1
#define FALSE 0
#define NUMEL 10

int linearSearch (int [], int, int);//函数原型

int main()
{
  int nums[NUMEL] = {5,10,22,32,45,67,73,98,99,101};//10个元素的一维数组
  int item, location;

  printf("Enter the item you are searching for: ");
  scanf("%d", &item);

  location = linearSearch(nums, NUMEL, item);//函数调用,数组,项目个数,待查元素
  
  if (location > -1)//从数组0的位置开始
    printf("The item was found at index location %d\n",
                                              location);
  else
    printf("The item was not found in the list\n");

  return 0;
}

linearSearch(int list[], int size, int key)//函数首部行,参数:整形数组、整形项目个数
/* this function returns the location of key in the list,这个location在自建函数中是index */
/* a -1 is returned if the value is not found */
{
  int index, found, i;
  index = -1;
  found = FALSE;

  i = 0;
  while (i < size && !found)//在数组内逐一比较。满足条件时跳出
  {
    if (list[i] == key)
    {
      found = TRUE;//跳出。原条件!0,现在!1不满足循环
      index = i;//将查出来的位置赋给索引
    }
    i++; /* move to next item in the list */
  }
  return (index);
}

这里不完善,比如,列表中有重复的项目需要查找


折半查找
binary search algorithm 概念:先按序排列,与中部元素进行比较。1若等,则停。2若小,则出现在前半部。3若大,则出现在后半部。

优点 缺点
比linear search减少很多比较次数 需要在查找前排序
#include 
#define TRUE 1
#define FALSE 0
#define NUMEL 10

int binarySearch(int [], int, int);  //函数原型

int main()
{
  int nums[NUMEL] = {5,10,22,32,45,67,73,98,99,101};//升序,已经排好了
  int item, location;

  printf("Enter the item you are searching for: ");
  scanf("%d", &item);

  location = binarySearch(nums, NUMEL, item);

  if (location > -1)
    printf("The item was found at index location %d\n", location);
  else
    printf("The item was not found in the list\n");

  return 0;
}

int binarySearch(int list[], int size, int key)
/* this function returns the location of key in the list */
/* a -1 is returned if the value is not found */
{
  int index, found, left, right, midpt;

  index = -1;
  found = FALSE;
  left = 0;
  right = size -1;
  while (left <= right && !found)
  {
    midpt = (int) ((left + right) / 2);
    if (key == list[midpt])//当待查正好等于中点时,跳出。
    {
      found = TRUE;
      index = midpt;
    }
    else if (key > list[midpt])//否则,如果待查>中点。
      left = midpt + 1;//重置左点,中点+1,在后半部折半查找
    else//重置右点,中点-1,在前半部这般查找
      right = midpt - 1;
  }
  return (index);
}

这里不完善,比如,列表没排好顺序。


8.6.2 排序算法

Sort Algorithm:有两种主要的技术,内部排序,外部排序

internal sort:列表不是特大,能存在计算机内存中。比如:选择排序selection sort,冒泡排序bubble sort

external sort:列表存储在巨大的外部磁盘。比如:快速排序quicksort algorithm


选择排序
selection sort概念:先选出列表中最小的数值,与列表第一个元素交换。在新的列表中,选下一个最小的数值,与列表第二个元素交换。以此推到最后一个元素(最大的数值)。过程需要N-1次重复。

#include 
#define NUMEL 10

int selectionSort(int [], int);//函数原型

int main()
{
    int nums[NUMEL] = {22,5,67,98,45,32,101,99,73,10};//随机排序的列表
    int i, moves;
    
    moves = selectionSort(nums, NUMEL);//选择排序函数调用,总共移动了几次
    
    printf("The sorted list, in ascending order, is:\n");
    for (i = 0; i < NUMEL; i++)
        printf("%d ",nums[i]);//显示排序后新的数组
    printf("\n %d moves were made to sort this list\n", moves);//显示移动了几次
    
    return 0;
}

int selectionSort(int num[], int numel)
{
    int i, j, min, minidx, temp, moves = 0;
    
    for ( i = 0; i < (numel - 1); i++)
    {
        min = num[i]; //假设第一个元素是列表中最小的
        minidx = i; //最小数值的索引值
        for(j = i + 1; j < numel; j++)//从第二个开始循环
        {
            if (num[j] < min) //寻找列表中真实的最小数值
            {                 
                min = num[j];//把新的最小值赋给min
                minidx = j;//把新的最小值的位置赋值累索引值
            }
        }
        if (min < num[i]) //通过一个临时变量,交换两个元素的数值和位置
        {                 
            temp = num[i];//把元素存储在临时变量中
            num[i] = min;//把最小的赋值给这个元素
            num[minidx] = temp;//把临时变量赋值给被改变的数值
            moves++;
        }
    }
    return (moves);
}

冒泡排序
bubble sort概念:也叫交换排序。相邻两个元素按排序需求(升/降)比较大小,将最值置于最后端,依次。

#include 
#define NUMEL 10

int bubbleSort(int [], int);  /* function prototype */

int main()
{
  int nums[NUMEL] = {22,5,67,98,45,32,101,99,73,10};
  int i, moves;

  moves = bubbleSort(nums, NUMEL);

  printf("The sorted list, in ascending order, is:\n");
  for (i = 0; i < NUMEL; i++)
    printf("%d ",nums[i]);
  printf("\n %d moves were made to sort this list\n", moves);

  return 0;
}

int bubbleSort(int num[],int numel)
{
  int i, j, temp, moves = 0;

  for ( i = 0; i < (numel - 1); i++)
  {
    for(j = 1; j < numel; j++)
    {
      if (num[j] < num[j-1])
      {
        temp = num[j];
        num[j] = num[j-1];
        num[j-1] = temp;
        moves++;
      }
    }
  }
  return (moves);
}

选择和冒泡的缺点:应用于大列表,速度慢。


快速排序
quicksort概念:也叫划分排序。将一个列表分为两个更小的子列表,通过划分为更小的字列表排序每个子列表,依次类推。

找一个支点,第一次划分,把大于它的都放到他右边,小于的都放到左边。

再按此方法,对左右分别依次排序。

#include 
#define NUMEL 7

int main()
{
  int nums[NUMEL] = {67,32,45,73,98,101,99};
  int i;
  void quicksort(int [], int, int);

  quicksort(nums, 0, NUMEL-1);

  printf("The sorted list, in ascending order, is:\n");
  for (i = 0; i < NUMEL; i++)
    printf("%d  ",nums[i]);
  printf("\n");
  
  return 0;
}

void quicksort(int num[], int lower, int upper)
{
  int pivot;
  int partition(int [], int, int);

  pivot = partition(num, lower, upper);

  if (lower < pivot)
    quicksort(num, lower, pivot - 1);
  if (upper > pivot)
    quicksort(num, pivot + 1, upper);
  return;
}

int partition(int num[], int left, int right)
{
  int pivot, temp;

  pivot = num[left];  /* "capture" the pivot value, which frees up one slot */
  while (left < right)
  {
    /* scan from right to left */
    while(num[right] >= pivot && left < right)  /* skip over larger or equal values */
      right--;
    if (right != left)
    {
      num[left] = num[right];   /* move the higher value into the available slot */
      left++;
    }
    /* scan from left to right */
    while (num[left] <= pivot && left < right) /* skip over smaller or equal values */
      left++;
    if (right != left)
    {
      num[right] = num[left];  /* move lower value into the available slot */
      right-- ;
    }
  }
  num[left] = pivot;  /* move pivot into correct position */
  return(left);       /* return the pivot index */
}

伪代码
Linear Search:

Set a "found" flag to FALSE
Set an index value to -1
Begin with the first item in the list
While there are still inters in the list AND the "found" flag is FALSE
  Compare the item with the desired item
  If the item was found
    Set the "found" flag to TRUE
    Set the index value to the item's position in the list
  EndIf
EndWhile
Return the index value

Binary Search:

Set an index value to -1
Set a "found" flag to FALSE
Set the lower index to 0
Set the upper index to one less than the size of the list
Begin with the first item in the list
While the lower index is less than or equal to the upper index and a match is not yet found
  Set the midpoint index to the integer average of the lower and upper index values
  Compare the desired item to the midpoint element
  If the desired element equals the midpoint element
    the item has been found
  Else if the desired element is greater than the midpoint element
    set the lower index value to the midpoint value plus 1
  Else if the desired element is less than the midpoint element
    set the upper index to the midpoint value less 1
  EndIf
EndWhile
Return the index value

The Selection Sort:

Set interchange count to zero
For each element in the list from first to next-to-last
  Find the smallest element from the current element being referenced to the last element by:
    Setting the minimum value equal to the current element
    Saving the index of the current element
    For each element in the list from the current element + 1 to the last element in the list
      If element[inner loop index] < minimum value
        Set the minimum value = element[inner loop index]
        Save the index of the tex found minimum value
      EndIf
    EndFor
    Swap the current value with the new minimum value
    Increment the interchange count
EndFor
Return the interchange count

An Bubble Sort:

Set interchange count to zero
For the first element in the list to one less than the last element
  For the second element in the list to the last element
    If num[j] < num[j - 1]
      Swap num[j] with num[j - 1]
      Increment interchange count
    EndIf
  EndFor
EndFor
Return interchange count

The Quicksort:

Set the pivot to the value of the first list element
Initialise the left index to the index of the first list element
Initialise the right index to the index of the last list element
While(left index < right index)
   While (right index element >= pivot && left < right)
    Decrement right index
  EndWhile
  If(right index != left index)
    Move the lower value into the slot indicated by the left index
    Increment the left index
  EndIf
  While(left index element <= pivot && left < right)
    Increment the left index
  EndWhile
  If right index != left index
    Move the higher value into the slot indicated by the right index
    Decrement the right index
  EndIf
EndWhile
Move the pivot into the slot indicated by the left(or right) index
Return the left(or right) index (the two are the same value at this pivot)

你可能感兴趣的:(8.6 查找和排序 Searching & Sorting Methods)