您的位置:首页 > 编程语言 > C语言/C++

几种基本的排序算法(选择排序,冒泡排序,快速排序,归并排序,希尔排序)C语言实现

2012-08-15 21:46 1356 查看
选择排序:每一趟从待排序的数据元素中选出最小(或最大)的一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。

选择排序是不稳定的排序方法。

/************************************************************

* 选择排序
* 参数:array为需要排序数的数组, num为数组的长度
************************************************************/
int select(int array[], int num)
{
  int i;
  int j;
  int temp;
  for(i = 0;i < num;i++){
    for(j = i+1;j < num; j++){
      if(array[i] > array[j]){
        temp = array[i];
        array[i] = array[j];
        array[j] = temp;
      }
    }
  }
  return 0;
}

冒泡排序(BubbleSort):依次比较相邻的两个数,将小数放在前面,大数放在后面。即在第一趟:首先比较第1个和第2个数,将小数放前,大数放后。

然后比较第2个数和第3个数,将小数放前,大数放后,如此继续,直至比较最后两个数,将小数放前,大数放后。至此第一趟结束,将最大的数放到了最后。

在第二趟:仍从第一对数开始比较(因为可能由于第2个数和第3个数的交换,使得第1个数不再小于第2个数),将小数放前,大数放后,

一直比较到倒数第二个数(倒数第一的位置上已经是最大的),第二趟结束,

在倒数第二的位置上得到一个新的最大数(其实在整个数列中是第二大的数)。如此下去,重复以上过程,直至最终完成排序。

是一种稳定的排序。
/************************************************************
* 冒泡排序
* 参数:array为需要排序数的数组, num为数组的长度
************************************************************/
int bubble(int array[], int num)
{
  int i;
  int j;
  int temp;
  for(i = 0; i < num; i++){
    for(j = 1; j < num-i; j++){
      if(array[j] < array[j-1]){
        temp = array[j];
        array[j] = array[j-1];
        array[j-1] = temp;
      }
    }
  }
  return 0;
}

快速排序:
1)设置两个变量I、J,排序开始的时候:I=0,J=N-1;

2)以第一个数组元素作为关键数据,赋值给key,即 key=A[0];

3)从J开始向前搜索,即由后开始向前搜索(J=J-1即J--),找到第一个小于key的值A[j],A[j]与A[i]交换;
4)从I开始向后搜索,即由前开始向后搜索(I=I+1即I++),找到第一个大于key的A[i],A[i]与A[j]交换;
5)重复第3、4、5步,直到 I=J; (3,4步是在程序中没找到时候j=j-1,i=i+1,直至找到为止。找到并交换的时候i, j指针位置不变。另外当i=j这过程一定正好是i+或j-完成的最后令循环结束。)
示例:待排序的数组A的值分别是:(初始关键数据:key=49) 注意关键key永远不变,永远是和key进行比较,无论在什么位置,最后的目的就是把key放在中间,小的放前面大的放后面。
是一种不稳定的排序
/****************************************************************
* 快速排序的排序函数
* 参数:array为需要排序数的数组, low为需要排序的数组的下限坐标,
* high为需要排序的数组的上限坐标
****************************************************************/
int q_sort(int array[], int low, int high)
{
  int temp;
  int key = array[low];
  while(low < high){
    while(low < high && array[high] >= key){
      high--;
    }

    temp = array[high];
    array[high] = array[low];
    array[low] = temp;

    while(low < high && array[low] < key){
      low++;
    }

    temp = array[high];
    array[high] = array[low];
    array[low] = temp;
  }
  return low;
}

/****************************************************************
* 快速排序的递归函数
* 参数:array为需要排序数的数组, low为需要排序的数组的下限坐标,
* high为需要排序的数组的上限坐标
****************************************************************/
int quick_sort(int array[], int low, int high)
{
  int n;
  if(low < high){
    n = q_sort(array, low, high);
    quick_sort(array, low, n);
    quick_sort(array, n+1, high);
  }
  return 0;
}

归并排序:

申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列

设定两个指针,最初位置分别为两个已经排序序列的起始位置
比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
重复步骤3直到某一指针达到序列尾
将另一序列剩下的所有元素直接复制到合并序列尾
是一种稳定的排序
/****************************************************************
* 归并排序的排序函数
* 参数:array为需要排序数的数组, low为需要排序的数组的下限坐标,
* high为需要排序的数组的上限坐标
****************************************************************/
int merge(int array[], int low, int high)
{
  int mid = (low+high)/2;
  int i;
  int l_start = low;
  int m_start = mid +1;
  int l_end = mid;
  int m_end = high;

  int *temp = (int*)malloc(sizeof(int) * (high - low + 1));

  for(i = 0;l_start <= l_end && m_start <= m_end; i++){
    if(array[l_start] <= array[m_start]){
      temp[i] = array[l_start++];
    }else{
      temp[i] = array[m_start++];
    }
  }

  if(l_start <= l_end){ /*把剩余部分拷贝到temp缓存中*/
    memcpy(temp + i, array + l_start, sizeof(int) * (l_end - l_start + 1));
  }

  if(m_start <= m_end){ /*把剩余部分拷贝到temp缓存中*/
    memcpy(temp + i, array + m_start, sizeof(int) * (m_end - m_start + 1));
  }

  memcpy(array + low, temp, (high - low + 1) * sizeof(int));
  free(temp);
  return 0;
}

/****************************************************************
* 归并排序的递归函数
* 参数:array为需要排序数的数组, low为需要排序的数组的下限坐标,
* high为需要排序的数组的上限坐标
****************************************************************/
int *merge_sort(int array[], int low, int high)
{
  int mid = (low + high)/2;
  if(low < high){
    merge_sort(array, low, mid);
    merge_sort(array, mid + 1, high);
    merge(array, low, high);
  }
  return array;
}

希尔排序:

先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成(n除以d1)个组。所有距离为d1的倍数的记录放在同一个组中。
先在各组内进行直接插入排序;然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量dt=1(dt<dt-l<…<d2<d1),
即所有记录放在同一组中进行直接插入排序为止。
是一种不稳定的排序
/************************************************************
* 希尔排序
* 参数:array为需要排序数的数组, num为数组的长度
************************************************************/
int shell_sort(int array[], int num)
{
  int i;
  int j;
  int temp;
  int k = num - 1;
  while(k > 0){
    k/=2;
    for(i = k; i < num; i++){
      temp = array[i];
      j = i - k;
      while(j >= 0 && temp < array[j]){
        array[j + k]=array[j];
        j = j - k;
      }
      array[j + k] = temp;
    }
  }
  return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐