常用的内部排序算法

数据结构之常用的内部排序算法

一,目的

  • 掌握顺序表和单链表的存储特点及插入、删除等算法。

  • 灵活运用顺序表和单链表的相关算法实现一元多项式的计算。

二,描述

通过一个简单的菜单,分别实现下列排序要求,采用几组不同数据测试各排序算法的性能(比较次数和移动次数)及稳定性。

​ 实现简单选择排序、直接插入排序和冒泡排序;

​ 实现折半插入排序;

​ 实现希尔排序算法;

​ 实现快速排序算法(递归和非递归);

​ 实现堆排序算法。

(1)输入:

​ 根据菜单提示选择排序算法,输入一组待排序数据。

(2)输出:

​ 输出排序结果(体现排序过程),及排序过程中数据的比较次数和移动

三,代码测试

  • 方案
测试数据
直接插入排序50 23 6 71 90 33 99 45
折半插入排序33 99 45 4 99 2 50 13
希尔排序6 71 50 66 12 9 67 43
简单选择排序3 99 45 23 60 47 91 7
冒泡排序6 71 51 88 19 45 37 51
快速排序50 23 6 55 60 57 91 66
堆排序5 33 73 91 20 87 93 91
  • 结果
    1,直接插入排序
    在这里插入图片描述
    2,折半插入排序
    在这里插入图片描述
    3,希尔排序
    在这里插入图片描述
    4,简单选择排序
    在这里插入图片描述
    5,冒泡排序
    在这里插入图片描述
    6,快速排序
    在这里插入图片描述
    7,堆排序
    在这里插入图片描述

四,部分源码

  1. 主要数据类型与变量

    typedef int KeyType;
    typedef struct{
    	KeyType key;  //关键字类型 
    }RedType;
    //顺序表类型 
    typedef struct{
    	RedType *r;  //r[0]闲置或用作哨兵单元 
    	int length;  //顺序表长度 
    }SqList;
    
  2. 部分函数模块

    void InserSort(SqList &L){
    	//直接插入排序
    	int i, j, m, n;
    	m = n = 0;
    	for(i = 2; i <= L.length; i++){
    	if(LT(L.r[i].key, L.r[i-1].key)){
    		L.r[0] = L.r[i];
    		L.r[i] = L.r[i-1];
    		n+=2;
    		m++;
    		for(j=i-2; LT(L.r[0].key, L.r[j].key); --j){
    		L.r[j+1] = L.r[j];
    		m++;
    		n++;
    		}
    		L.r[j+1] = L.r[0];
    		PrintList_Sq(L);
    	}
    	m++;
    	}
    	printf("比较次数为:%d\n", m);
    	printf("移动次数为:%d\n", n);
    } 
    
    void BInsertSort(SqList &L){
    	//折半插入排序
    	int m, i, j, a, b;
    	a = b =0;
    	for(i=2; i<=L.length; ++i){
    		L.r[0] = L.r[i];
    		b++;
    		int low = 1; int high = i - 1;
    		while(low <= high){
    			m = (low + high)/2;
    			if(LT(L.r[0].key, L.r[m].key)) high = m-1;
    			else low = m + 1;
    			a++;
    		}
    		for(j=i-1; j>=high+1; --j){
    		 L.r[j+1] = L.r[j];
    		 b++;
    		 }
    		L.r[high+1] = L.r[0];
    		b++;
    		PrintList_Sq(L);
    	} 
    	a++;
    	printf("比较次数为:%d\n", a);
    	printf("移动次数为:%d\n", b);
    }
    
    void ShellInsert(SqList &L, int dk, SqList &H){
    	//希尔排序 增量 
    	int i, j, m, n;
    	m = n =0;
    	for(i=dk+1; i<=L.length; ++i)
    	if(LT(L.r[i].key, L.r[i-dk].key)){
    		L.r[0] = L.r[i];
    		n++;
    		for(j=i-dk; j>0 && LT(L.r[0].key, L.r[j].key); j-=dk){
    		L.r[j+dk] = L.r[j];
    		m++;
    		n++;
    		}	
    		L.r[j+dk] = L.r[0];
    		n++; 
    		m++;
    	}
    	PrintList_Sq(L);
    	H.length += m;
    	H.r[0].key += n;
    }
    
    void ShellSort(SqList &L){
    	//希尔排序
    	SqList H;
    	InitList(H, 1);
    	H.length = 0;
    	H.r[0].key = 0;
    	int a = L.length;
    	int b = a/2;
    	while(b>=1){
    	ShellInsert(L, b, H);
    	b = b/2;
    	}
    	printf("比较次数为:%d\n", H.length);
    	printf("移动次数为:%d\n", H.r[0].key);
    }
    
    Status SelectMinKey(SqList L, int i){
    	//在L.r[i..L.length]中选择key最小的
    	int min = i;
    	int a = L.r[min].key;
    	for(i; i<L.length; i++){
    		if(L.r[i+1].key < a){
    		min = i+1;
    		a = L.r[i+1].key;
    		}	
    	}
    	i = min; 
    	return i;
    }
    
    void SelectSort(SqList &L){
    	//简单选择排序
    	int i, j, m;
    	m = L.length;
    	for(i=1; i<L.length; ++i){
    		j = SelectMinKey(L, i);
    		if(i!=j){
    			L.r[0] = L.r[i];
    			L.r[i] = L.r[j];
    			L.r[j] = L.r[0]; 
    		}
    		PrintList_Sq(L); 
    	}
    	printf("比较次数为:%d\n", m*(m-1)/2);
    	printf("移动次数为:%d\n", m-1); 
    } 
    
    void bubbleSort(SqList &L){
    	//冒泡排序 
    	int i, j, m, n;
    	m = n =0;
    	for(i=1; i<L.length; i++){
    		for(j=1; j<L.length-i+1; j++){
    			if(L.r[j].key > L.r[j+1].key)
    			{
    				L.r[0] = L.r[j];
    				L.r[j] = L.r[j+1];
    				L.r[j+1] = L.r[0];
    				n += 2;
    			}
    			m++;	
    		}
    			PrintList_Sq(L);
    		printf("比较次数为:%d\n", m);
    		printf("移动次数为:%d\n", n);
    	}			
    }
    
    void QSort(SqList &L, int low, int high, SqList &H){
    	//快速排序 
    	int pivotloc;
    	if(low < high){
    		pivotloc = Partition(L, low, high, H);
    		QSort(L, low, pivotloc-1, H);
    		QSort(L, pivotloc+1, high, H);
    	}
    }
    
    Status Partition(SqList &L, int low, int high, SqList &H){
    	//快速排序中轴 
    	int m, n; 
    	m = n = 0;
    	L.r[0] = L.r[low];
    	n++; 
    	int pivotkey = L.r[low].key;
    	while(low < high){
    		while(low<high && L.r[high].key>=pivotkey){
    			--high;  m++;
    		}	
    		L.r[low] = L.r[high];	n++;
    		while(low<high && L.r[low].key<=pivotkey){
    			++low;  m++;
    		}	
    		L.r[high] = L.r[low]; n++;
    	}
    	L.r[low] = L.r[0];  n++;
    	PrintList_Sq(L);
    	H.length +=m;
    	H.r[0].key +=n;
    	return low;
    }
    
    void HeapAdjust(SqList &H, int s, int m, SqList &L){
    	//建堆 
    	int j;
    	int a, b;
    	a = b = 0; 
    	RedType rc;
    	rc = H.r[s];
    	b++;
    	for(j=2*s; j<=m; j*=2){
    		if(j<m && LT(H.r[j].key, H.r[j+1].key) ){
    		++j;  a++;
    		} 
    		if(!LT(rc.key, H.r[j].key)){
    			break; a++;
    		}   a++;
    		H.r[s] = H.r[j]; s = j; b++;
    	} 
    	H.r[s] = rc; b++;
    	L.length += a;
    	L.r[0].key += b;
    }
    
    void HeapSort(SqList &H){
    	//堆排序
    	int i;
    	SqList L;
    	InitList(L, 1);
    	L.length = 0;
        L.r[0].key = 0;
        
    	for(i=H.length/2; i>0; --i)
    		HeapAdjust(H, i, H.length, L);
    	for(i = H.length; i>1; --i){
    		H.r[0] = H.r[1];
    		H.r[1] = H.r[i];
    		H.r[i] = H.r[0];
    		L.r[0].key +=2; 
    		PrintList_Sq(H);
    		HeapAdjust(H, 1, i-1, L);
    	}
    	printf("比较次数为:%d\n", H.length);
    	printf("移动次数为:%d\n", H.r[0].key);
    }
    
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值