c++实现冒泡排序、快速排序、直接插入排序

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

//记录类
template<class key_type>
class Record
{
private:
	key_type key; //键值
public:
	Record(){}//构造函数
	void set_key(int k) { this->key = k; } //设置键值
	key_type get_key() { return this->key; } //获取键值
};

//排序类
class Sort : private Record<int> //继承类模板
{
private:
	void swap_ele(Record *arr, int first, int second); //交换元素
	int partition(Record *arr, int low, int high); //让元素移动到正确的位置
public:
	Sort(){} //构造函数
	void Menu(); //菜单
	void Insert_Sort(Record *arr, int num); //直接插入排序
	void Quick_Sort(Record *arr, int low, int high); //快速排序
	void Bubble_Sort(Record *arr, int num); //冒泡排序
};


//菜单
void Sort::Menu()
{
	cout << "**************************" << endl
		<< "**************************" << endl
		<< "1.直接插入排序" << endl
		<< "2.快速排序" << endl
		<< "3.冒泡排序" << endl
		<< "4.显示姓名" << endl
		<< "**************************" << endl;
}

//直接插入排序
void Sort::Insert_Sort(Record *arr, int num)
{
	//设置一个哨兵——用来交换
	Record *temp = new Record;
	int i = 0, j = 0;
	for (i = 1; i < num; i++)
	{
		//如果第1个元素小于第0个元素
		if (arr[i].get_key() < arr[i - 1].get_key())
		{
			//将第一个元素放入哨兵中
			*temp = arr[i]; 
			//元素后移
			for (j = i - 1;   j >= 0 && arr[j].get_key() > temp->get_key(); j--)
			{
				arr[j + 1] = arr[j];
			}
			//插入
			arr[j + 1] = *temp;
		}
	}

}



//交换元素(使用在快速排序中)
void Sort::swap_ele(Record *arr, int first, int second)
{
	Record *temp = new Record;
	*temp = arr[first];
	arr[first] = arr[second];
	arr[second] = *temp;
}

//让元素移动到正确的位置(使用在快速排序中)
int Sort::partition(Record *arr, int low, int high)
{
	//三数取中——找到一个合理的枢轴
	int mid = high / 2; //计算数组中间元素的下标

	if (arr[low].get_key() > arr[high].get_key())
	{
		this->swap_ele(arr, low, high);
	}
	if (arr[mid].get_key() > arr[high].get_key())
	{
		this->swap_ele(arr, mid, high);
	}
	if (arr[mid].get_key() > arr[low].get_key())
	{
		//使数组第一个下标low作为枢轴
		this->swap_ele(arr, mid, low);
	}
	//初始化枢轴记录
	int pivot_key = arr[low].get_key();
	//暂存枢轴记录
	Record* pivot_temp = new Record;
	pivot_temp->set_key(pivot_key);
	//从表的两端交替向中间扫描
	while (low < high)
	{
		while (low < high && arr[high].get_key() >= pivot_key)
		{
			high--;
		}
		arr[low] = arr[high]; //采用替换而不是交换
		//this->swap_ele(v, low, high);
		while (low < high && arr[low].get_key() <= pivot_key)
		{
			low++;
		}
		arr[high] = arr[low]; //采用替换而不是交换
		//this->swap_ele(v, high, low);
	}

	arr[low] = *pivot_temp;
	return low;
}

//快速排序
void Sort::Quick_Sort(Record *arr, int low, int high)
{
	int pivot = 0;
	if (low < high)
	{
		pivot = this->partition(arr, low, high);
		this->Quick_Sort(arr, low, pivot - 1);
		//low = pivot + 1; //尾递归
		this->Quick_Sort(arr, pivot + 1, high);
	}
}

//冒泡排序
void Sort::Bubble_Sort(Record *arr, int num)
{
	Record *temp = new Record;
	int i = 0, j = 0;
	bool flag = 1; //标志
	for (i = 0; i < num - 1 && flag; i++)
	{
		flag = 0; //每一趟都初始化为0,当一整趟走完都没有发生交换,则flag为0,表示整个序列有序,直接跳出循环
		for (j = num - 2; j >= i; j--)
		{
			if (arr[j].get_key() > arr[j + 1].get_key())
			{
				*temp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = *temp;
				flag = 1;
			}
		}
	}
}

//main函数
int main()
{

	int num;
	cout << "请输入要排序的序列个数:" << endl;
	cin >> num;
	Record<int> *arr = new Record<int>[num];
	int input;

	cout << "请输入序列:" << endl;
	for (int i = 0; i < num; i++)
	{
		cin >> input;
		arr[i].set_key(input);
	}


	//菜单选项
	int choice = 0;
	//Sort动态对象
	Sort *s = new Sort;
	//调用菜单
	s->Menu();
	//循环输入选项
	while (1)
	{
		cout << "**************************" << endl;
		cout << "请输入你的选择(输入选项外其他数字退出):" << endl;
		cin >> choice;
		switch (choice)
		{
		case 1:
			
			s->Insert_Sort(arr, num);
			cout << "直接插入排序的结果:" << endl;
			for (int i = 0; i < num; i++)
			{
				cout << arr[i].get_key() << "\t";
			}
			cout << endl;
			break;

		case 2:
			s->Quick_Sort(arr, 0, num - 1);
			cout << "快速排序的结果:" << endl;
			for (int i = 0; i < num; i++)
			{
				cout << arr[i].get_key() << "\t";
			}
			cout << endl;
			break;

		case 3:
			s->Bubble_Sort(arr, num);
			cout << "冒泡排序的结果:" << endl;
			for (int i = 0; i < num; i++)
			{
				cout << arr[i].get_key() << "\t";
			}
			cout << endl;
			break;

		case 4:
			cout << "计科6班——罗炳培" << endl;
			break;

		default:
			exit(0);
			break;
		}
	}

	return 0;
}
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值