C++实现8种排序算法(直接上代码)

2023-03-24 10:04:07 3064人已围观 39已点赞 14人已收藏

简介本文介绍C++实现C++实现8种排序算法,主要包括冒泡排序、插入排序、二分插入排序、希尔排序、直接选择排序、堆排序、归并排序、快速排序,直接上代码,感兴趣的朋友可以参考一下。

冒泡排序(n 2

/////////////////////////////////////////////
// 
// 冒泡排序 v1.0
// arr    整型数组指针
// n      数组长度
/////////////////////////////////////////////
template <class T>
void BubbleSort(T* arr, int n)
{
	for (int i = 0; i < n; ++i)
	{
		for (int j = 0; j < n - 1 - i; ++j)
		{
			if (arr[j] > arr[j + 1])
			{
				int temp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = temp;
			}
		}
	}
}
/////////////////////////////////////////////
// 
// 冒泡排序	 v2.0
// arr   整型数组指针
// n     数组长度
/////////////////////////////////////////////
template <class T>
void BubbleSort(T* arr, int n)
{
	int bFlag = false;
	for (int i = 0; i < n; ++i)
	{
		for (int j = 0; j < n - 1 - i; ++j)
		{
			// 交换数据
			if (arr[j] > arr[j + 1])
			{
				int temp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = temp;
				bFlag = true;
			}
		}
		if (bFlag == false)	 // 无交换直接跳出
		{
			break;
		}
	}
}

备注:对于最坏情况,该改进和未改进差不多。

插入排序(n 2

/////////////////////////////////////////////
// 
// 直接插入排序
// 基本思想:每次将一个待排序的记录,按其关键字大小插入到前面已经排好序的子序列中的适当位置,直到全部记录插入完成为止。
// a      int*    整型数组指针
// N      int     数组长度
/////////////////////////////////////////////
void InsertSort(int *a, int N)
{
	int i = 0;
	int j = 0;

	for (int i = 1; i < N; i++)
		if (a[i] < a[i - 1])
		{
			int temp = a[i];
			for (j = i - 1; j >= 0 && a[j] > temp; j--)
				a[j + 1] = a[j]; // 把比temp大或相等的元素全部往后移动一个位置
			a[j + 1] = temp;
		}
}

二分插入排序(nlog 2 n)

/////////////////////////////////////////////
// 
// 二分插入排序
// 基本思想:基于插入排序,在查找插入位置时采用二分查找法。
// A       int*    整型数组指针
// length  int     数组长度
/////////////////////////////////////////////
void BinInsertSort(int* A, int length)
{
	int middle = 0;
	int left = 0;
	int right = 0;

	for (int i = 1; i<length; i++)       // 从第2个元素开始
	{
		int insertNum = A[i];	

		// 将有序区作为查找范围
		left = 0;
		right = i - 1; 

		// 二分查找
		while (left <= right)
		{
			// 依次取查找范围的中间位置
			middle = (left + right) / 2;
			if (insertNum<A[middle])
				right = middle - 1;// 在前半区查找
			else 
				left = middle + 1; // 在后半区查找
		}

		// 移动元素, 空出要插入的位置
		for (int j = i - 1; j >= left; j--)   
			A[j + 1] = A[j];
		// 将当前元素插入适当位置
		A[left] = insertNum;
	}
}

希尔排序

/////////////////////////////////////////////
// 
// 希尔排序  
// a    整型数组指针
// n    数组长度
/////////////////////////////////////////////
void ShellSort(int* a, int n)
{
	int i = 0;
	int j = 0;
	int x = 0;
	int gap = n / 2;
	while (gap >= 1) // 循环至增量为1时结束 
	{
		for (i = gap; i<n; i++)
		{
			x = a[i]; // 获取序列中的下一个数据 
			j = i - gap; // 序列中前一个数据的序号 
			while (j >= 0 && a[j]>x) // 下一个数大于前一个数 
			{
				a[j + gap] = a[j]; // 将后一个数向前移动 
				j = j - gap; // 修改序号,继续向前比较 
			}
			a[j + gap] = x; // 保存数据 
		}
		gap /= 2;  // 缩小增量 
	}
}

直接选择排序(n 2

/////////////////////////////////////////////
// 
// 直接选择排序  
// a    整型数组指针
// n    数组长度
/////////////////////////////////////////////
void SelectSort(int* a, int n)
{
	int i, j, t, k;
	for (i = 0; i<n - 1; i++)
	{
		k = i;
		for (j = i + 1; j<n; j++)
			if (a[k]>a[j]) k = j;
		t = a[i];
		a[i] = a[k];
		a[k] = t;
	}
}

直接选择排序适合在移动成本高,比较成本低的场景。

不稳定,元素的位置可能会改变。

堆排序

void HeapAdjust(int a[],int s,int n)//构成堆
{
    int j,t;
    while(2*s+1<n) //第s个结点有右子树 
    {
        j=2*s+1 ;
        if((j+1)<n)
        {            
            if(a[j]<a[j+1])//右左子树小于右子树,则需要比较右子树
                j++; //序号增加1,指向右子树 
        }
        if(a[s]<a[j])//比较s与j为序号的数据
        {            
            t=a[s];  //交换数据 
            a[s]=a[j];
            a[j]=t;            
            s=j ;//堆被破坏,需要重新调整
        }
        else //比较左右孩子均大则堆未破坏,不再需要调整
            break;
    }
}
void HeapSort(int a[],int n)//堆排序
{
    int t,i;
    int j;
    for(i=n/2-1;i>=0;i--)    //将a[0,n-1]建成大根堆
        HeapAdjust(a, i, n);
    for(i=n-1;i>0;i--)
    {
        t=a[0];//与第i个记录交换
        a[0] =a[i];
        a[i] =t;
        HeapAdjust(a,0,i);        //将a[0]至a[i]重新调整为堆
    }  
}

归并排序

void MergeStep(int a[],int r[],int s,int m,int n) //相邻有序段合并 
{
    int i,j,k;
    k=s;
    i=s;
    j=m+1;
    while(i<=m && j<=n) //当两个有序表都未结束时,循环比较 
    {
        if(a[i]<=a[j]) //当较小的元素复制到R中 
            r[k++]=a[i++];
        else
            r[k++]=a[j++];
    }
    while(i<=m) //将未合并的部分复制到R中 
        r[k++]=a[i++];
    while(j<=n)
        r[k++]=a[j++]; //将未合并的部分复制到R中 
}
void MergePass(int a[],int r[],int n,int len) //完成一遍合并的函数 
{
    int s,e;
    s=0;
    while(s+len<n) //至少有两个有序段 
    {
        e=s+2*len-1;
        if(e>=n) //最后一段可能少于len个结点 
            e=n-1;
        MergeStep(a,r,s,s+len-1,e); //相邻有序段合并 
        s=e+1; //下一对有序段中左段的开始下标 
    }
    if(s<n) //还剩一个有序段,将其从A中复制到R中 
        for(;s<n;s++)
            r[s]=a[s];
}
void MergeSort(int a[],int n)
{
    int *p;
    int len=1;     //有序序列的长度 
    int f=0;	//变量f作标志
    if(!(p=(int *)malloc(sizeof(int)*n)))	//分配内存空间,保存临时数据
    {
        printf("分配临时内存失败!\n");
        exit(0); 
    }
    while(len<n)
    {
        if(f)   //交替地在A和P之间来回合并 
            MergePass(p,a,n,len);	//调用MergePass,对p合并到a
        else
            MergePass(a,p,n,len);	//调用MergePass,对a合并到p
        len*=2;	//增加有序序列长度
        f=1-f; //使f值在0和1之间切换 
    }
    if(f)	//若进行了排序
        for(f=0;f<n;f++)	//将数组p中的数据复制到数组a
            a[f]=p[f];
    free(p); //释放分配的内存 
}

快速排序

int Division(int a[],int left, int right) //分割 
{
    int base=a[left];    //基准元素
    while(left<right)
    {
        while(left<right && a[right]>base)
            --right;     //从右向左找第一个比基准小的元素
        a[left]=a[right];
        while(left<right && a[left]<base )
            ++left;      //从左向右找第一个比基准大的元素
        a[right]=a[left];
    }
    a[left]=base;
    return left;
}
void QuickSort(int a[],int left,int right)
{
    int i,j;
    if(left<right)
    {
        i=Division(a,left,right);   //分割
        QuickSort(a,left,i-1);     //将两部分分别排序
        QuickSort(a,i+1,right);
    }
}

测试示例代码

#include <ctime>
#include <iostream>
using namespace std;

/////////////////////////////////////////////
// 
// 获取随机数
// min    最小值
// max    最大值
/////////////////////////////////////////////
int GetRandom(int min, int max)
{
	return (rand() % static_cast<int>(max + 1 - min)) + min;
}
int _tmain(int argc, _TCHAR* argv[])
{
	const int nMax = 1000;
	int Data[nMax];
	srand((unsigned)time(NULL)); // 设置种子

	for (int n = 0; n < nMax; ++n)
	{
		Data[n] = rand();
	}


	//BubbleSort<int>(Data, nMax);
	InsertSort(Data, nMax);


	for (int n = 0; n < nMax; ++n)
	{
		cout << Data[n] << " ";
	}

	system("pause");
	return 0;
}


更多为你推荐