排序算法

3 篇文章 0 订阅
2 篇文章 0 订阅

排序动态过程可参考网站:Visualgo

插入排序算法1:直接插入排序

//直接插入排序算法的实现
#include<iostream>
using namespace std;

void InsertSort(int *a, int len)
{
	for (int i = 1; i < len; i++)
	{
		int j = i - 1;//j记录在要插入元素之前还有几个待比较元素
		int x = a[i];//先把要插入元素的值保存下来
		while (j>-1 && x < a[j])//要插入元素逐个与在它位置之前的元素比较
		{
			a[j + 1] = a[j];
			j--;
		}
		a[j + 1] = x;
	}
}

int main()
{
	//测试样例
	int a[8] = { 3, 1, 7, 5, 2, 4, 9, 6 };
	int len = sizeof(a) / sizeof(int);//计算数组size
	InsertSort(a, len);
	for (int i = 0; i < len; i++)
		cout << a[i];
	cout << endl;
	system("pause");
	return 0;
}

直接插入排序算法的时间复杂度为O(n2)

插入算法2:希尔排序

希尔排序的具体实现思路是:先将整个记录表分割成若干部分,分别进行直接插入排序,然后再对整个记录表进行一次直接插入排序。

一般在记录的数量多的情况下,希尔排序的排序效率较直接插入排序高。

//希尔排序
#include<iostream>
using namespace std;
#define SIZE 15

struct SqNode{
	int key;
};

struct Sqlist{
	SqNode r[SIZE];
	int length;
};

void ShellInsert(Sqlist *L, int dk)
{
	for (int i = dk + 1; i <= L->length; i++)
	{
		if (L->r[i].key < L->r[i - dk].key)
		{
			int j;
			L->r[0] = L->r[i];
			for (j = i - dk; j>0 &&( L->r[i].key < L->r[j].key); j -= dk)
			{
				L->r[j + dk] = L->r[j];
			}
			L->r[j + dk] = L->r[0];
		}
	}
}

void ShellSort(Sqlist *L, int dk[], int n)
{
	for (int i = 0; i < n; i++)
	{
		ShellInsert(L, dk[i]);
	}
}

int main()
{
	Sqlist *L = new Sqlist;
	L->r[1].key = 49;
	L->r[2].key = 38;
	L->r[3].key = 64;
	L->r[4].key = 97;
	L->r[5].key = 76;
	L->r[6].key = 13;
	L->r[7].key = 27;
	L->r[8].key = 49;
	L->r[9].key = 55;
	L->r[10].key = 4;
	L->length = 10;

	int delta[] = { 5, 3, 1 };//最后一次的间隔必须是1,表示对整张表进行一次插入排序
	ShellSort(L, delta, 3);
	
	for (int i = 1; i <= L->length; i++)
	{
		cout << L->r[i].key<<" ";
	}
	cout << endl;

	system("pause");
	return 0;
}

冒泡排序

如果是升序排序,则是通过一趟趟冒泡,每次相邻的元素两两比较并将最大的值冒到最后,没冒到最后的最大值将不参与下次的冒泡比较

冒泡排序法的时间复杂度和表中元素的顺序有关,如果记录为正序,则只需比较n-1次且不需要移动元素位置即可完成,若为降序,则是最坏的时间复杂度,每个元素冒一趟,每趟比较次数分别为:n-1,n-2,...1,0,时间复杂度为:O(n*(n-1)/2)即O(n2)

//冒泡排序
#include<iostream>
using namespace std;

//void swap(int &x, int &y)//引用交换
//{
//	int temp = x;
//	x = y;
//	y = temp;
//}
//void swap(int *x, int *y)//指针交换
//{
//	int temp = *x;
//	*x = *y;
//	*y = temp;
//}

int main()
{
	int arr[] = { 49, 38, 65, 97, 76, 13, 27, 49 };
	int len = sizeof(arr) / sizeof(int);
	for (int i = 0; i < len; i++)
		for (int j = 0; j + 1 < len - i;j++)
		{
			if (arr[j] > arr[j + 1])
				swap(arr[j], arr[j + 1]);//即使自己不定义swap()函数,C++有自己内嵌的函数可以调用
				/*swap(&arr[j], &arr[j + 1]);*/
		}
	for (int m = 0; m < len; m++)
		cout << arr[m] << " ";
	cout << endl;

	system("pause");
	return 0;

}

快速排序法

快速排序算法的时间复杂度为O(nlogn),是所有时间复杂度相同的排序方法中性能最好的排序算法。

//快速排序法
#include<iostream>
using namespace std;
#define MAX 12

struct SqNode{
	int key;
};

struct Sqlist{
	SqNode r[MAX];
	int length;
};

int QSort(Sqlist *L, int low, int high)//这只是一次的快排
{
	L->r[0] = L->r[low];
	int pivot = L->r[low].key;
	while (low < high)
	{
		while (low<high&&L->r[high].key >= pivot)
		{
			high--;
		}
		L->r[low] = L->r[high];
		while (low < high&&L->r[low].key <= pivot)
		{
			low++;
		}
		L->r[high] = L->r[low];
	}
	L->r[low] = L->r[0];
	return low;
}

void QuickSort(Sqlist *L, int low, int high)
{
	if (low < high)
	{
		int pivotloc;
		pivotloc=QSort(L, low, high);
		QuickSort(L, low, pivotloc - 1);//递归
		QuickSort(L, pivotloc + 1, high);//递归
	}
}

int main()
{
	Sqlist *L = new Sqlist;
	L->r[1].key = 49;
	L->r[2].key = 38;
	L->r[3].key = 65;
	L->r[4].key = 97;
	L->r[5].key = 76;
	L->r[6].key = 13;
	L->r[7].key = 27;
	L->r[8].key = 49;
	L->r[9].key = 9;
	L->r[10].key = 3;
	L->r[11].key = 100;
	L->length = 12;

	int low = 1;
	int high = L->length - 1;
	QuickSort(L, low, high);
	for (int i = 1; i < L->length; i++)
		cout << L->r[i].key << " ";
	cout << endl;

	system("pause");
	return 0;
}

选择排序算法1:简单排序算法

//选择排序法1:简单选择排序
//从小到大排序
//遍历n-1,每次把表中最小的值与前面位置的值交换位置

#include<iostream>
using namespace std;

void SelectSort(int *a,int len)
{
	
	for (int i = 0; i < len-1; i++)
	{
		int min_value = a[i];
		int index = i;
		for (int j = i + 1; j < len; j++)
		{
			if (min_value > a[j]){
				min_value = a[j];
				index = j;
			}
				
		}
		swap(a[i], a[index]);
	}
}

int main()
{
	int a[5] = { 56, 12, 80, 91, 20 };
	int len = sizeof(a) / sizeof(int);
	SelectSort(a, len);
	for (int i = 0; i < len; i++)
		cout << a[i] << " ";
	cout << endl;
	system("pause");
	return 0;
}

堆排序

堆排序在最坏的情况下,其时间复杂度仍为O(nlogn)。这是相对于快速排序的优点所在。

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#define MAX 9
//单个记录的结构体
typedef struct {
	int key;
}SqNote;
//记录表的结构体
typedef struct {
	SqNote r[MAX];
	int length;
}SqList;
//将以 r[s]为根结点的子树构成堆,堆中每个根结点的值都比其孩子结点的值大

void swap(SqNote *a, SqNote *b)
{
	int temp = a->key;
	a->key = b->key;
	b->key = temp;
}

void HeapAdjust(SqList *L, int s, int m)
{
	SqNote rc = L->r[s];
	for (int j = 2 * s; j <= m; j *= 2)
	{
		if (j + 1 <= m&&L->r[j].key<L->r[j+1].key)
		{
			j++;
		}
		if (rc.key>L->r[j].key)
		{
			break;
		}
		L->r[s].key = L->r[j].key;
		s = j;
	}
	L->r[s] = rc;

}

void HeapSort(SqList *L)
{
	for (int i = L->length / 2; i > 0; i--)
	{
		HeapAdjust(L, i, L->length);
	}
	for (int n = L->length; n >1; n--)
	{
		swap(&L->r[1], &L->r[n]);//交换之后,只有根节点不是按堆排的
		HeapAdjust(L, 1, n - 1);//所以这只重排根节点即可
	}
}

int main() {
	SqList * L = (SqList*)malloc(sizeof(SqList));
	L->length = 8;
	L->r[1].key = 49;
	L->r[2].key = 38;
	L->r[3].key = 65;
	L->r[4].key = 97;
	L->r[5].key = 76;
	L->r[6].key = 13;
	L->r[7].key = 27;
	L->r[8].key = 49;
	HeapSort(L);
	for (int i = 1; i <= L->length; i++) {
		printf("%d ", L->r[i].key);
	}
	std::cout << std::endl;
	system("pause");
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值