排序的基本操作与应用

算法设计与分析

排序的基本操作与应用

排序的基本操作与应用
1.实验目的
(1)掌握常用的排序方法,并掌握用高级语言实现排序算法的方法;
(2)深刻理解排序的定义和各种排序方法的特点,并能加以灵活应用;
(3)了解各种方法的排序过程及其时间复杂度的分析方法。
2.实验内容
编写程序,可以由用户输入任意n个待排数据,并指定任一种排序算法,
运行显示出排序过程。需要实现的排序算法有:
(1)选择排序
(2)直接插入排序
(3)冒泡排序
(4)快速排序
(5)归并排序
(6)堆排序
(7)希尔排序

// cpp
#include <iostream>
using namespace std;
//输出
void show(int a[], int n)
{
	int i;
	for (i = 1; i < n; i++)
		cout << a[i] << " ";
	cout << endl;
}
//输入
int *InPut(int &m)
{
	cout << "请输入元素的个数:" << endl;
	cin >> m;
	int *a = new int[m + 1];
	cout << "请依次输入数据,并用空格隔开" << endl;
	for (int i = 1; i < m + 1; i++)
		cin >> a[i];
	return a;
}
//直接插入排序
void InsertSort(int a[], int n)
{
	int i, j;
	for (i = 2; i < n; i++)//截止到a[7]
	{
		if (a[i] < a[i - 1])
		{
			a[0] = a[i];
			a[i] = a[i - 1];
			for (j = i - 2; a[j] > a[0]; j--)
				a[j + 1] = a[j];
			a[j + 1] = a[0];
		}
		show(a, n);
	}
}
//折半插入排序
void BInsertSort(int a[], int n)
{
	int i, j;
	for (i = 2; i < n; i++)//截止到a[7]
	{
		if (a[i] < a[i - 1])
		{
			a[0] = a[i];
			int low = 1, high = i - 1, m;
			while (low <= high)
			{
				m = (low + high) / 2;
				if (a[0] < a[m])
					high = m - 1;
				else
					low = m + 1;
			}
			for (j = i - 1; j > high; j--)
				a[j + 1] = a[j];
			a[j + 1] = a[0];
		}
		show(a, n);
	}
}
//希尔排序
void ShellSort(int a[], int n)
{
	void ShellInsert(int a[], int d, int n);
	int d, i;
	d = n - 1;//增量数组为d[i]=d[i-1]/2
	for (i = 0; d > 1; i++)
	{
		d = d / 2;
		cout << "d:" << d << endl;
		ShellInsert(a, d, n);
	}
}
void ShellInsert(int a[], int d, int n)
{
	int i, j;
	for (i = d + 1; i < n; i++)
	{
		if (a[i] < a[i - d])
		{
			a[0] = a[i];
			for (j = i - d; j > 0 && a[0] < a[j]; j = j - d)
				a[j + d] = a[j];
			a[j + d] = a[0];//跳出循环时,j为负数,需加上增量d补正
		}
	}
	show(a, n);
}
//选择排序(打擂台)
void SelectSort(int a[], int n)
{
	void show(int a[], int n);
	int i, j, k;
	for (i = 1; i < n - 1; i++)//截止到a[6]
	{
		k = i;
		for (j = i + 1; j < n; j++)//截止到a[7]
			if (a[j] < a[k])
				k = j;
		if (k != i)
		{
			a[0] = a[i];
			a[i] = a[k];
			a[k] = a[0];
		}
		show(a, n);
	}
}
//冒泡排序
void BubbleSort_flag(int a[], int n)
{
	bool flag = 1;
	int i = 1, j;
	while (i < n - 1 && flag == 1)
	{
		flag = 0;
		for (j = 1; j < n - i; j++)
			if (a[j] > a[j + 1])
			{
				flag = 1;
				a[0] = a[j];
				a[j] = a[j + 1];
				a[j + 1] = a[0];
			}
		i++;
		cout << flag << ": ";
		show(a, n);
	}
}
//冒泡排序
void BubbleSort_last(int a[], int n)
{
	int i = n - 1, j, last;
	int s1 = 0, s2 = 0;
	while (i > 1)
	{
		last = 1;
		for (j = 1; j < i; j++)
		{
			s1++;
			if (a[j] > a[j + 1])
			{
				a[0] = a[j];
				a[j] = a[j + 1];
				a[j + 1] = a[0];
				s2++;
				last = j;
			}
		}
		i = last;
		show(a, n);
		cout << s1 << " " << s2 << endl;
	}
	//cout<<s1<<" "<<s2<<endl;
}

//快速排序
void QuickSort(int a[], int n)
{
	void QSort(int a[], int low, int high);
	QSort(a, 1, n - 1);
	show(a, n);
}
//递归
void QSort(int a[], int low, int high)
{
	int Partition(int a[], int low, int high);
	int pivotloc;
	if (low < high)
	{
		pivotloc = Partition(a, low, high);
		QSort(a, low, pivotloc - 1);
		QSort(a, pivotloc + 1, high);
	}
}
//划分调整
int Partition(int a[], int low, int high)
{
	int pivotkey;
	a[0] = a[low];
	pivotkey = a[low];
	while (low < high)
	{
		while (low < high && a[high] >= pivotkey)
			high--;
		a[low] = a[high];
		while (low < high && a[low] < pivotkey)
			low++;
		a[high] = a[low];
	}
	a[low] = a[0];
	//第一次返回a[1]的下标,将数组一分为二
	return low;
}
//归并排序,自上而下
void MergeSortDC(int a[], int n)
{
	void MSortDC(int a[], int low, int high);
	MSortDC(a, 1, n - 1);
	show(a, n);
}
//归并
void Merge(int a[], int low, int mid, int high)
{
	//a[low...mid]
	//a[mid+1...high]
	int i = low, j = mid + 1, k = 0;
	int *b = new int[high - low + 1];
	while (i <= mid && j <= high)
	{
		if (a[i] <= a[j])
			b[k++] = a[i++];
		else
			b[k++] = a[j++];
	}
	while (i <= mid)
		b[k++] = a[i++];
	while (j <= high)
		b[k++] = a[j++];
	for (k = 0, i = low; i <= high; k++, i++)
		a[i] = b[k];
}

//递归划分子表,越分越小,破而后立,先拆后并
void MSortDC(int a[], int low, int high)
{
	int mid;
	if (low < high)
	{
		mid = (low + high) / 2;
		MSortDC(a, low, mid);
		MSortDC(a, mid + 1, high);
		Merge(a, low, mid, high);
	}
}

//从单个元素开始,直接归并,子表逐渐倍增
void MSortBU(int a[], int n)
{
	int i, length;
	for (length = 1; length < n; length = 2 * length)
	{
		for (i = 1; i < n; i = 2 * length + i)
		{
			if ((2 * length + i - 1) < n)
				Merge(a, i, length + i - 1, 2 * length + i - 1);
			else
				Merge(a, i, length + i - 1, n);
		}
		show(a, n + 1);
	}
}

//归并排序,自下而上
void MergeSortBU(int a[], int n)
{
	MSortBU(a, n - 1);
}

//筛选法调整堆
//s为下标,尚未确定位置的根结点下标
void HeapAdjust(int a[], int s, int m)
{
	a[0] = a[s];
	int j;
	for (j = 2 * s; j <= m; j = j * 2)
	{//排序时,m的值会依次减小,需防止越界
		if (j < m && a[j] < a[j + 1])
			j++;
		if (a[0] >= a[j])
			break;
		a[s] = a[j];
		s = j;
	}
	a[s] = a[0];
}
//初建堆
void GreatHeap(int a[], int n)
{
	int i;
	for (i = n / 2; i > 0; i--)
		HeapAdjust(a, i, n);
	cout << "初建堆" << endl;
	show(a, n + 1);
}

//堆排序
void HeapSort(int a[], int n)
{
	GreatHeap(a, n - 1);
	cout << "过程:" << endl;
	int i;
	for (i = n - 1; i > 1; i--)
	{
		a[0] = a[1];
		a[1] = a[i];
		a[i] = a[0];
		HeapAdjust(a, 1, i - 1);
		show(a, n);
	}
}






//默认测试
int* A()
{
	int *a = new int[8];
	a[1] = 6, a[2] = 2, a[3] = 7, a[4] = 1, a[5] = 5, a[6] = 3, a[7] = 4;
	show(a, 8);
	return a;
}
//默认测试
int* B()
{
	int *b = new int[8];
	b[1] = 4, b[2] = 2, b[3] = 1, b[4] = 3, b[5] = 5, b[6] = 7, b[7] = 8;
	show(b, 8);
	return b;
}

int main()
{
	SelectSort(A(), 8);
	cout << "直接插入排序:" << endl;
	InsertSort(A(), 8);
	cout << "\n冒泡排序flag:" << endl;
	BubbleSort_flag(A(), 8);
	cout << "\n冒泡排序last:" << endl;
	BubbleSort_last(B(), 8);
	cout << "\n快速排序:" << endl;
	QuickSort(A(), 8);
	cout << "\n归并排序自上而下:" << endl;
	MergeSortDC(A(), 8);
	cout << "\n归并排序自下而上:" << endl;
	MergeSortBU(A(), 8);
	cout << "\n堆排序:" << endl;
	HeapSort(A(), 8);
	cout << "\n希尔排序:" << endl;
	ShellSort(A(), 8);
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值