数据结构 C++内排序

一.排序的基本概念

  1. 排序:
    使表中元素按关键字递增或递减有序排列。
  2. 内排序和外排序:
    ①内排序:排序过程中,整个表都放在内存中处理,排序时不涉及数据的内、外存交换。
    ②外排序:排序过程中要进行数据的内、外存交换。
  3. 排序的稳定性
    稳定:如果待排序的表中存在多个关键字相同的元素,经过排序后这些具有相同关键字的元素之间的相对次序保持不变。
    不稳定:具有相同关键字的元素之间的相对次序发生改变。

二.定义和初始化一个排序类

建立排序类

#include <iostream>
using namespace std;
#define MAX 100

class  RecType{
	public:
		int key;
		char data;
}; 

class MSort{
	public:
		MSort();
		~MSort();
		void input();
		void display();
		void insertSort();//直接插入排序
		void binInsertSort();//折半插入排序
		void shellSort(); //希尔排序
		void bubbleSort();//冒泡排序
		void quickSort();//快速排序
		void selectSort();//选择排序
		void heapSort(); //堆排序
		void mergeSort();//归并排序
	private:
		RecType* R;
		int length;
		void quickSort1(int s,int t);
		void sift(int low,int high);//将结点调整为堆 
		void mergePass2(int len);
		void merge2(int low,int mid,int high);
};

MSort::MSort(){
	R = new RecType[MAX];
	length = 0;
}

MSort::~MSort(){
	delete [] R;
}

输入和输出数据

void MSort::input(){
	int n,i;
	cout << "请输入元素个数(不超过100):";
	cin >> n;
	cout << endl;
	if(n<=0||n>100){
		cout << "输入个数有误!" << endl;
	}else{
		length = n;
		for(i=0;i<n;i++){
			RecType *t = new RecType();
			cout << "请输入元素和对应key值(用空格隔开):";
			cin >> t->data >> t->key;
			R[i] = *t; 
			cout << endl;
		}
	}
}

void MSort::display(){
	for(int i=0;i<length;i++){
		cout << R[i].data << " ";
	}
	cout << endl;
}

三.插入排序

(一)直接插入排序

void MSort::insertSort(){
	int i,j;
	RecType tmp;
	for(i=1;i<length;i++){
		if(R[i].key<R[i-1].key){
			tmp = R[i];
			j = i-1;
			do{
				R[j+1] = R[j];
				j--;
			}while(j>=0&&R[j].key>tmp.key);
			R[j+1] = tmp;
		}
	}
}

(二)折半插入排序

void MSort::binInsertSort(){
	int i,j,low,high,mid;
	RecType tmp;
	for(i=1;i<length;i++){
		if(R[i].key<R[i-1].key){
			tmp = R[i];
			low = 0;
			high = i-1;
			while(low<=high){
				mid = (low+high)/2;
				if(tmp.key<R[mid].key){
					high = mid-1;
				}else{
					low = mid+1;
				}
			}
			for(j=i-1;j>=high+1;j--){
				R[j+1] = R[j];
			}
			R[high+1] = tmp;
		}
	}
}

(三)希尔排序

void MSort::shellSort(){
	int i,j,d;
	RecType tmp;
	d = length/2;
	while(d>0){
		for(i=d;i<length;i++){
			tmp = R[i];
			j = i-d;
			while(j>=0 && tmp.key<R[j].key){
				R[j+d] = R[j];
				j = j-d;
			}
			R[j+d] = tmp;
		}
		d = d/2; 
	}
}

四.交换排序

(一)冒泡排序

void MSort::bubbleSort(){
	int i,j;
	bool exchange;
	RecType tmp;
	for(i=0;i<length-1;i++){
		exchange = false;
		for(j=length-1;j>i;j--){
			if(R[j].key < R[j-1].key){
				tmp = R[j];
				R[j] = R[j-1];
				R[j-1] = tmp;
				exchange = true;
			}
		}
		if(!exchange){
			return;
		}
	}
}

(二)快速排序

void MSort::quickSort(){
	quickSort1(0,length-1);
} 

void MSort::quickSort1(int s,int t){
	int i=s,j=t;
	RecType tmp;
	if(s<t){
		tmp = R[s];//用区间第一个作为基准 
		while(i!=j){//从两端交替向中间扫描,直至i=j为止 
			while(j>i && R[j].key>=tmp.key){
				j--;//从右向左扫描,找到第1个小于tmp.key的R[j] 
			}
			R[i] = R[j];
			while(i<j && R[i].key<=tmp.key){
				i++;//从左向右扫描,找到第1个大于tmp.key的R[j]
			}
			R[j] = R[i];
		}
		R[i] = tmp;
		quickSort1(s,i-1);//对左区间递归排序
		quickSort1(i+1,t);//对右区间递归排序 
	}
}

五.选择排序

(一)简单选择排序

void MSort::selectSort(){
	int i,j,min;
	RecType tmp;
	for(i=0;i<length-1;i++){
		min = i;
		for(j=i+1;j<length;j++){
			if(R[j].key<R[min].key){
				min = j;
			}
		}
		if(min!=i){
			tmp = R[i];
			R[i] = R[min];
			R[min] = tmp;
		}
	} 
}

(二)堆排序

void MSort::heapSort(){
	int i;
	RecType tmp;
	for(i=length/2;i>=1;i--){
		sift(i,length);
	}
	for(i=length;i>=2;i--){
		tmp = R[1];
		R[1] = R[i];
		R[i] = tmp;
		sift(1,i-1);
	}
}

void MSort::sift(int low,int high){//将结点调整为堆
	int i=low,j=2*i;
	RecType tmp=R[i];
	while(j<=high){
		if(j<high && R[j].key<R[j+1].key){
			j++;
		}
		if(tmp.key<R[j].key){
			R[i] = R[j];
			i = j;
			j = 2*i;
		}else{
			break;
		}
	}
	R[i] = tmp;
}

六.归并排序

void MSort::mergeSort(){//对R按递增进行二路归并算法
	int len;
	for(len=1;len<length;len=2*len){
		mergePass2(len);
	}
}

void MSort::mergePass2(int len){//对整个数据序列进行一趟归并
	int i;
	for(i=0;i+2*len-1<length;i=i+2*len){
		merge2(i,i+len-1,i+2*len-1);
	}
	if(i+len-1<length){
		merge2(i,i+len-1,length-1);
	}
}

void MSort::merge2(int low,int mid,int high){
//将R[low..mid]和R[mid+1..high]两个有序段二路归并为一个有序段R[low..high]
	RecType *R1 = new RecType[high-low+1];
	int i=low,j=mid+1,k=0;
	while(i<=mid && j<=high){
		if(R[i].key<R[j].key){
			R1[k] = R[i];
			i++;
			k++;
		}else{
			R1[k] = R[j];
			j++;
			k++;
		}
	}
	while(i<=mid){
		R1[k] = R[i];
		i++;
		k++;
	}
	while(j<=high){
		R1[k] = R[j];
		j++;
		k++;
	}
	for(k=0,i=low;i<=high;k++,i++){
		R[i] = R1[k];
	}
	delete [] R1;
}

七.各种排序算法的性能

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值