数据结构:实验八:数据排序

一、    实验目的

(1)掌握各种排序算法的过程和算法设计。

(2)体会各种排序算法的性能。

二、  实验要求

编写程序分别采用直接插入排序算法 、折半插入排序算法、冒泡排序算法、快速排序算法,实现对任意一组整型数据(无序),分别输出各一趟的排序结果。

 三、实验环境

Windows+DEV C++( 或者其他编译工具)

四、实验步骤及结果 

1.类型声明

typedef int ElemType;

typedef struct {

   ElemType key;

} RecType;//排序元素的类型

2.各类排序算法的实现

//直接插入排序

void InsertSort(RecType R[],int n) {//对R[0..n-1]按递增有序进行直接插入排序



   RecType tmp;

   int i,j;

   for(i=0; i<n; i++) {

       if(R[i].key<R[i-1].key) {//反序时

          tmp=R[i];

          j=i-1;

          do {//找R[i]的插入位置

              R[j+1]=R[j];//将关键字大于R[i].key的记录后移

              j--;

          } while(j>=0&&R[j].key>tmp.key);

          R[j+1]=tmp;//在j+1处插入R[i]

       }

   }

}

//折半插入排序

void BinInsertSort(RecType R[],int n) {

   int i,j,low,high,mid;

   RecType tmp;

   for(i=1; i<n; i++) {

       if(R[i].key<R[i-1].key) {//反序时

          tmp=R[i];//将R[i]保存到tmp中

          low=0;

          high=i-1;

          while(low<=high) {//在R[low..high]中查找插入的位置

              mid=(low+high)/2;//取中间位置

              if(tmp.key<R[mid].key)

                 high=mid-1;//插入点在左半区

              else

                 low=mid+1;//插入点在右半区

          }//找位置high+1

          for(j=i-1; j>=high+1; j--)//集中进行元素的后移

              R[j+1]=R[j];

          R[high+1]=tmp;//插入tmp

       }

   }

}

//冒泡排序

void BubbleSort(RecType R[],int n) {

   int i,j;

   for(i=0; i<n-1; i++)

       for(j=n-1; j>i; j--)//将R[i]元素归位

          if(R[j].key<R[j-1].key) //相邻的两个元素反序时

              swap(R[j],R[j-1]);//将R[j]和R[j-1]两个元素交换

}

//快速排序

int partition(RecType R[],int s,int t) {//一趟划分

   int i=s,j=t;

   RecType base=R[i];//以R[i]为基准

   while(i<j) {//从两端交替向中间扫描,直到i=j为止

       while(j>i&&R[j].key>=base.key)

          j--;//从右往左遍历,找一个小于base.key的R[j]

       if(i<j) {

          R[i]=R[j];

          i++;

       }

       while(i<j&&R[i].key<=base.key)

          i++;//从左往右遍历,找一个大于base.key的R[i]

       if(i<j) {

          R[i]=R[j];

          j--;

       }

   }

   R[i]=base;

   return i;

}

void QuickSort(RecType R[],int s,int t) {//对R[s..t]中的元素进行快速排序

   int i;

   if(s<t) {//区间内至少存在两个元素的情况

       i=partition(R,s,t);

       QuickSort(R,s,i-1);//对左区间递归排序

       QuickSort(R,i+1,t);//对右区间递归排序

   }

}

3.主程序设计及完成实验要求中的功能

//输出

void Display(RecType R[],int n) {

   for(int i=0; i<n; i++)

       cout<<R[i].key<<" ";

   cout<<endl;

}

//主面板

void Interface() {

   cout<<"0.退出程序"<<endl;

   cout<<"1.直接插入排序算法"<<endl;

   cout<<"2.折半插入排序算法"<<endl;

   cout<<"3.冒泡排序算法"<<endl;

   cout<<"4.快速排序算法"<<endl;

   cout << "请输入选择:";

}

//选择匹配面板

void Select(RecType R[],int n,int x) {

   switch(x) {

       case 0:

          cout << "已退出程序!";

          exit(0);

       case 1:

          InsertSort(R,n);

          Display(R,n);

          break;

       case 2:

          BinInsertSort(R,n);

          Display(R,n);

          break;

       case 3:

          BubbleSort(R,n);

          Display(R,n);

          break;

       case 4:

          QuickSort(R,1,n-1);

          Display(R,n);

          break;

   };

}

int main() {

   int n=0,x;

   RecType R[N]= {5,8,6,10,1,4,9,7,3,2};

   for(int i=0; i<N&&R[i].key!=0; i++)

       n++;

   cout<<"初始序列为:"<<endl;

   Display(R,n);

   cout<<endl;

   while(1) {

       Interface();

       cin>>x;

       while(!(x==0||x==1||x==2||x==3||x==4)) {

          system("cls");

          cout<<"输入错误请重新输入!"<<endl;

          Interface();

          cin>>x;

       }

       Select(R,n,x);

   }

}

完整代码:

#include<iostream>
using namespace std;
#define N 100
typedef int ElemType;
typedef struct {
	ElemType key;
} RecType;//排序元素的类型
//直接插入排序
void InsertSort(RecType R[],int n) {//对R[0..n-1]按递增有序进行直接插入排序

	RecType tmp;
	int i,j;
	for(i=0; i<n; i++) {
		if(R[i].key<R[i-1].key) {//反序时
			tmp=R[i];
			j=i-1;
			do {//找R[i]的插入位置
				R[j+1]=R[j];//将关键字大于R[i].key的记录后移
				j--;
			} while(j>=0&&R[j].key>tmp.key);
			R[j+1]=tmp;//在j+1处插入R[i]
		}
	}
}
//折半插入排序
void BinInsertSort(RecType R[],int n) {
	int i,j,low,high,mid;
	RecType tmp;
	for(i=1; i<n; i++) {
		if(R[i].key<R[i-1].key) {//反序时
			tmp=R[i];//将R[i]保存到tmp中
			low=0;
			high=i-1;
			while(low<=high) {//在R[low..high]中查找插入的位置
				mid=(low+high)/2;//取中间位置
				if(tmp.key<R[mid].key)
					high=mid-1;//插入点在左半区
				else
					low=mid+1;//插入点在右半区
			}//找位置high+1
			for(j=i-1; j>=high+1; j--)//集中进行元素的后移
				R[j+1]=R[j];
			R[high+1]=tmp;//插入tmp
		}
	}
}
//冒泡排序
void BubbleSort(RecType R[],int n) {
	int i,j;
	for(i=0; i<n-1; i++)
		for(j=n-1; j>i; j--)//将R[i]元素归位
			if(R[j].key<R[j-1].key) //相邻的两个元素反序时
				swap(R[j],R[j-1]);//将R[j]和R[j-1]两个元素交换
}
//快速排序
int partition(RecType R[],int s,int t) {//一趟划分 
	int i=s,j=t;
	RecType base=R[i];//以R[i]为基准 
	while(i<j) {//从两端交替向中间扫描,直到i=j为止 
		while(j>i&&R[j].key>=base.key)
			j--;//从右往左遍历,找一个小于base.key的R[j] 
		if(i<j) {
			R[i]=R[j];
			i++;
		}
		while(i<j&&R[i].key<=base.key)
			i++;//从左往右遍历,找一个大于base.key的R[i] 
		if(i<j) {
			R[i]=R[j];
			j--;
		}
	}
	R[i]=base;
	return i;
}
void QuickSort(RecType R[],int s,int t) {//对R[s..t]中的元素进行快速排序 
	int i;
	if(s<t) {//区间内至少存在两个元素的情况 
		i=partition(R,s,t);
		QuickSort(R,s,i-1);//对左区间递归排序 
		QuickSort(R,i+1,t);//对右区间递归排序 
	}
}
//输出
void Display(RecType R[],int n) {
	for(int i=0; i<n; i++)
		cout<<R[i].key<<" ";
	cout<<endl;
}
//主面板
void Interface() {
	cout<<"0.退出程序"<<endl;
	cout<<"1.直接插入排序算法"<<endl;
	cout<<"2.折半插入排序算法"<<endl;
	cout<<"3.冒泡排序算法"<<endl;
	cout<<"4.快速排序算法"<<endl;
	cout << "请输入选择:";
}
//选择匹配面板
void Select(RecType R[],int n,int x) {
	switch(x) {
		case 0:
			cout << "已退出程序!";
			exit(0);
		case 1:
			InsertSort(R,n);
			Display(R,n);
			break;
		case 2:
			BinInsertSort(R,n);
			Display(R,n);
			break;
		case 3:
			BubbleSort(R,n);
			Display(R,n);
			break;
		case 4:
			QuickSort(R,1,n-1);
			Display(R,n);
			break;
	};
}
int main() {
	int n=0,x;
	RecType R[N]={28,16,32,12,60,2,5,72};
	//RecType R[N]= {5,8,6,10,1,4,9,7,3,2};
	for(int i=0; i<N&&R[i].key!=0; i++)
		n++;
	cout<<"初始序列为:"<<endl;
	Display(R,n);
	cout<<endl;
	while(1) {
		Interface();
		cin>>x;
		while(!(x==0||x==1||x==2||x==3||x==4)) {
			system("cls");
			cout<<"输入错误请重新输入!"<<endl;
			Interface();
			cin>>x;
		}
		Select(R,n,x);
	}
}

4.实验结果截图

如需源文件,请私信作者,无偿

  • 10
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 快速排序是一种高效的排序算法,它的基本思想是通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,然后再分别对这两部分记录继续进行排序,以达到整个序列有序的目的。快速排序的时间复杂度为O(nlogn),是一种比较快速的排序算法。 ### 回答2: 快速排序是一种基于分治法的高效的排序算法,被广泛应用于实际的排序问题中。其核心思想是选取一个枢轴元素将待排序序列分成两个子序列,一个子序列中的所有元素小于枢轴,另一个子序列中的所有元素大于枢轴,然后对这两个子序列分别进行递归排序,最终得到有序序列。 下面我们来分步讲解快速排序算法的实现过程: 1.选择枢轴 在实现快速排序算法时,一般采用三数取中法选取枢轴元素。即从待排序序列的第一个元素,中间元素和最后一个元素中选取中间值作为枢轴元素。 2.划分子序列 选取了枢轴元素后,接下来就需要根据枢轴元素将待排序序列划分成两个子序列。划分时需要从序列两端开始向中间扫描,将小于枢轴元素的元素放到左边的子序列中,大于枢轴元素的元素放到右边的子序列中。当左右两端的扫描相遇时结束扫描,最终得到两个子序列。 3.递归排序 接下来对划分后的两个子序列进行递归排序,重复上述过程,直到子序列中只包含一个元素为止。这时,所有子序列都已排序好,整个序列也就变成有序的了。 需要注意的是,在实现快速排序算法时,应该注意边界问题,尤其是递归过程中的边界条件的设置,否则可能会导致死循环或越界等错误。 快速排序算法的时间复杂度为O(nlogn),是一种十分高效的排序算法。其应用范围也非常广泛,几乎包括了所有需要排序的领域。在实际应用中,我们可以根据需要对快速排序算法进行一定的改进,以满足实际需求。例如,在排序大量数据时,我们可以采用并行化的方法,将待排序序列分成多个子序列并行地进行排序,以提高排序效率。 ### 回答3: 快速排序是一种基于比较的排序算法,它的基本思想是通过一趟排序将待排序数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据要小,然后再递归地对这两部分数据分别进行快速排序快速排序的时间复杂度为O(nlogn),是目前比较常用的排序算法之一。 快速排序的基本思想是选定一个基准元素,将数组中小于等于基准元素的元素放到其左边,大于基准元素的元素放到其右边,然后递归地对左、右子数组进行快速排序。具体实现时,我们通常选择待排序数组中的第一个元素作为基准元素,将数组从第二个元素开始扫描,把小于等于基准元素的放到左边,大于基准元素的放到右边,最后将基准元素插入到中间位置,这样排序之后基准元素就在它的最终位置上了。 快速排序的关键在于如何把小于等于基准元素的元素放到左边,大于基准元素的元素放到右边。这可以通过一趟扫描来实现,具体实现时可以采用双指针法,即设置一个指针i指向数组的第二个元素,一个指针j指向数组的最后一个元素,然后在数组中查找第一个小于等于基准元素的元素和第一个大于基准元素的元素,交换它们的位置,直到i>=j为止。这样扫描结束后,i所在的位置就是基准元素的位置。 快速排序的递归结束条件是子数组只包含一个元素或为空。这样,每次递归都会使待排序的数组规模减半,排序的复杂度就为O(nlogn)。 总结一下,快速排序是一种高效的排序算法,具有简单、快速、不需要额外的存储空间等优点,但是在最坏情况下的时间复杂度会达到O(n^2),因此需要注意基准元素的选择和算法的实现细节,以避免这种情况的出现。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值