数据结构课程设计源码---综合排序

头文件:

#include <iostream>

//1插入类的排序: 
//希尔排序:取增量d1的分为一组,共分成d1组分别进行插入排序,然后每组对应元素放在一起,然后取d2...知道d=1 
//希尔排序的代码可以近乎看成把1换成dk
/*我们简单处理增量序列:增量序列d = {n/2 ,n/4, n/8 .....1} n为要排序数的个数
即:先将要排序的一组记录按某个增量d(n/2,n为要排序数的个数)分成若干组子序列,每组中记录的下标相差d.对每组中全部
元素进行直接插入排序,然后再用一个较小的增量(d/2)对它进行分组,在每组中再进行直接插入排序。继续不断缩小增量直至
为1,最后使用直接插入排序完成排序。*/
//时间复杂度 O(n^3/2)  不稳定 
void ShellSort(int a[], int n){
	int i, j, dk;
	for(dk = n/2; dk > 0; dk /= 2){
		for(i = dk; i <= n; i++){
		if(a[i] < a[i-dk]){
			a[0] = a[i];
			for(j = i-dk; a[j]>a[0] && j>=0; j -= dk)
			a[j+dk] = a[j];
			a[j+dk] = a[0];
		}
	 }
  }		
}  
//直接插入排序:将第一个数据看成有序表,将后面的数据一次插入表中
//时间复杂度 O(n^2)  稳定 
void InsertSort(int a[], int n){
	int i, j;
	for(i = 1; i <= n; i++){
		if(a[i] < a[i-1]){ //若插入的第i个数大于它的前一个数i-1,就直接插入再最后,如果小于,就移动有序表插入
		a[0] = a[i]; //设置为哨兵,作用是用于暂时存放要插入的数
		for(j = i-1; a[j]>a[0] && j>=0; j--)//从要插入数i的前一个数i-1开始,若比i大,就后移一位 
		a[j+1] = a[j]; 
		a[j+1] = a[0]; //找到真确位置,将要插入数放在第j个数后面	
		}
	}
} 



//2归并类排序:
/*归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,
即把待排序序列分为若干个子序列,每个子序列是有序的。
然后再把有序子序列合并为整体有序序列。*/
 //时间复杂度 O(nlogn)  稳定 
//合并两个已经排好顺序的数组 
void Merge(int a[], int start, int mid, int end, int *temp){
	int i = start, j = mid+1, k = 0;//start到mid位数组1,mid+1到end为数组2
	while(i<=mid && j<=end)  //从两个数组最低位开始比较,数值小的存入临时数组
	      temp[k++] = (a[i] <= a[j]) ? a[i++] : a[j++];
	      while(i <= mid) //总有一个数组先比较完,所以处理剩下数组的元素
                temp[k++] = a[i++];
           while(j <= end)
                temp[k++] = a[j++];
            k = 0; //下面将排完序的临时数组里的数拷贝到原数组里 
            for(i = start; i <= end; i++)
			    a[i] = temp[k++]; 
} 
//用分治法进行二路归并
void MergeSort(int a[], int start, int end, int *temp){
	if(start < end){  //当数组至少有两个元素时,进行二路归并
	   int mid = (start+end)/2;
	   MergeSort(a, start, mid, temp);
	   MergeSort(a, mid+1, end, temp);
	   Merge(a, start, mid, end, temp);
	}
}  



//3交换类排序:
//快速排序
//时间复杂度 O(nlogn)  不稳定 
void QuickSort(int a[], int n){
	int low, high, p, t;
	if(n < 2)//只有一个数,不用交换 
	return;
	p = a[n/2]; //p取数组a的中间的数
	for(low = 0, high = n-1;; low++, high--){      //从p的两边开始排序
	    while(p > a[low])                          //将小于p的数放在左边,大于p的数放在p的右边 
	    low++;                                    
	    while(p < a[high])
	    high--;
	    if(low >= high) break;
	    t = a[low]; //如果p左边的数比p右边的那个数大,把p左右两边数交换一下 
	    a[low] = a[high];
	    a[high] = t;  
	} 
	QuickSort(a, low); //第一个递归调用处理数组的前部分,a对应的是数组的首地址,low是指对应的元素个数
	QuickSort(a+low, n-low);//第二个递归调用处理数组后部分,a + low指的当然是首地址加偏移地址,n-low就是p后面剩下的元素个数		 
} 
//冒泡排序
//时间复杂度 O(n^2) 稳定 
void BubbleSort(int a[], int n){
	for(int i = 1; i <= n; i++) //每一趟结束都把一个最大的数放到最下面 
	    for(int j = 1; j <= n-i; j++)
	     if(a[j] > a[j+1]){
		   int t = a[j];
		   a[j] = a[j+1];
		   a[j+1] = t;
		} 
} 


//4选择类排序:
/*堆排序:初始时把要排序的n个数的序列看作是一棵顺序存储的二叉树(一维数组存储二叉树),
调整它们的存储序,使之成为一个堆,将堆顶元素输出,
得到n 个元素中最大(或最小)的元素,这时堆的根节点的数最大(或者最小)。
然后对前面(n-1)个元素重新调整使之成为堆,输出堆顶元素,得到n 个元素中次小(或次大)的元素。
依此类推,直到只有两个节点的堆,并对它们作交换,最后得到有n个节点的有序序列*/
//堆排序:树形选择排序,将带排序记录看成完整的二叉树,第一步:建立初堆,第二步:调整堆 
//时间复杂度 O(nlogn)  不稳定 
//第二步:调整堆  
void HeapAdjust(int a[], int s, int n){   //调整为大根堆,从大到小  
	int rc = a[s];//rc根节点,s第一个节点,n节点数 
	for(int j = 2*s; j <= n; j *= 2){
		if(j<n && a[j]<a[j+1])//判断左右子数大小
		j++;
		if(rc >= a[j])//直到找到比第一个节点大的数 
		break;
		a[s] = a[j];
		s = j;
	} 
	a[s] = rc;
} 

//第一步:建初堆 
void CreatHeap(int a[], int n){ //大根堆 
	for(int i = n/2; i > 0; i--)
	HeapAdjust(a, i, n);
}

//整合
void HeapSort(int a[], int n){
    CreatHeap(a, n);//第一步建堆
	for(int i = n; i > 1; i--){ //堆顶与最后一个元素互换
		int x = a[1];
		a[1] = a[i];
		a[i] = x;
		HeapAdjust(a, 1, i-1);
	} 
} 
//简单选择排序:遍历一次找到最小与第一个元素互换位置,再从第二个元素开始遍历找到最小与第二个元素互换位置... 
//时间复杂度 O(n^2)  稳定
void SelectSort(int a[], int n){
	for(int i = 1; i < n; i++){  //第一趟共比较n-1次 
		int k = i; //k总是指向最小的那个数的下标,开始认为第一个数最小,然后把最小的数往上放 
		for(int j = i+1; j <= n; j++) //从个第二个数开始循环找出这组数中最小数的下标,并把它赋值给k 
		    if(a[j] < a[k])
			k = j;
			if(k != i){      //若果最小的那个数不是开始排序的第一个数,那么就把最小的那个数和开始排序的第一个数交换 
				int t = a[i];
				a[i] = a[k];
				a[k] = t;
			} 
    }
}  


 
主函数:
#include <iostream>
#include<iomanip>
#include "Sort.h" 
#define Max 101
using namespace std;

int main(){

	cout << endl << endl << endl; 
	cout <<setw(45) << "******************";
	cout << "综" <<setw(10) << "合"<< setw(10) << "排" << setw(10) << "序";
	cout << "****************";
	cout << endl << endl << endl;
	cout <<setw(55) << "****************************";
	cout << "菜" << setw(10) <<"单";
	cout << "**************************"; 
	cout << endl << endl;
	cout <<" " << setw(93) << "--------------------------------------------------------------------";
	cout << endl;
	cout << " " << setw(40) << "+ 归并排序----0" << setw(53) << "+" << endl;
	cout << " " << setw(26) << "+" << setw(67) << "+" << endl;;
	cout <<" " << setw(40) << "+ 希尔排序----1" << setw(50) << "直接插入排序----2" << setw(3) << "+" << endl; 
	cout << " " << setw(26) << "+" << setw(67) << "+" << endl;
	cout <<" " << setw(40) << "+ 快速排序----3" << setw(46) << "冒泡排序----4" << setw(7) << "+" << endl; 
	cout << " " << setw(26) << "+" << setw(67) << "+" << endl;
	cout <<" " << setw(38) << "+ 堆排序----5" << setw(52) << "简单选择排序----6" << setw(3) << "+" << endl; 
	cout << " " << setw(26) << "+" << setw(67) << "+" << endl;
	cout <<" " << setw(93) << "--------------------------------------------------------------------";
	cout << endl << endl;
	cout <<setw(55) << "*****************************";
	cout << "退出程序----7";
	cout << "**************************" << endl << endl;
	cout << "(注意:选择排序算法时输入对应的编号即可)" << endl;
	cout << endl; 
	int num, a[Max];
	while(scanf("%d", &num) != EOF){
		for(int i = 1; i <= Max-1; i++){
			a[i] = rand();
		} 
		if(num == 0){
				cout << "您选择了归并排序:" << endl << endl;
				int temp[Max-1] = {-1}; //临时数组,作为参数传递,避免每次在merge中分配临时数组
				MergeSort(a, 1, Max-1, temp);
				cout << "排序后:" << endl;
				for(int i = 1; i <= Max-1; i++)
					cout << left << setw(6) << a[i];
				cout << endl << endl;	 
		}
		
		if(num == 1){
				cout << "您选择了希尔排序:" << endl << endl;
				ShellSort(a, Max-1);
				cout << "排序后:" << endl;
				for(int i = 1; i <= Max-1; i++)
					cout << left << setw(6) << a[i]; 
				cout << endl << endl;	
		}
		
		if(num == 2){
				cout << "您选择了直接插入排序:" << endl << endl;
				InsertSort(a, Max-1);
				cout << "排序后:" << endl;
				for(int i = 1; i <= Max-1; i++)
					cout << left << setw(6) << a[i]; 
				cout << endl << endl;	
		}
		
		if(num == 3){
				cout << "您选择了快速排序:" << endl << endl;
				QuickSort(a, Max-1);
				cout << "排序后:" << endl;
				for(int i = 1; i <= Max-1; i++)
					cout << left << setw(6) << a[i]; 
				cout << endl << endl;	
		}
		
		if(num == 4){
				cout << "您选择了冒泡排序:" << endl << endl;
				BubbleSort(a, Max-1);
				cout << "排序后:" << endl;
				for(int i = 1; i <= Max-1; i++)
					cout << left << setw(6) << a[i]; 
				cout << endl << endl;	
		}
		if(num == 5){
				cout << "您选择了堆排序:" << endl << endl;
				HeapSort(a, Max-1);
				cout << "排序后:" << endl;
				for(int i = 1; i <= Max-1; i++)
					cout << left << setw(6) << a[i]; 
				cout << endl << endl;	
		}
		if(num == 6){
				cout << "您选择了简单选择排序:" << endl << endl;
				SelectSort(a, Max-1);
				cout << "排序后:" << endl;
				for(int i = 1; i <= Max-1; i++)
					cout << left << setw(6) << a[i]; 
				cout << endl << endl;	
		}
		
		if(num == 7){
			cout << "您已退出程序!"; 
			return 0;
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/wangjian530/article/details/80529443
今日推荐