#include <iostream>
using namespace std;
#define maxsize 1000
typedef struct{
int r[maxsize+1];//设定哨兵
int length;//顺序表长度:不包括0结点
}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;
bool flag=true;//设定标志变量,如果循环发现不需要交换则结束
for(i=1;i<l.length&&flag;i++){
flag=false;
for(j=l.length-1;j>=i;j--){
if(l.r[j]>l.r[j+1]){
flag=true;
swap_(l,j,j+1);
}
}
}
}
//简单选择排序:从前往后,找到后面序列的最小值进行交换
void selectsort(sqlist&l){
int i,j;int min;
for(i=1;i<l.length;i++){
min=i;
for(j=i+1;j<=l.length;j++){
if(l.r[min]>l.r[j]){
min=j;
}
}
if(i!=min){
swap_(l,i,min);
}
}
}
//直接插入排序
void insertsort(sqlist&l){
int i,j;
for(i=2;i<l.length+1;i++){
if(l.r[i]<l.r[i-1]){
l.r[0]=l.r[i];//引入哨兵
//引入哨兵后,不需要判断j是否大于0,只需判断在哪里插入,之前元素已经有序
for(j=i-1;l.r[j]>l.r[0];j--){ //从后往前
l.r[j+1]=l.r[j];
}
l.r[j+1]=l.r[0];//插入 注意这里j指向
}
}
}
//希尔排序
void shellsort(sqlist&l){
int i,j=0;
int shell=l.length;//初始化shell为数组最后一个元素下标
do{
shell=shell/3+1;//构造序列
for(i=shell+1;i<=l.length;i++){//i从1+shell出发,可以类比上面直接插入排序的代码,只是变成以shell为公差的子列 ,对子列进行直接插入排序
if(l.r[i]<l.r[i-shell]){
l.r[0]=l.r[i];
for(j=i-shell;j>0&&l.r[j]>l.r[0];j-=shell){//此时有j>0是因为不能保证哨兵在子列里
l.r[j+shell]=l.r[j];
}
l.r[j+shell]=l.r[0];
}
}
}while(shell>1);//多次使shell值减小直到shell=1,在这样的流程中使序列基本有序,最后一步是直接插入排序
}
//堆排序
void heapadjust(sqlist&l,int s,int m){//使s,m间元素形成大顶堆 以s为根节点
int temp,j;
temp=l.r[s];//中间变量
for(j=2*s;j<=m;j*=2){//2*s代表s的左孩子 每一次循环遍历到子树的子树 因为交换根节点和孩子可能会改变子树的大顶堆排列
if(j<m&&l.r[j]<l.r[j+1]){//判断左右孩子谁大
++j;
}
if(temp>=l.r[j])//如果根节点值大于左右孩子,则跳出循环,因为下面的子树已构成堆
break;
l.r[s]=l.r[j];//交换根节点和孩子的值
s=j;//将j的位置赋给s
}
l.r[s]=temp;//赋值
}
void heapsort(sqlist&l){
int i;
for(i=l.length/2;i>0;i--){//i的取值都是非叶子节点,从下到上提高效率,从而将原序列构成大顶堆
heapadjust(l,i,l.length);
}
for(i=l.length;i>1;i--){//将根节点与最后一个节点(即线性表最右边的节点-排序最大)交换,
swap_(l,1,i);
heapadjust(l,1,i-1);//将除了最后几个已归位结点以外的构成大顶堆
}
}
//归并排序
void merge(int s[],int t[],int i,int m,int n){//将有序的i到m序列与m+1到n的序列进行归并为一个序列t
int j,k,l;
for(j=m+1,k=i;i<=m&&j<=n;k++){//i和j是变量,如果其中一个小,那么将值赋给t,然后下标加1,再比较。循环终止条件为一个序列终止了
if(s[i]<s[j]){
t[k]=s[i++];//K代表t的下标
}
else{
t[k]=s[j++];
}
}
//将剩余序列加入t
if(i<=m){
for(l=0;l<=m-i;l++){
t[k+l]=s[i+l];//此时i,k都加一了,所以l从0开始
}
if(j<=n){
for(l=0;l<=n-j;l++){
t[k+l]=s[j+l];
}
}
}
}
void msort(int s[],int t[],int a,int b){//二路归并排序
int m;
int t2[maxsize];
if(a==b){
t[a]=s[a];
}
else{
m=(a+b)/2;//将区间分两份
//递归再分两份
msort(s,t2,a,m);
msort(s,t2,m+1,b);
//整合
merge(t2,t,a,m,b);
}
}
//快速排序
int partition(sqlist&l,int low,int high){
int p;
p=l.r[low];//选取关键值 目的将它放到一个位置使左边都比它小右边都比它大
while(low<high){
while(low<high&&l.r[high]>=p)high--;
swap_(l,low,high);
while(low<high&&l.r[low]<=p)low++;
swap_(l,low,high);
}
return low;
}
void qsort(sqlist&l,int low,int high){
int pivot;
if(low<high){
pivot=partition(l,low,high);
qsort(l,low,pivot-1);
qsort(l,pivot+1,high);
}
}
void show(sqlist&l){
for(int i=1;i<=l.length;i++){
cout<<l.r[i]<<endl;
}
}
int main(){
sqlist l;
l.length=6;
for(int i=1;i<=6;i++){
l.r[i]=7-i;
}
l.r[0]=0;
show(l);
cout<<"-----------"<<endl;
//msort(l.r,l.r,1,6);
qsort(l,1,6);
show(l);
return 0;
}
数据结构排序
于 2023-01-28 09:43:56 首次发布