内部排序算法

#include <stdio.h>

#include <stdlib.h>

#define MAXSIZE 100

typedef struct{

int r[MAXSIZE+1];//用于存储要排序数组,r[0]用做哨兵或临时变量

int length;

}SqList;

 

//交换两个值

void swap(SqList *L,int i,int j){

int temp = L->r[i];

L->r[i] = L->r[j];

L->r[j] = temp;

}

 

//冒泡排序

void BubbleSort(SqList *L){

int i,j,k=0,l=0;

for (i = 1;i<L->length;i++){//外层循环,确定所有数都与其它数比较

//k++;

for(j = i+1;j<=L->length;j++){//内层循环,用一个数跟其它数比较大小

k++;

if(L->r[i] > L->r[j]){

swap(L,i,j);

l = l+3;

}

}

}

printf("冒泡排序中关键字的比较次数为%d:",k);

printf("\n冒泡排序中关键字的移动次数为%d:",l);

printf("\n");

}

 

//直接排序

void InsertSort(SqList *L) {

int i,j,k=0,l=0;

for(i = 2;i<=L->length;i++){

k++;

if(L->r[i] < L->r[i-1]){

L->r[0] = L->r[i];//设置哨兵

l++;

for(j = i-1;L->r[j] >L->r[0];j--){

L->r[j+1] = L->r[j];//记录后移

l++;

k++;

}

k++;//这一步容易忽略,跳出循环的时候,是比较了一次,不符合条件才跳出的

L->r[j+1] = L->r[0];//插入到正确位置

l++;

}

}

printf("直接排序中关键字的比较次数为%d:",k);

printf("\n直接排序中关键字的移动次数为%d:",l);

printf("\n");

}

 

//简单选择排序

void SelectSort(SqList *L){

int i,j,min;

int k=0,l=0;

for(i = 1;i<L->length;i++){

//k++;

min = i;

for(j = i+1;j<=L->length;j++){

k++;

if(L->r[min] > L->r[j]){

min = j;

}

}

if(i != min){//判断 i!min,则证明有数据比r[min]还要小,则需交换

swap(L,i,min);

l = l+3;

}

}

printf("简单排序中关键字的比较次数为:%d",k);

printf("\n简单排序中关键字的移动次数为:%d",l);

printf("\n");

}

 

//希尔排序

void ShellSort(SqList *L) {

int i,j;

int k = 0,l = 0;

int increment = L->length;

do{

increment = increment/5+1;//增量序列

for(i =increment+1;i<=L->length;i++){

k++;

if(L->r[i] < L->r[i-increment]){//需要将L->r[i]插入有序增量子表

L->r[0] = L->r[i];

l++;

for(j =i-increment;L->r[0]<L->r[j] && j>0;j = j-increment){

k++;

L->r[j+increment] = L->r[j];

l++;

}

k++;//这一步容易忽略,跳出循环的时候,是比较了一次,不符合条件才跳出的

L->r[j+increment] = L->r[0];

l++;

}

}

}while(increment > 1);

printf("希尔排序中关键字的比较次数为:%d",k);

printf("\n希尔排序中关键字的移动次数为:%d",l);

printf("\n");

}

 

//已知L->r[s..m]中记录的关键字除L->r[s]之外均满足堆的定义

//本函数调整L->r[s]的关键字,使L->r[s..m]成为一个大顶堆

void HeapAdjust(SqList *L,int s,int m,int&a,int &b){

int temp,j;

temp = L->r[s];

b++;

for(j = 2*s;j<=m;j = j*2){

a++;

if( L->r[j] < L->r[j+1] &&j<m)

++j;//j为关键字中较大的记录的下标

a++;

if(temp >= L->r[j])

break;

L->r[s] = L->r[j];

b++;

s = j;

}

L->r[s] = temp;

b++;

}

//堆排序

void HeapSort(SqList *L) {

int i ;

int k = 0,l = 0;

for(i = L->length/2;i>0;i--){//把L中的r构建成一个大顶堆

HeapAdjust(L,i,L->length,k,l);

}

for(i = L->length;i>1;i--){

swap(L,1,i);//将堆顶记录和当前未经排序子序列的最后一个记录交换

l = l+3;

HeapAdjust(L,1,i-1,k,l);//将L->r[1...i-1]重新调整为大顶堆

}

printf("堆排序中关键字的比较次数为:%d",k);

printf("\n堆排序中关键字的移动次数为:%d",l);

printf("\n");

}

 

//交换顺序表L中子表的记录,使枢轴记录到位,并返回其所在位置

//此时在它之前(后)的记录均不大(小)于它

int Partition(SqList *L,int low,inthigh,int &k,int &l){

int pivotkey;

pivotkey = L->r[low];

while(low<high){

while(L->r[high] >= pivotkey&& low<high ){

k++;

high--;

}

k++;//这一步容易忽略,跳出循环的时候,是比较了一次,不符合条件才跳出的

swap(L,low,high);

l = l+3;

while(L->r[low] <= pivotkey&& low<high ){

k++;

low++;

}

k++;//这一步容易忽略,跳出循环的时候,是比较了一次,不符合条件才跳出的

swap(L,low,high);

l = l+3;

}

return low;

}

//对顺序表L中的子序列L->r[low..high]作快速排序

void QSort(SqList *L,int low,int high,int&k,int &l){

int pivot;//枢轴

if(low<high){

pivot = Partition(L,low,high,k,l);//将L->r[low..high]一分为二,算出枢轴值

QSort(L,low,pivot-1,k,l);//对低子表递归排序

QSort(L,pivot+1,high,k,l);//对高子表递归排序

}

}

 

//快速排序

void QuickSort(SqList *L) {

int k=0,l=0;

QSort(L,1,L->length,k,l);

printf("快速排序中关键字的比较次数为:%d",k);

printf("\n快速排序中关键字的移动次数为:%d",l);

printf("\n");

}

 

 

int main(){

int x,y;

SqList L,L1,L2,L3,L4,L5;

L.length = 100;

 

for(int i = 0;i<5;i++){

printf("第%d次待排序列为:\n",i+1);

for(x=1; x<101; x++) {

y = rand()% 100;

L.r[x] = y;

printf("%3d",y);

}

L1=L2=L3=L4=L5=L;

//fflush(stdin);

printf("\n排序后的结果\n");

BubbleSort(&L);

printf("直接排序后的结果\n");

InsertSort(&L1);

printf("简单排序后的结果\n");

SelectSort(&L2);

printf("希尔排序后的结果\n");

ShellSort(&L3);

printf("堆排序后的结果\n");

HeapSort(&L4);

printf("快速排序后的结果\n");

QuickSort(&L5);

   for(x=1; x<101; x++) {

printf("%3d",L.r[x]);

}

printf("\n");

}

while(1){//设置一个死循环,为了不让程序结束而关闭窗口

 

}

return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值