c语言5个常用的排序算法实例代码

所属分类: 软件编程 / C 语言 阅读数: 100
收藏 0 赞 0 分享

1.插入排序

基本思想:插入排序就是每一步都将一个待排数据按其大小插入到已经排序的数据中的适当位置,直到全部插入完毕。

void insertSort(vector<int>& nums)
{
  int k = 0;
  for (int i = 0; i < nums.size(); ++i)
  {
    int temp = nums[i];
    int j = i;
    for (; j > 0 && temp < nums[j-1]; --j)
      nums[j] = nums[j-1];
    nums[j] = temp;
  }
}

2.希尔排序

基本思想:先将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入排序。因为直接插入排序在元素基本有序的情况下(接近最好情况),效率是很高的,因此希尔排序在时间效率上比前两种方法有较大提高。

void shellSort(vector<int>& nums)
{
  for (int gap = nums.size() / 2; gap > 0; gap /= 2)
  {
    for (int i = gap; i < nums.size(); ++i)
    {
      int temp = nums[i];
      int j = i;
      for (; j >=gap && temp < nums[j-gap]; j -= gap)
        nums[j] = nums[j - gap];
      nums[j] = temp;
    }
  }
}

3.堆排序

用一句概括,堆排序就是一种改进的选择排序,改进的地方在于,每次做选择的时候,不单单把最大的数字选择出来,而且把排序过程中的一些操作进行了记录,这样在后续排序中可以利用,并且有分组的思想在里面,从而提高了排序效率,其效率为O(n*logn).

#include<stdio.h> 
int c=0;
/*heapadjust()函数的功能是实现从a[m]到a[n]的数据进行调整,使其满足大顶堆的特性*/
/*a[]是待处理的数组,m是起始坐标, n是终止坐标*/
void heapadjust(int a[], int m, int n) 
{
	int i, temp;
	temp=a[m];
	for (i=2*m;i<=n;i*=2)//从m的左孩子开始 
	{
		if(i+1<=n && a[i]<a[i+1])//如果左孩子小于右孩子,则将i++,这样i的值就是最大孩子的下标值 
		{
			i++;
		}
		if(a[i]<temp)//如果最大的孩子小于temp,则不做任何操作,退出循环;否则交换a[m]和a[i]的值,将最大值放到a[i]处 
		{
			break;
		}
		a[m]=a[i];
		m=i;
	}
	a[m]=temp;
}
void crtheap(int a[], int n)//初始化创建一个大顶堆 
{
	int i;
	for (i=n/2; i>0; i--)//n/2为最后一个双亲节点,依次向前建立大顶堆 
	{
		heapadjust(a, i, n);
	}
}
/*swap()函数的作用是将a[i]和a[j]互换*/
void swap(int a[], int i, int j) 
{
	int temp;
	temp=a[i];
	a[i]=a[j];
	a[j]=temp;
	c++;
}
void heapsort(int a[], int n) 
{
	int i;
	crtheap(a, n);
	for (i=n; i>1; i--) 
	{
		swap(a, 1, i);
		//将第一个数,也就是从a[1]到a[i]中的最大的数,放到a[i]的位置 
		heapadjust(a, 1, i-1);
		//对剩下的a[1]到a[i],再次进行堆排序,选出最大的值,放到a[1]的位置
	}
}
int main(void) 
{
	int i;
	int a[10]={-1,5,2,6,0,3,9,1,7,4};
	printf("排序前:");
	for (i=1;i<10;i++) 
	{
		printf("%d",a[i]);
	}
	heapsort(a, 9);
	printf("\n\n共交换数据%d次\n\n", c);
	printf("排序后:");
	for (i=1;i<10;i++) 
	{
		printf("%d",a[i]);
	}
	printf("\n\n\n");
	return 0;
}

4.归并排序

基本思想:归并排序是利用递归和分而治之的技术将数据序列划分成为越来越小的半子表,再对半子表排序,最后再用递归步骤将排好序的半子表合并成为越来越大的有序序列,归并排序包括两个步骤,分别为:

1)划分子表
2)合并半子表

刚好最近刷leetcode有道题用的归并排序:sort list

class Solution {
public:
 //归并排序
  ListNode* getMiddleOfList(ListNode* head)
  {
    ListNode* mid = head;
    ListNode* last = head;
    while (last->next!=NULL&&last->next->next!=NULL)
    {
      mid = mid->next;
      last = last->next->next;
    }
    return mid;
  }
  ListNode* sortList(ListNode* head) {
    if (head == NULL || head->next == NULL)return head;
    ListNode* mid = getMiddleOfList(head);
    ListNode* midnext = mid->next;
    mid->next = NULL;
    return mergeList(sortList(head), sortList(midnext));
  }
  ListNode* mergeList(ListNode* a, ListNode* b)
  {
    ListNode* res = new ListNode(-1);
    ListNode* cur = res;
    while (a != NULL&&b != NULL)
    {
      if (a->val < b->val)
      {
        cur->next = a;
        a = a->next;
      }
      else
      {
        cur->next = b;
        b = b->next;
      }
      cur = cur->next;
    }
    cur->next = a != NULL ? a : b;
    return res->next;
  }
};

5.快速排序

基本思想:先将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入排序。因为直接插入排序在元素基本有序的情况下(接近最好情况),效率是很高的,因此希尔排序在时间效率上比前两种方法有较大提高。

class sort {
public:
  int median3(vector<int>& nums, int left, int right)
  {
    int mid = (left + right) / 2;
    if (nums[left] > nums[mid])swap(nums[left], nums[mid]);
    if (nums[mid] > nums[right])swap(nums[mid], nums[right]);
    if (nums[left] > nums[mid])swap(nums[left], nums[mid]);

    swap(nums[mid], nums[left]);
    return nums[left];
  }
  void quickSort(vector<int>& nums, int i, int j)
  {
    if (i > j)return;
    int partition = median3(nums, i, j);
    int low = i+1, high = j;
    while (low < high)
    {
      while (nums[low] < partition)low++;     
      while (nums[high] > partition)high--;
      if (low < high)swap(nums[low], nums[high]);
      else
        break;
    }
    swap(nums[i], nums[high]);
    quickSort(nums, i, high - 1);
    quickSort(nums, high + 1, j);
  }
  void qs(vector<int>& nums)
  {
    quickSort(nums, 0, nums.size() - 1);
  }
};

总结

以上就是本文关于c语言5个常用的排序算法实例代码的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!

更多精彩内容其他人还在看

用标准c++实现string与各种类型之间的转换

这个类在头文件中定义, < sstream>库定义了三种类:istringstream、ostringstream和stringstream,分别用来进行流的输入、输出和输入输出操作。另外,每个类都有一个对应的宽字符集版本
收藏 0 赞 0 分享

C++如何通过ostringstream实现任意类型转string

再使用整型转string的时候感觉有点棘手,因为itoa不是标准C里面的,而且即便是有itoa,其他类型转string不是很方便。后来去网上找了一下,发现有一个好方法
收藏 0 赞 0 分享

C/C++指针小结

要搞清一个指针需要搞清指针的四方面的内容:指针的类型,指针所指向的类型,指针的值或者叫指针所指向的内存区,还有指针本身所占据的内存区
收藏 0 赞 0 分享

C++ 类的静态成员深入解析

在C++中类的静态成员变量和静态成员函数是个容易出错的地方,本文先通过几个例子来总结静态成员变量和成员函数使用规则,再给出一个实例来加深印象
收藏 0 赞 0 分享

C++类的静态成员初始化详细讲解

通常静态数据成员在类声明中声明,在包含类方法的文件中初始化.初始化时使用作用域操作符来指出静态成员所属的类.但如果静态成员是整型或是枚举型const,则可以在类声明中初始化
收藏 0 赞 0 分享

C++类静态成员与类静态成员函数详解

静态成员不可在类体内进行赋值,因为它是被所有该类的对象所共享的。你在一个对象里给它赋值,其他对象里的该成员也会发生变化。为了避免混乱,所以不可在类体内进行赋值
收藏 0 赞 0 分享

C++中的friend友元函数详细解析

友元可以是一个函数,该函数被称为友元函数;友元也可以是一个类,该类被称为友元类。友元函数的特点是能够访问类中的私有成员的非成员函数。友元函数从语法上看,它与普通函数一样,即在定义上和调用上与普通函数一样
收藏 0 赞 0 分享

static全局变量与普通的全局变量的区别详细解析

以下是对static全局变量与普通的全局变量的区别进行了详细的分析介绍,需要的朋友可以过来参考下,希望对大家有所帮助
收藏 0 赞 0 分享

C++ explicit关键字的应用方法详细讲解

C++ explicit关键字用来修饰类的构造函数,表明该构造函数是显式的,既然有"显式"那么必然就有"隐式",那么什么是显示而什么又是隐式的呢?下面就让我们一起来看看这方面的知识吧
收藏 0 赞 0 分享

教你5分钟轻松搞定内存字节对齐

随便google一下,人家就可以跟你解释的,一大堆的道理,我们没怎么多时间,讨论为何要对齐.直入主题,怎么判断内存对齐规则,sizeof的结果怎么来的,请牢记以下3条原则
收藏 0 赞 0 分享
查看更多